Error shapes
The body depends on which layer answered.- Options business rejections carry the code in
error. - Futures business rejections carry the code inside
message, after the status text ("Bad Request: <CODE>: <detail>"). - Gateway errors (authentication, validation, routing) carry only
message. A request that fails schema validation returns400with the offending field inmessage.
Status codes
Common business rejections
These come back on trading and wallet endpoints. They are expected outcomes, not bugs — handle each deliberately.INSUFFICIENT_MARGIN
INSUFFICIENT_MARGIN
The order would breach your margin. Every order passes a server-side margin check before acceptance. If the shortfall is only collateral sitting elsewhere in your account, the gateway moves it and retries once before you see this. Otherwise reduce size or deposit. Options rejections include
details.reason.EXIT_COST_EXCEEDS_EQUITY
EXIT_COST_EXCEEDS_EQUITY
Options: opening this position would leave you unable to close it at current book prices without taking your account to the liquidation line.
POST_ONLY_WOULD_TAKE
POST_ONLY_WOULD_TAKE
A
postOnly order would have taken liquidity, so it was rejected to keep you
on the maker side. Re-price behind the touch and resubmit.REDUCE_ONLY_VIOLATION
REDUCE_ONLY_VIOLATION
A
reduceOnly order would have increased your position (wrong side, or already flat). Check your position before retrying.FOK_NOT_FILLABLE / MARKET_NO_LIQUIDITY
FOK_NOT_FILLABLE / MARKET_NO_LIQUIDITY
A
fok order could not fill in full, or a market order found nothing to take. Nothing executes; adjust price or time-in-force.PRICE_OUT_OF_BAND
PRICE_OUT_OF_BAND
Futures: a limit price too far through the mark and the opposite side of the book.
MARKET_NOT_TRADING / MARKET_HALTED / MARKET_EXPIRED
MARKET_NOT_TRADING / MARKET_HALTED / MARKET_EXPIRED
The market is halted or past expiry (
MARKET_NOT_TRADING on futures; MARKET_HALTED / MARKET_EXPIRED on options).INVALID_PRICE / INVALID_QUANTITY
INVALID_PRICE / INVALID_QUANTITY
A price off the tick, a missing limit price, or a quantity that is not a positive whole number of contracts.
IDEMPOTENCY_CONFLICT
IDEMPOTENCY_CONFLICT
You reused a
clientOrderId with different order parameters. A retry with identical parameters returns the original result instead.RATE_LIMITED
RATE_LIMITED
The engine’s per-account order rate limit. Returned as
400, not 429; options responses include retryAfterMs.leg_match_failed
leg_match_failed
A multi-leg strategy could not fill every leg immediately. Strategies are all-or-none — nothing executes. The body names
failedLegIndex.Insufficient {bucket} balance
Insufficient {bucket} balance
A transfer or withdrawal exceeds the available balance. Returned as
400 from the wallet endpoints.A business rejection is not a transport failure. Retrying it unchanged will fail the same way and can burn your rate budget — fix the cause first.
Rate limits
The gateway limits requests per client in one-minute windows:
Rate-limited responses carry:
When you exceed a limit you receive
429 with a retry-after header and a body { statusCode, error, message, retryAfter } (seconds). Order placement is additionally limited per account by the engines (RATE_LIMITED, above).
Handling 429 in practice
Idempotency
Send aclientOrderId on orders. If a response is lost and you retry with the same clientOrderId and parameters, you get the original result rather than a duplicate order. Reconcile by reading your orders rather than assuming a lost request failed.