error/message for detail.
Error shape
error is a stable, machine-readable code you can switch on; message is a
human-readable explanation that may include specifics (amounts, the bucket to
transfer from). New codes may be added over time — treat an unrecognized code as
a generic failure of its status class.
Status codes
| Status | Meaning | What to do |
|---|---|---|
200 / 201 | Success | Read the response body. |
400 | Bad request — malformed body, invalid enum, or insufficient bucket balance | Fix the request; don’t retry unchanged. |
401 | Not authenticated — missing/expired session or key | Re-run the SIWE flow or check your x-api-key. |
403 | Forbidden — wrong scope, IP not allowed, or action not permitted | Use a trade-scoped key; check IP allowlist. |
404 | Unknown resource — market, order, or record not found | Verify the id. |
409 | Conflict — duplicate clientOrderId or conflicting state | Treat as already-applied; reconcile. |
422 | Business rejection — the request was valid but the engine declined it | Handle by code (see below); do not blindly retry. |
429 | Rate limited | Back off until the window resets. |
5xx | Server or upstream error | Retry with backoff; if persistent, contact support. |
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 available margin. Every order passes a
server-side margin gate before acceptance. Read your headroom from
GET /perps/positions and GET /perps/balances, reduce size, or fund the
venue — do not retry the same order.Insufficient {bucket} balance
Insufficient {bucket} balance
A transfer or withdrawal exceeds the source bucket’s available balance.
Withdrawals draw only from
wallet; transfer back from perps/options/spot
first. Returned as 400.POST_ONLY_WOULD_CROSS
POST_ONLY_WOULD_CROSS
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_REJECTED
REDUCE_ONLY_REJECTED
A
reduceOnly order would have increased your position (e.g. wrong side or
already flat). Check your current position before retrying.Strategy not fully filled
Strategy not fully filled
A multi-leg combo could not fill every leg immediately. Combos are
all-or-none (FOK) — the whole strategy is rejected and nothing executes.
Re-price the legs and resubmit.
Order would not fill (IOC / FOK)
Order would not fill (IOC / FOK)
An
ioc order found no liquidity to take, or a fok order could not be
filled in full. Nothing rests; adjust price or time-in-force.A
422 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
Requests are rate-limited per client. Authenticated sessions and API keys get a higher budget than anonymous traffic. Every response carries the current window state so you can pace yourself.| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the current window |
X-RateLimit-Remaining | Requests left in the window |
X-RateLimit-Reset | When the window resets |
429 Too Many Requests. Back off until
X-RateLimit-Reset, ideally with exponential backoff and jitter.
Handling 429 in practice
Idempotency
To make retries safe, send aclientOrderId on order and quote endpoints. If a
response is lost and you retry, the same clientOrderId prevents a duplicate
order — reconcile by reading the resulting order rather than assuming it failed.
Quoting endpoints also accept a quoteId to group and atomically replace a
market-maker’s quote set.