> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xarchive.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Responses

> Parse 0xArchive success responses, error responses, pagination metadata, request IDs, decimal fields, and data-quality payloads.

Parse success, empty, and error responses correctly, and keep the `meta` context that makes a result usable later. Exact types for each route come from [OpenAPI](/openapi) and the [Schemas](/schemas) pages; this page covers the handling every route shares.

Market-data routes return a JSON envelope with `success`, `data`, and `meta`. Data-quality, `/v1/status/coverage`, and `/v1/symbols` keep their own body shape by default, with `success` and `meta.request_id` added, and use the standard envelope when you send `0xArchive-Version: 2026-10-01`. The rules shared by every route are on [API conventions](/conventions).

## Parse a response

<Steps>
  <Step title="Check HTTP status">
    Decide retry, fail-fast, auth repair, or support escalation from the status class.
  </Step>

  <Step title="Check body success">
    Handle `success: false` as an application error and preserve `error_code` and `request_id`.
  </Step>

  <Step title="Handle empty pages">
    Treat `success: true` plus empty `data` as a state to record, not as permission to fabricate records. Check `meta.coverage_from` and `meta.notice` first: present means the window predates coverage; absent usually means a quiet market, though windows past the end of a symbol's coverage also return the plain envelope, so confirm coverage dates via `/v1/symbols`.
  </Step>

  <Step title="Log request ID">
    Store `meta.request_id` for envelope responses, for every page and every failed attempt. For resource-specific bodies, store `x-request-id` or the client wrapper's request handle when available.
  </Step>

  <Step title="Use the route schema">
    Parse `data` from the endpoint-specific OpenAPI schema, not from a nearby example. Keep numeric-looking market fields decimal-safe until the application boundary.
  </Step>

  <Step title="Keep venue context">
    Persist venue family and symbol style beside records so downstream joins do not mix Hyperliquid core, Spot, HIP-3, HIP-4, and Lighter.
  </Step>
</Steps>

## Success envelope

