OrdersService.CancelAllOrders (POST /v1/orders/cancel-all) cancels every open order of an
account that matches a filter. Use it as a kill switch, or to clear a Pair or Side before
requoting.
Which orders are canceled
The filter selects:
- the account: the Subaccount in
subaccount_id; when it is omitted, the caller's Main Account, or the bound Subaccount for a Subaccount-scoped API key - optional Pairs, up to 100; an empty list matches every Pair
- optional
side; when it is omitted, both sides match
An unknown Pair rejects the request. Cancel-all accepts every Pair status, so you can clear your orders on a disabled or halted Pair.
Polyester fixes the set of matching orders when it accepts the request. Every order that is pending or open at that moment is canceled, including orders whose cancellation is already in progress. An order modified after that moment is still canceled.
Orders that Polyester accepts after that moment are not affected, even if they were sent shortly before the cancel-all.
What happens to triggers
oco set the order's other legs too.The triggers themselves keep their reserved funds and behave as follows after a cancel-all:
- A stop-loss, take-profit, or trailing stop that has not fired stays armed and places its order when its condition is met.
- A TWAP keeps running and places its next slice when it is due.
- A ladder ends once none of its levels remains open:
STATUS_CANCELEDwithTRIGGER_CANCEL_REASON_USER_REQUESTwhen none of them filled,STATUS_COMPLETEDwhen any did. - An attached leg whose working exit is canceled ends
STATUS_CANCELEDwithTRIGGER_CANCEL_REASON_USER_REQUEST. Attached legs without a working exit keep protecting the parent's filled position, even when the parent order is canceled; they end only if the parent is canceled before any fill. - A paused trigger stays paused.
Stop all automated trading
To stop every order and trigger, cancel each live trigger first, then cancel all orders. A trigger that fires before its cancel places an order that the cancel-all then cancels.
- List the live triggers, attached legs included, with
TriggersService.ListTriggersand the statusesSTATUS_CREATED,STATUS_ARMED,STATUS_RUNNING, andSTATUS_PAUSED. Over REST, useGET /v1/triggers?status=CREATED,ARMED,RUNNING,PAUSED. Follow the next page token until it is empty. - Cancel each one with
TriggersService.CancelTrigger, orDELETE /v1/triggers/{trigger_id}over REST. Canceling a TWAP or a ladder also cancels its open child orders. - Send the cancel-all.
The dead-man switch cancels what a cancel-all with the same scope cancels, so a client that stopped responding leaves its triggers live.
Request examples
Send the filter to POST /v1/orders/cancel-all. REST takes Pair symbols in symbols:
{
"symbols": ["BTC-USDT"],
"side": "BUY",
"requestId": "ca-1"
}Call /orders.v1.OrdersService/CancelAllOrders. ConnectRPC takes the Pair IDs from GetSpotConfig in symbol_ids:
{
"symbolIds": [1],
"side": "BUY",
"requestId": "ca-1"
}Response fields
Polyester answers as soon as it has durably recorded the cancel-all, before the orders are canceled. A matched order can still execute before its cancel takes effect, so read order updates or order reads for each final outcome. The full schema is in the API reference; these are the rules behind each field.
| Protobuf field | Meaning |
|---|---|
status | SUBMITTED, or DRY_RUN for a dry run |
matched_orders | Open orders that matched the filter when the request was accepted, including orders whose cancellation was already in progress and open orders that triggers placed. Triggers themselves are never counted. Unless dry_run is set, equals submitted_cancels plus failed_cancels |
submitted_cancels | Matched orders for which cancellation was requested, including orders whose cancellation was already in progress. Zero for a dry run |
failed_cancels | Matched orders that could not be submitted because the cancel-all could not be recorded for their Pair. This request does not cancel them. Zero for a dry run |
cancelled_orders | Orders whose cancellation was requested, oldest first, at most 200. Each lists order_id and client_order_id. Empty for a dry run |
total_cancelled | Number of orders whose cancellation was requested, including those not listed. Equals submitted_cancels |
truncated | true when more orders were canceled than cancelled_orders lists |
listing_status | INCLUDED on the first answer. NOT_RETAINED_READ_OPEN_ORDERS on a retry, whose cancelled_orders is empty |
ts, ts_ns | Server time of the response |
REST returns the same fields in camelCase, such as matchedOrders and cancelledOrders, with each orderId as a public ID.
{
"status": "SUBMITTED",
"matchedOrders": 2,
"submittedCancels": 2,
"failedCancels": 0,
"cancelledOrders": [
{ "orderId": "2NEpo7TZRRrLZSi2U", "clientOrderId": "mm-bid-17" },
{ "orderId": "2NEpo7TZRRrLZSi2V", "clientOrderId": "mm-ask-17" }
],
"totalCancelled": 2,
"truncated": false,
"listingStatus": "INCLUDED"
}When truncated is true, read the remaining state with GET /v1/orders/open. A retry with the
same request_id and filter within 120 seconds returns the original status, counts, and timestamp,
but not the list: cancelled_orders is empty and listing_status is NOT_RETAINED_READ_OPEN_ORDERS. An empty list on a retry does not mean nothing was canceled; read
open orders for the current state.
Completion
Each submitted order then moves to CANCELED asynchronously, unless it fills first. Observe the
result through the private WebSocket or GetOpenOrders.
An accepted cancel-all completes even if the service restarts.
failed_cancels is not zero, or matching orders are still open afterwards, send a new cancel-all
with a new request_id.Retries and idempotency
request_id is required and makes the call idempotent. It contains 1 to 64 ASCII letters, numbers, ., _, :, /, or -, and is scoped to the account.
- A retry with the same
request_idand the same filter returns the original outcome and counts and does not cancel again. Polyester retains the result for at least two minutes. - Reusing a
request_idwith a different filter, or with a differentdry_runvalue, is rejected withCONFLICT_IDEMPOTENCY_KEY_REUSE. - A
request_idreused after the retention window starts a new cancel-all. Use a newrequest_idfor every new cancel-all.
Errors
Each entry gives the stable code and the ConnectRPC code, then the condition and what to do.
UNAVAILABLE·Unavailable
The service is busy. The cancel-all may still be processed. Retry with the samerequest_id, then confirm the result.ORDER_CANCEL_OUTCOME_UNKNOWN·DeadlineExceeded
The cancel-all was not confirmed in time. Some or all matching orders may be canceled. Read open orders, then retry with the samerequest_idif needed.CONFLICT_IDEMPOTENCY_KEY_REUSE·AlreadyExists
Samerequest_id, different filter. Use a newrequest_idfor a different cancel-all.UNKNOWN_SYMBOL·InvalidArgument
Unknown Pair. Correct the filter.VALIDATION_ERROR(REST) ·InvalidArgument
More than 100 Pairs. Split the request, or omit Pairs to match every Pair.RATE_LIMIT_EXCEEDED·ResourceExhausted
Rate limited. Retry with the samerequest_idafter backoff.
REST returns 503, 504, 409, 400, and 429 for these conditions.
If the request can be recorded for only some Pairs, the call succeeds and the orders it could not
submit are counted in failed_cancels.
Dry run
With dry_run set, the response counts the matching orders in matched_orders and nothing is
canceled. A dry run uses its request_id; send the live cancel-all with a new one.