Skip to main content

Cancel a single order

Response:
If the order already reached a terminal state before your cancel arrived (a re-cancel, a double click, a retry after a timeout):
If this wallet holds no such order (an unknown id, or another wallet’s — the two read the same, on purpose):
Both are 200, not 404: cancellation is idempotent. Treat CANCELLED, already_terminal and not_found all as “nothing left to cancel” — a client that only whitelists CANCELLED and not_found will read a re-cancel as a failure.

202 cancel_pending: recorded, not complete yet

If the platform has recorded your cancel but no answer to it is recorded yet (for example while the matching engine restarts), the response is HTTP 202 with a Retry-After: 5 header:
The cancel is not lost. Send the same cancel again after Retry-After (5 seconds) until it ends. Retrying with the same order id is safe: it finds the same recorded cancel, so it cannot cancel twice. A retry asks the matching engine again, so it completes the cancel as soon as the engine answers. The platform also completes the cancel on its own, but that can take several minutes after a long matching-engine outage, and the order can fill in the meantime. Until the cancel lands, the order may still be open and can still fill, so no remainingQty is given. Its final status arrives on the order WebSocket stream and on GET /api/orders/{id}. That status is CANCELLED, or FILLED if the order filled first. A retry can therefore be answered already_terminal. If a retry is answered 409 order_cancel_not_taken, the matching engine refused this cancel and the order is still open.
Changed (RND-161). This condition used to be answered 503 exchange_unavailable (upstream order_cancel_unanswered) with no Retry-After. While the change rolls out, it can still be answered 503 cancel_unanswered with Retry-After: 5. Handle it the same way: send the same cancel again after Retry-After.

Errors on a single cancel

Field-name conventions across the orders API:
  • The cancel request and response use orderId.
  • List/read endpoints (GET /api/orders/open, /api/orders/history, /api/orders/{id}) return the same value under id.
  • The unfilled remainder is remainingQty everywhere it surfaces (cancel response, order list/read). Treat orderId and id as the same identifier for lookup; the variance is purely a request-vs-response convention.

Cancel a batch by ID

Cancel up to 100 orders by id in one request with POST /api/orders/cancel-batch. Built for an MM re-quote tick: it collapses N single cancels into one round-trip instead of N. It is not atomic: every id is decided and reported on its own, so one id failing neither aborts the request nor undoes the ids already in cancelled.
Response splits every id into cancelled and notCancelled, and remainingQty gives each cancelled id’s unfilled quantity (same meaning as on cancel-all):
Duplicate ids are de-duplicated (cancelled once, reported once). 409 shard_owned_elsewhere and 503 shard_owner_unavailable mean no id was attempted: send the same batch again (after Retry-After, 2 seconds, for shard_owner_unavailable; the platform has already re-sent it for about 6 seconds). 503 exchange_unavailable / exchange_transport_error mean some ids may have been cancelled: re-read the orders, then resend. Rate limited at 5 req/sec/wallet. No KYC / deposit-tier gating — cancellation is always permitted.

Cancel all your open orders

Cancel-all takes no filters. It cancels every open order of the authenticated wallet (your key’s associatedWallet, or the X-User-Wallet on a multi_wallet key) across every market, side and outcome. A request that names marketId, side or outcome, in the body or in the query string, is refused with 400 cancel_all_takes_no_scope and nothing is cancelled. To cancel only part of your book, see Cancelling a subset. Response (HTTP 201) has the cancel-batch shape: cancelled, notCancelled, and remainingQty, which maps each id in cancelled to its unfilled quantity as read when the platform accepted the cancel:
A fill that lands between that read and the cancel taking effect is not reflected, so treat each remainingQty value as an upper bound: size a replacement quote from it, but book fills from the order read (GET /api/orders/{id}), not from quantity − remainingQty. An empty remainingQty ({}) next to a non-empty cancelled means the figures were not returned — never read it as zero left; read the orders instead.
Breaking change (2026-06). cancelled changed from a number to an array of order ids — read cancelled.length for the count. Orders that could not be cancelled now appear in notCancelled (orderId → reason, same vocabulary as cancel-batch) instead of being dropped silently from the count. Cancel-all also operates on a snapshot of the orders open when the request arrives — orders placed while the cancel runs are not guaranteed to be included, so stop quoting first. One call may also stop before it has worked through the whole snapshot: every id it did not attempt is listed in notCancelled as not_attempted. Call cancel-all again until no not_attempted comes back.
The failure answers mean different things. 409 shard_owned_elsewhere and 503 shard_owner_unavailable (the exchange node that serves your account is restarting or being taken over): nothing was attempted, so repeat the call, after Retry-After (2 seconds) for shard_owner_unavailable. The platform does not re-send a cancel-all for you, because a new cancel-all is a new sweep. 503 cancel_all_unknown and 503 exchange_unavailable: the outcome was lost, and some orders may already be cancelled while others still rest. Do not re-issue cancel-all automatically; stop placing orders, then read GET /api/orders/open and decide from what is still open.

Cancelling a subset

Cancel-all cannot be narrowed. To pull only part of your book (for example, all your asks on outcome 0 of one market), list those orders with the filters on GET /api/orders/open, then cancel the returned ids with POST /api/orders/cancel-batch (up to 100 ids per call):
Cancel-all is rate-limited at 1 req/sec/wallet. Use for operational interventions, not normal per-order cleanup.

What a cancel does

A successful cancel takes the order off the book and ends it as CANCELLED. The collateral locked for its unfilled remainder (USDC on a BUY, outcome tokens on a SELL) returns to available. The status change and the collateral release can follow the cancel response rather than land with it, so a read made right after the response can briefly still show the order’s previous status with its collateral locked — re-read rather than assume. Cancelling an order that has already ended changes nothing and answers already_terminal, so repeating a cancel is safe.

Cancellation states