Skip to main content

Batch Orders

Place multiple orders in a single request, up to your tier’s max batch size (see the table below). Each order is processed independently — partial failures are reported per-order.

Batch Size Limits

Authoritative on the wire via GET /v1/keys/tiersmax_batch_size field. See Rate Limits for the full per-tier matrix.

Request

Each order in the array follows the same schema as POST /v1/orders.
Market orders inside a batch still require price — it’s the worst-price slippage cap (Polymarket-faithful). Without it the entry is rejected with Market orders require a 'price' field. For BUY, set the maximum you’ll pay; for SELL, the minimum you’ll accept. See Placing Orders for the full slippage-cap rationale.

Response

Partial failures don’t roll back successful orders. Each order is independent — some may succeed while others fail. Always check the succeeded and failed counts.

Error Response Format

Every entry in results is a full OrderResponse. A failed entry has status="REJECTED" (a per-entry validation/business rejection) or status="ERROR" (an internal error processing that entry), with two clean machine-readable fields:
  • error — the stable machine code (e.g. INSUFFICIENT_BALANCE, MARKET_CLOSED, INVALID_QUANTITY), matching the single-order error envelope byte-for-byte. See the canonical trading error-code table.
  • error_message — the human-readable prose for that failure.
Each failed entry in results has this shape:
Branch on the error code; show error_message to humans. (Earlier drafts showed error as a stringified Python-repr of the detail dict — that behaviour was removed; error is now a clean code and error_message carries the prose.)
A batch request itself returns HTTP 200 even when individual orders fail — iterate results to check per-order status. Request-level failures still use HTTP status codes: auth, rate limit, malformed JSON, and an oversize batch (see below).

Oversize batch → request-level 400

If orders exceeds your tier’s max batch size, the whole request is rejected with 400 BATCH_LIMIT_EXCEEDED — no results array, no per-entry processing. Check GET /v1/keys/tiers (max_batch_size) and split large batches client-side.
Note the key difference between the two failure shapes: a request-level rejection (like this oversize-batch 400) uses the standard {error, message} envelope, while a per-entry rejection inside a 200 results array uses {error, error_message} (shown above). Branch on error in both cases.

Use Cases

Portfolio Rebalancing

Buy underweight positions and sell overweight positions in a single request.

Grid Trading

Place a ladder of limit orders at multiple price levels simultaneously.

Market Scanning

Buy small positions across multiple undervalued markets at once.

Rate Limit Optimization

1 batch request counts as 1 API call vs N individual calls.

Next Steps