Batch Operations

Batch endpoints allow placing or canceling multiple orders in a single request. Essential for market makers who need to update quotes across multiple price levels simultaneously.

Batch Place Orders

POST /v1/orders/batch

Scope: trade:bulk

Place up to 15 orders in a single request. Each order is processed independently — partial success is possible. The backend enforces MaxBatchPlaceOrders = 15; requests exceeding the cap return 400 INVALID_REQUEST.

Request Body

{
  "orders": [
    {
      "market_id": "...",
      "side": "BUY",
      "maker_amount": "500000",
      "taker_amount": "1000000",
      "token_id": "...",
      "maker": "0x...",
      "signer": "0x...",
      "taker": "0x0000000000000000000000000000000000000000",
      "salt": "111",
      "nonce": 0,
      "expiration": 0,
      "fee_rate_bps": 50,
      "signature": "0x...",
      "outcome_index": 0,
      "time_in_force": "GTC"
    },
    {
      "market_id": "...",
      "side": "SELL",
      "maker_amount": "1000000",
      "taker_amount": "500000",
      ...
    }
  ]
}

Response

{
  "results": [
    {
      "index": 0,
      "order_hash": "0x...",
      "order_id": "...",
      "status": "success",
      "response": { "order_id": "...", "order_hash": "0x...", "status": "open", "matches": [] }
    },
    {
      "index": 1,
      "status": "failed",
      "error": "invalid signature"
    }
  ],
  "succeeded": 1,
  "failed": 1,
  "total": 2
}

Each result row carries a status of "success" or "failed". The nested response field on a success row mirrors the single-order place response so consumers can replay the same parser.

Batch Cancel Orders

DELETE /v1/orders/batch

Scope: trade:bulk

Cancel multiple orders by their hashes.

Request Body

{
  "order_hashes": [
    "0xabc123...",
    "0xdef456..."
  ]
}

Response

{
  "results": [
    { "order_hash": "0xabc123...", "status": "cancelled" },
    { "order_hash": "0xdef456...", "status": "failed", "error": "order not found" }
  ],
  "cancelled": 1,
  "failed": 1,
  "total": 2
}

Each result row carries a status of "cancelled" or "failed" (string, not boolean).

Cancel All Orders (Kill Switch)

DELETE /v1/orders/cancel-all

Scope: trade:bulk

Cancel all open orders for the authenticated user across all markets. This is the emergency kill switch for market makers.

Response

{
  "cancelled": 47,
  "message": "cancelled all open orders"
}

Cancel Market Orders

DELETE /v1/orders/cancel-market

Scope: trade:bulk

Cancel all open orders for the authenticated user in a specific market. Optionally filter by outcome index. The target market is sent in the JSON body (not query params).

Request Body

{
  "market_id": "550e8400-e29b-41d4-a716-446655440000",
  "outcome_index": 0
}
FieldTypeRequiredDescription
market_idUUIDYesMarket to cancel orders in
outcome_indexintNoFilter by outcome; omit for both

Response

{
  "message": "market orders cancelled",
  "market_id": "550e8400-e29b-41d4-a716-446655440000",
  "cancelled": 12
}

Heartbeat (Auto-Cancel)

POST /v1/orders/heartbeat

Scope: trade:orders

Send a heartbeat to keep your orders alive. If no heartbeat is received within 15 seconds, all open orders for the user are automatically cancelled.

Use this as a dead-man's switch to protect against network disconnections.

Request Body

{}

Response

{
  "status": "ok",
  "server_time": 1709136000
}

server_time is the Unix-second timestamp at which the heartbeat was received. The 15-second dead-man's-switch deadline is server_time + 15.