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

# L2 Orderbooks

> Replay raw captures into sorted top-25 historical books.

This endpoint replays source captures from a preceding snapshot and returns a sorted top-25 book after each L2 event. Unlike [L2 Orderbook Updates](/endpoints/l2-updates), each returned row represents a reconstructed book. Deltas before a source snapshot produce no book.

## Request

```bash theme={null}
curl -H "Authorization: Bearer $POLARIS_API_KEY" "https://api.polaris.supply/l2-orderbooks?source=hyperliquid&market=BTC&start=1727200000000&end=1727200060000&limit=2"
```

### Query parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `source` | `string` | Yes | Required exact source identifier |
| `market` | `string` | Yes | Required exact normalized routing market |
| `instrument` | `string` | No | Exact venue-native instrument |
| `start` | `integer` | Yes | Required inclusive collector time in Unix milliseconds |
| `end` | `integer` | Yes | Required inclusive collector time in Unix milliseconds, at or after start |
| `limit` | `integer` | No | Page size from 1 to 1000; defaults to 200 |
| `cursor` | `string` | No | Opaque keyset cursor bound to this complete query; anonymous continuation skips rows that have aged beyond the last hour |

## Access and behavior

`source`, `market`, `start`, and `end` are required. The time range is inclusive and may have any duration, but replay is limited to 100,000 matching raw captures, 1 GiB of ClickHouse reads, and 30 seconds. Requests over a limit return `422`. Older history requires a Polaris API key. `source_event_is_snapshot` marks the source event that produced each complete book.

## Response

| Field | Type | Required | Description |
| - | - | - | - |
| `items` | `OrderbookL2EventItem[]` | Yes | — |
| `has_more` | `boolean` | Yes | — |
| `next_cursor` | `string / null` | Yes | — |

### `items[]` fields

| Field | Type | Required | Description |
| - | - | - | - |
| `event_id` | `string` | Yes | — |
| `source` | `string` | Yes | — |
| `market` | `string` | Yes | — |
| `instrument` | `string / null` | Yes | — |
| `collector_timestamp` | `integer` | Yes | — |
| `exchange_timestamp` | `integer / null` | Yes | — |
| `source_capture_id` | `string` | Yes | — |
| `schema_version` | `integer` | Yes | — |
| `source_event_is_snapshot` | `boolean` | Yes | — |
| `bid_px_00`–`bid_px_24`, `bid_sz_00`–`bid_sz_24`, `ask_px_00`–`ask_px_24`, `ask_sz_00`–`ask_sz_24` | `number / null` | Yes | Fixed top-25 price and size slots for each side. |

A `next_cursor` continues the same source, market, instrument, and time range. For source snapshots and sparse absolute-level updates without reconstruction, use [L2 Orderbook Updates](/endpoints/l2-updates).

## Pagination

Pass `next_cursor` as `cursor` with the same filters. Stop when `has_more` is false, or when `next_cursor` is null for endpoints without `has_more`. A cursor is opaque; do not edit or reuse it with different filters.

## Errors

The OpenAPI contract lists `400`, `401`, `422`, `429`, `503`. Error responses use `error.code`, `error.message`, and `error.resolution`. Narrow an expensive query after `422`. Follow `Retry-After` after `429`.

For the machine-readable contract, see the [OpenAPI document](https://api.polaris.supply/openapi.json).
