Error Codes
TL;DREvery error response is a small JSON envelope,
{ code, message }, with a
mapped HTTP status. code is a stable numeric error code you can branch on;
message is the human-readable reason. Every response (success and error)
carries an x-request-id header for correlating with server logs. Success
responses are not enveloped; their typed body is returned directly.Error shape
A failed REST request returns a non-2xx HTTP status and the envelope:/v1/stream order frame returns an error reply carrying the same
numeric code and message the REST path would have returned:
x-request-id header:
Code catalogue
Codes are grouped by class. The HTTP status is derived from the class.
Codes are stable: branch on the number, not the message text (which may change).
Status reference
Conditions by endpoint
Authentication
401: bad credentials (POST /auth/token); a missing, expired, or revoked token on an authenticated request; or a token an operator invalidated. Token expiry is exact — there is no grace period pastexpires_in.403(1150): the account is suspended. Returned both on authenticated requests and onPOST /auth/token, so re-authenticating does not clear it. Not retryable.429(1401): this account’s authentication allowance is exhausted. An unrecognisedapi_keyis refused before any verification work, so it consumes no allowance.503(1402): verification is at capacity; requests are refused rather than queued. Retry after a short, jittered delay.
expires_in window will not meet these limits.
Place order
400: malformed fields, a failed field-element check, a zero order id, a bid with zero price, an off-tick non-zero price, an opening that does not match the signed commitment, or collateral below the required (nominal + fee) floor.400(1010/1011): the collateral proof was rejected at intake — either its Merkle root has aged out of the recent-root window, or the proof itself did not verify. Rebuild against a current root and resubmit.403: the trading-key signature does not verify.409: theorder_idis already in the book, or the collateral commitment is reserved by another live/pending order.
Cancel / modify
403: signature does not verify, or the key does not own the order.404: the order is not resting (filled / expired / cancelled).409: cancel nonce or boot session is stale.409(modify): the replacementorder_idis already booked.
Reads (orders, settlement, tree)
400: malformed id / parameter hex.404: unknown order / batch / note.GET /orders/{id}intentionally returns this same response for a foreign account’s order.503(5002, tree only): the mirror disagrees with Solana. Read the selectedMerkleTreeaccount and leaves from chain; do not keep retrying the unsafe mirror.
A rejected order is better than an accepted one that cannot settleCollateral proofs are verified when the order is submitted, not when it
settles. An order whose proof is stale or invalid is refused immediately with
1010 / 1011 and costs you nothing.
Rebuild the proof against a current root and resubmit.Handling errors
Make cancels idempotent in your logicA cancel that races a fill returns
404 once the order has matched. Treat
404-on-cancel as success-equivalent (“the order is gone”) and reconcile state,
rather than as a hard error.