Cancel a single order
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:
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 underid. - The unfilled remainder is
remainingQtyeverywhere it surfaces (cancel response, order list/read). TreatorderIdandidas 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 withPOST /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.
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
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:
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.
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 onGET /api/orders/open, then cancel the returned
ids with POST /api/orders/cancel-batch
(up to 100 ids per call):
What a cancel does
A successful cancel takes the order off the book and ends it asCANCELLED. 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.