```json theme={"theme":"github-dark"}
{
  "success": true,
  "data": [],
  "meta": {
    "count": 100,
    "has_more": true,
    "next_cursor": "1704067200123_456789",
    "symbol": "BTC",
    "venue": "hyperliquid",
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

| Field | Client behavior |
| - | - |
| `success` | Treat `false` as an application-level failure even when a JSON body exists |
| `data` | Parse according to the endpoint-specific schema |
| `meta.count` | Use for returned item count, not necessarily total available records |
| `meta.has_more` | On cursor-paged routes: keep paging while `true` |
| `meta.next_cursor` | Present exactly when `has_more` is `true`; send it back unchanged as `cursor` |
| `meta.symbol`, `meta.venue` | On per-symbol routes: the canonical symbol and the venue key (`hyperliquid`, `hip3`, `hip4`, `spot`, `lighter`, `rh-lighter`). Records are not required to repeat them |
| `meta.request_id` | Log on success and failure for debugging and support |
| `meta.coverage_from` | Present only when the requested window ends before recorded coverage for the symbol; ISO 8601 start of coverage |
| `meta.notice` | Present alongside `meta.coverage_from`; explains the empty result and points to `/v1/symbols` for per-symbol dates |

## Error envelope

```json theme={"theme":"github-dark"}
{
  "success": false,
  "code": 429,
  "error_code": "rate_limited",
  "error": "Rate limit exceeded. Please slow down.",
  "retry_after": 1,
  "request_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
}
```

Error bodies are flat: `code` repeats the HTTP status, `error_code` is the stable identifier to branch on, `error` is the readable message, and `request_id` sits at the top level rather than under `meta`.

Treat HTTP status as the control signal and the JSON body as debugging context. Validation, auth, route, access, capacity, rate-limit, and upstream errors require different client behavior; [Errors](/errors) gives the retry model for each.

## Empty success responses

Some historical requests return `success: true` with an empty `data` array. Before treating that as "no market activity," check `meta` for coverage annotations. The two empty states mean different things, and a client that skips this check misreads pre-coverage windows as quiet markets.

| Empty `data` plus | Meaning and next call |
| - | - |
| `meta.coverage_from` and `meta.notice` present | The requested window ends before recorded coverage for that symbol begins, so there is no data to fetch in that window. Move the window to `meta.coverage_from` or later; check `/v1/symbols` for per-symbol coverage dates |
| No coverage annotations | No pre-coverage condition was detected. Usually a quiet market inside coverage; a window past the end of a symbol's coverage, such as a delisted or settled market, returns the same plain envelope. Confirm the window against `/v1/symbols` coverage dates before recording a quiet market, then continue, widen, or record as-is |

A request to `/v1/hyperliquid/trades/{symbol}` for a window that ends before the symbol's coverage starts returns:

```json theme={"theme":"github-dark"}
{
  "success": true,
  "data": [],
  "meta": {
    "count": 0,
    "request_id": "d9c8c1ca-a583-471e-9efa-a4fcd03d7777",
    "coverage_from": "2024-12-05T00:00:00Z",
    "notice": "No data in the requested range. Hyperliquid trades coverage for HYPE begins 2024-12-05 (UTC); the requested window ends before coverage starts. See /v1/symbols for per-symbol coverage dates."
  }
}
```

`meta.coverage_from` is the ISO 8601 start of recorded coverage for the requested symbol and data type. `meta.notice` is a human-readable explanation of why the page is empty. These fields appear on per-symbol time-series routes across venues, including trades, candles, order book history, L4 diffs and history, order history, funding, open interest, and liquidations, when the requested window ends before the symbol's own coverage begins. A window that ends before a data type's policy floor returns `400` with `error_code` `range_before_coverage` instead. A window that starts before the first served row and ends after it is served from that row. Quiet windows inside coverage return the plain envelope without annotations.

Do not turn an empty page into synthetic rows in either state. Store the route, query parameters, `meta.count`, `meta.next_cursor`, `meta.request_id`, and any coverage annotations, then decide whether the downstream job should move the window, continue, narrow the window, or mark the output incomplete.

## Pagination

Cursor-paged routes set `meta.has_more`, and `meta.next_cursor` is present exactly when it is `true`. Send the cursor back unchanged with the same filters, and stop when `has_more` is `false`; see [Pagination](/rest-api/pagination). Keep request IDs per page, not just for the final result. A resumable job should store route family, route path, symbol, query parameters, cursor, request ID, output file, and data-quality decision. Confirm the route family, response shape, and freshness with a one-page request before widening a pagination loop.

## Field dictionary

What the common fields mean, and the handling that keeps a backtest honest.

### Numbers and decimals

Types are not uniform across routes, so check the route before you bind a model.

| Where | Type and handling |
| - | - |
| L2 order book `px`, `sz` | Decimal strings. Keep as strings; convert at the app edge with a decimal library |
| L4 order `price`, `size` | Numbers. Already numeric in the payload |
| Funding rate, spread, open interest, mark/oracle price, liquidation value | Decimal strings. Decimal-safe; do not parse as floats when precision matters |

### Timestamps

There are two clocks. Log both when you store a record.

| Field | Meaning |
| - | - |
| `timestamp` | Event time, when the data was that state at the venue. |
| `checkpoint_timestamp` | (L4) the instant the reconstructed book is current to. |
| `measured_at`, `last_updated` | (data-quality / freshness) when 0xArchive last measured the data (ingest/measure time, not event time). |

### Order-book fields

| Field | Where it appears, and meaning |
| - | - |
| `px`, `sz`, `n` | L2. Price, size, and the number of orders resting at that level |
| `oid` | L4. Hyperliquid order ID for one resting order across L4 diffs and history |
| `order_index` | Lighter L3. Numeric Lighter order index. It is not a raw order ID from a Hyperliquid L4 payload |
| `owner_account_index` | Lighter L3. Numeric Lighter account index. It is not a wallet address or user identifier |
| `user_address` | L4 and trades. Wallet attributed to a Hyperliquid resting order or fill when the source reports it |
| `side` | L4 and trades. Venue-native side code: `B` = bid/buy, `A` = ask/sell. L2 uses separate `bids` and `asks` arrays; Lighter L3 uses `bid` or `ask` |
| `diffs_applied`, `last_block_number` | L4. Reconstruction metadata: diffs rolled onto the checkpoint, and the chain block it is current to |

### Trade and liquidation fields

| Field | Meaning |
| - | - |
| `trade_id` | Venue trade/fill ID. |
| `cloid` | Client order ID, when the placer set one. |
| `closed_pnl` | Realized PnL on this fill; `"0"` when the fill opened or added to a position. When the source did not record it, the field is omitted, or `null` on live Lighter trade legs; neither means zero. The finalized Lighter record uses `realized_pnl` instead. |
| `direction` | Human label such as `Open Long` or `Close Long`. |
| `fee`, `fee_token` | Fee paid, including any builder fee, and its token; a negative `fee` is a maker rebate and `"0"` is a real zero. When the source did not record them, the fields are omitted, or `null` on live Lighter trade legs; neither means zero. The finalized Lighter record carries `fee`. |
| `liquidated_user`, `liquidator_user` | On liquidations, the liquidated wallet and the liquidator. |

### IDs to keep

Store `meta.request_id` (or the `x-request-id` header) for support. Keep `oid` and `trade_id` for Hyperliquid L4 and fill joins, and keep `order_index` plus `owner_account_index` as numeric Lighter L3 fields. Do not use Lighter L3 indexes as wallet or raw-order identifiers.

### Probability, not price

HIP-4 `mark_price` and `mid_price` are implied probabilities in `[0, 1]`, not USD. Spot symbols are pairs, and HIP-3 symbols can carry a builder prefix. Keep the venue family with every record so a later join stays inside one family.

### Empty, null, and gap are different

An empty page is one of the two states under [Empty success responses](#empty-success-responses). A null or missing field means "not available for this record," not zero. A coverage gap inside covered history is a third thing: confirm it against the data-quality coverage route rather than inferring it from an empty page.

## Data-quality responses

Data-quality routes answer whether a downstream job should trust a market-data result. A degraded status, incident, latency issue, or coverage gap does not always mean every route is unusable. It means the client must compare the state to the job tolerance and record that decision.

For backtests, alerts, exports, dashboards, and model features, store both the quality response and the downstream data request ID. Coverage routes such as `/v1/data-quality/coverage/{exchange}/{symbol}` return a resource-specific body by default, with `success` and `meta.request_id` added; parse it from the REST reference. Send `0xArchive-Version: 2026-10-01` to receive the same body inside the standard `data` field.

## Export responses

Data Catalog exports return files and dashboard job state, not market-data JSON. Keep the selected market, schema keys, UTC range, estimated size, credits, checkout state, delivery state, and data-rights decision with the export record. For programmatic market data, use the REST API, WebSocket, SDKs, CLI, or MCP Server instead.

## Next step

See a full payload for each route family in [Example responses](/response-examples).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.