Response envelope
The shared REST response envelope has three keys:data is the payload: an array for lists and history, an object for a single snapshot. meta describes the response. Records are not required to repeat the symbol or venue, so read both from meta.
A few catalog and status routes (data quality,
/v1/status/coverage, and /v1/symbols) return their own body shape by default, with success: true and meta.request_id added. With the version header they return the standard envelope, where data holds the body (the symbol array for /v1/symbols).
Health checks use a direct response body. GET /health returns {"service":"0xarchive-api","status":"ok"}, including when the version header is sent. Its request identifier is in the X-Request-Id response header. See the health check schema.
Errors
Every error response is JSON with the same shape, including authentication failures and unknown routes:code is the HTTP status. error_code is a stable, machine-readable name: branch on it, not on the message text. param and valid_values appear when one parameter caused the error. The full list of codes, their statuses, and what to do about each is on Errors. WebSocket error messages carry the same error_code.
Versioning
Send0xArchive-Version: 2026-10-01 on REST requests, and version=2026-10-01 in the WebSocket connection URL, to receive the current contract. Without it, responses keep their earlier shape, so existing integrations keep working unchanged. The official SDKs, CLI, and hosted MCP send it for you.
Authorization: Bearer $OXARCHIVE_API_KEY in the opening handshake; see WebSocket connection.
A response shaped by the version echoes it in the 0xArchive-Version response header, and WebSocket subscribed and replay_started messages include "version": "2026-10-01". A later dated value is read as the newest version the API supports. A value that is not a supported date is ignored and the default shape is returned. Responses carry Vary: 0xArchive-Version, so caches keep the two shapes apart.
What the version changes:
We recommend sending the version on every request in new code. Pin the exact date rather than computing it, so a future version never changes your parser without a code change.
Time
Requests accept either form forstart, end, timestamp, and at:
- Unix milliseconds, for example
1790553600000. - RFC 3339, for example
2026-09-28T00:00:00Zor2026-09-28T02:00:00+02:00. URL-encode+as%2B; a literal+is also accepted.
2026-09-28T14:55:17.295Z. Integer milliseconds appear only in fields whose names end in _ms. The few payloads that still carry integer times without the version header are listed in the Versioning table. Store times in UTC and convert only for display.
Point-in-time reads take timestamp. The levels routes also accept at as a synonym.
Pagination
Every cursor-paged route setsmeta.has_more. meta.next_cursor is present exactly when has_more is true.
- Send the first request with
start,end,limit, and any filters. - While
meta.has_moreistrue, send the same request again withcursorset tometa.next_cursor. Keep every other parameter unchanged. - Stop when
meta.has_moreisfalse.
limit and still have more to come, and the last page can be empty when the previous page was exactly full. Stop on has_more, never on a short page. The maximum limit for each route family is published as page_limit in capabilities. Details and examples are on Pagination.
Parameter names
Every documented parameter changes the result. A value outside the accepted set is rejected with
400 and names the parameter, rather than being silently ignored.
Coverage signals
Each data type has a first served row on each venue, published asavailable_from in capabilities. Per-symbol dates are in /v1/symbols.
- A range that starts before the first row and ends after it is served from the first row. You do not need to trim
start. - A range that ends before a symbol’s coverage begins returns an empty
dataarray withmeta.coverage_fromandmeta.notice, so an empty page is never mistaken for a quiet market. - A range that ends before a data type’s policy floor (for example Hyperliquid candles before 2025-03-01) returns
400witherror_coderange_before_coverage.
Unsupported combinations and unknown routes
A route that asks a venue for a data type it does not offer, such as order flow on Hyperliquid Spot, returns404 with error_code unsupported_for_venue. The message and the available_on list name the venues and routes that do serve it. Any other unknown path returns 404 with error_code route_not_found. Neither is ever an empty or plain-text response.
Deprecated root routes
The unprefixed routes/v1/trades/{symbol}, /v1/orderbook/{symbol}, /v1/funding/{symbol}, /v1/openinterest/{symbol}, and /v1/instruments are aliases for Hyperliquid. They keep working, and every response carries Deprecation: true and a Link header with rel="successor-version" that points at /v1/hyperliquid/. Use the venue-prefixed routes in new code. No removal date has been set.
Capabilities
GET /v1/capabilities lists what each venue serves: one row per venue and data type, with its REST routes, WebSocket channels, whether live streaming and replay are available, the first served time, the cadence, the page limit, and the accepted intervals. It is public, needs no API key, and costs no credits. Use it to check a combination before you call it, and to drive venue and channel choices in your own code. The rendered table is on Capabilities.
Related pages
Errors
Every
error_code, its HTTP status, and what to do next.Capabilities
Venue and data type matrix with live, replay, and history start.
Pagination
Follow
has_more and next_cursor through long histories.Data conventions
Decimal strings, numeric fields, and HIP-4 probabilities.