Skip to main content

Error shape

Errors return JSON with a readable message. Quote and trading errors can add a stable code:
Branch on code when it is present, and always show or log message. Some errors carry only a message. A few 400 messages start with a stable token such as app_fee_override_requires_api_key:; match on that prefix.

HTTP statuses

Quote and fill codes

These appear on 400 responses from GET /orderbook/{venueMarketOutcomeId}/route, POST /execution/fill, and POST /execution/orders. A rejected fill is remembered for the rest of the quote’s life. Sending the same quoteId again returns the same error. Get a new quote.

Idempotency and safe retries

POST /execution/fill has no separate idempotency key: one quoteId can create at most one set of orders, so resending the same quoteId is always safe. Never get a new quote to retry a fill whose result you do not know, or you can trade twice. After a timeout on POST /execution/fill:
  1. Keep the same quoteId. Poll GET /execution/status?quoteId=, or resend the fill with that quoteId.
  2. Orders in the status response mean the fill was accepted. Track it to a terminal status.
  3. A 404 from status means no orders are recorded yet. The original request may still be running, so treat the result as unknown and keep polling.
  4. Treat the fill as not executed only when the quote’s lifetime has passed, a resend with the same quoteId returns quote_expired, and status for that quoteId still returns 404. Only then get a new quote.
Generate one externalId per intended trade, store it before you send the request, and reuse it across retries. A direct order the venue refuses after acceptance still uses up its externalId. Reads (GET) are always safe to retry.

Rate limits

A 429 carries Retry-After in seconds. Wait that long before retrying. Server calls with a validated x-app-api-key get their own budget. See Base URL, app IDs & API keys.