Skip to main content
Every error is application/json with the same one-field shape, on every route:
The message is written for a human reading a log. Show it, log it, or match on the status code. There is no separate error-code enum to memorize. Three of these deserve special handling in your client:
  • 409 means stop, not retry. Your intent already landed. Re-sending with the same clientOrderId will keep answering 409, and re-sending with a new one would place a second order. Read the account stream to see what actually rests.
  • 503 on a money route means the command was not run. Nothing reached the venue, so the same clientOrderId may be sent again after Retry-After. The one exception is the unknown-outcome answer: an earlier command with that id may be resting at the venue, so read the account stream before deciding, and never mint a new id to get past it.
  • 423 means the account is locked, not that the request was wrong. Surface it to the trader as a risk lock. Retrying in a loop just re-earns the same refusal.
  • 429 tells you exactly how long to wait. Honor Retry-After rather than retrying tightly.
One rule that surprises people: a present Origin header must be on the allowlist even when a valid key is attached. A bearer excuses a missing Origin, never an untrusted one.