Skip to content

Errors

Every non-2xx body is {"error": "<human message>", "code": "<machine code>"} (the 428 confirmation response carries a few extra fields). Match on code, never on the prose — the message may change; the code will not.

code is drawn from a closed enum that evolves additively: a new refusal class adds a member, but no member is ever renamed or removed (a contract test fails CI on a break). So a client can safely switch on it, and an unknown code means a newer server — handle it as a generic failure, don't crash.

Status codes

statusmeaning
400validation / insufficient balance or margin
401missing or unknown key
403compliance refusal, insufficient scope, or a program refusal
404unknown market / order / account, or a route not served here
409idempotency or uniqueness conflict
428confirmation required (first-seen withdrawal destination)
429rate limited (see Rate limits)
503deposits halted — never affects withdrawals

The code vocabulary

The full set, from the spec's ErrorCode enum (the REST reference links it, and /openapi.json carries it verbatim):

codetypical statusmeaning
validation400malformed or out-of-range request
insufficient_balance400not enough free balance
insufficient_margin400order would breach margin
unauthorized401missing or unknown API key
insufficient_scope403key lacks the route's scope
compliance_refused403signup/deposit refused by the compliance gate
referral_forbidden403referral action not permitted
session_limit403account is at its live-key cap
not_found404unknown resource, or route not served here
conflict409uniqueness conflict
idempotency_key_reused409a key reused on a different request
confirmation_required428withdrawal needs a confirmation token
rate_limited429a token bucket is exhausted
deposits_halted503deposits paused (withdrawals unaffected)
feature_unavailable501feature not wired for this deployment
market_halted409/400the market is halted
reduce_only409/400market is reduce-only; order would increase
oracle_stale409/400oracle too stale to price
oi_cap409/400open-interest cap reached
position_limit409/400position limit reached
body_too_large413request body exceeds the cap
unavailable503temporarily unavailable

The status a given code rides can vary with context; the code is the stable signal. Build against code.

Program policy v1 · numbers current as of 2026-08-28

Testnet — test sats have no value. Nothing on this page is an offer, a solicitation, or advice.

Program policy v1 · numbers current as of 2026-08-28
Testnet — test sats have no value. Nothing here is an offer, a solicitation, or advice.