Skip to main content
Every error the API raises has the same body:
The HTTP status always matches the code. Two responses carry no JSON body: a request with the wrong method for its path gets 405 Method Not Allowed, and a request to /v1/stream without WebSocket upgrade headers gets a plain-text 4xx.

Error codes

Validation details

Only two codes carry details: UNSUPPORTED_CHAIN carries {chain}, and VALIDATION_ERROR carries a list of {field, message}, one per problem, as in the example at the top of this page. field is the parameter’s name as you sent it, or path, query or body when the problem is not tied to one field.

Limits

The limits exist to stop runaway clients, not to ration normal use. They sit far above what a working integration needs. If you meet one, your client is most likely looping or leaking connections. Every key, evaluation or production, has the same limits. A key’s request budget refills evenly over each minute, and a full minute’s budget can be spent at once, so a backfill can burst and then settle to the steady rate. The IP limit sits above the key limit, so a fleet of your servers behind one outbound IP still gets its full key budget. Treat every number as a ceiling to stay well under, not as an exact quota to run at. A stream connection counts against your key from its handshake until it closes, and requests over the socket spend no request budget. One connection holds up to 100 subscriptions, so most integrations need only a few. GET /openapi.json needs no key, spends no budget, and carries no X-RateLimit-Remaining header.

Response headers

X-RateLimit-Remaining reports your key’s budget. It reports your IP address’s budget instead on a 401, on a 429 from the IP limit, and on a 503 when the key could not be checked. Pace your client on X-RateLimit-Remaining to slow down before you reach the limit.

Retry strategy

  1. Honour Retry-After. Wait at least that long.
  2. Back off exponentially on 500 and 503, with jitter, so parallel workers do not retry in step.
  3. Cap your retries. Three to five attempts are enough. Past that, the problem needs attention.
  4. Never retry a 4xx other than 429. It fails the same way every time.

Request IDs

Every response carries an X-Request-ID header. You can also send your own X-Request-ID: up to 128 visible ASCII characters, with no spaces. The API echoes it back. It replaces any other value with a generated ID rather than rejecting the request. When you contact support about a failed request, include its X-Request-ID.

Errors on streams

A refused stream frame gets an error frame with the same code, message and details. See Connecting to streams.