error_code gives the reason, and request_id lets support find the exact request later.
Response shape
Every error response is JSON with the same top-level fields, on every route, including authentication failures, rate limits, and unknown paths:
Some routes add their own fields, such as
available_on on unsupported_for_venue. Ignore fields you do not recognize. If a response has no error_code, fall back to the HTTP status.
Error codes
A few routes use their own codes for conditions that only they have, such as
positions_unavailable on account position routes. Treat a code you do not recognize as a generic error of its HTTP status.
Versioned and earlier names
Four codes predate this list. They are still sent to clients that do not send the version header, so existing integrations keep working. With0xArchive-Version: 2026-10-01 (see Versioning), you get the current names:
Handle both spellings if your client runs without the header. With the version header, an inverted or malformed window returns
invalid_time_range and a malformed cursor returns invalid_cursor. Without it, some routes return an empty page for an inverted window, and trades routes read a malformed cursor as no cursor. Never edit or construct a cursor.
Parameter validation errors
A parameter that fails to parse, or carries a value the route does not accept, returns400 with param naming it. Where the accepted set is small, valid_values lists it.
?limit=abc, returns the same shape with the parse error in error:
error_code invalid_query_params. Handle all of these the same way: fail fast, log request_id plus error_code and param, correct the parameter, and do not retry the request unchanged.
Unsupported venue and unknown route
A request for a data type that the venue does not offer returns404 with unsupported_for_venue. The body names the data type and the routes where it is available:
404 with route_not_found, and a known path called with the wrong method returns 405 with the same code:
WebSocket errors
WebSocket errors arrive as messages on the open connection, with the sameerror_code values:
slow_consumer and endpoint_unsupported occur only on WebSocket. A connection that is refused before it opens, for example because the key is invalid or the connection limit is reached, is an HTTP response to the upgrade request, not an error message. See WebSocket connection.
Status handling
Retry policy
- Retry
- Do not retry unchanged
Retry a REST
rate_limited, transient 5xx, and network timeouts within a bounded budget, waiting the retry_after seconds or the Retry-After header when the response gives one, and capped exponential backoff with jitter when it does not. Do not retry insufficient_credits, and do not resend a WebSocket subscribe refused with rate_limited: unsubscribe from something first. When you reach a limit has the rule for each limit.Next-call routing
Do not treat every failed request as a reason to rerun the same call faster. Route the next call by error class.Log enough to act on
Treat request IDs as part of your application log schema. Storemeta.request_id for each successful REST pull, including the coverage and freshness calls that set up a replay, and the top-level request_id from the error body for each failed attempt. When a route returns a resource-specific body, such as some data-quality routes, store the route path, parameters, returned status fields, and the x-request-id response header or the client wrapper’s request handle. When a job spans pagination windows, keep the request ID per page instead of only the final one.
For each failure, log the method, full path, query parameters, venue family, symbol, HTTP status, error_code, param when present, attempt count, backoff delay, and whether the output was skipped, delayed, marked incomplete, or safely continued. A generated client or coding agent should expose the request ID on the returned object or exception; a retry wrapper that hides the original response body makes production failures hard to diagnose. If the final retry succeeds, keep both the successful request ID and the failed attempt IDs.
When a failure needs support, send that context plus the affected workflow, and never the API key. For a data-quality issue, add the observed timestamp, the freshness tolerance you expected, and whether the route feeds a backtest, alert, dashboard, export, or model input.