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

# Orderbook Snapshots

> The orderbook dataset shape, coverage, reconstruction, and usage rules

## Shape

Each row is the complete orderbook for one market outcome at one source timestamp. It replaces both sides of the previous book; it is not a level update.

Orderbook snapshots are event-driven, not sampled at a fixed interval. Probalytics processes the venue's ordered event stream, applies each change to the reconstructed book, and publishes a new complete snapshot when the book changes. `VERIFIED` snapshots are thoroughly checked and guarantee that the orderbook is correct. A quiet market can therefore have a long time between rows without any missing data.

<Note>
  Orderbook reconstruction has more moving parts than our other datasets. If anything here is unclear, ask us in the [Probalytics Telegram channel](https://t.me/probalytics) or email [support@probalytics.io](mailto:support@probalytics.io). Include the `market_id`, `outcome.id`, and time range when asking about a specific series.
</Note>

| Field                | Type                    | Values and meaning                                                                                                                                                                                                                                                                          |
| -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `market_id`          | `UUID`                  | Probalytics market ID. Join this to `markets.id`.                                                                                                                                                                                                                                           |
| `market_platform_id` | `string`                | Venue-native market identifier copied from the linked market.                                                                                                                                                                                                                               |
| `platform`           | `enum`                  | `POLYMARKET` or `KALSHI`.                                                                                                                                                                                                                                                                   |
| `outcome`            | `Outcome`               | The outcome whose book is represented. Contains `id` (UUID), `platform_id` (string), `name` (string), and zero-based `index` (integer).                                                                                                                                                     |
| `bids`               | `array<OrderbookLevel>` | Complete bid side, sorted from highest to lowest price. Each level contains `price` (decimal) and aggregate `size` (decimal).                                                                                                                                                               |
| `asks`               | `array<OrderbookLevel>` | Complete ask side, sorted from lowest to highest price. Each level contains `price` (decimal) and aggregate `size` (decimal).                                                                                                                                                               |
| `timestamp`          | `datetime`              | Source event time represented by the book. Different books can share the same timestamp.                                                                                                                                                                                                    |
| `indexed_at`         | `datetime`              | Time Probalytics materialized this row. Use it to inspect delivery timing and choose the newest copy of the same row identity.                                                                                                                                                              |
| `hash`               | `integer`               | Probalytics content hash for row identity and deduplication. It is not a venue hash or a cryptographic proof.                                                                                                                                                                               |
| `state`              | `enum`                  | `VERIFIED` — final snapshot in a processed update sequence; Probalytics guarantees that this orderbook snapshot was reconstructed with no loss<br />`INTERMEDIATE` — earlier book state retained from that same sequence                                                                    |
| `continuity`         | `enum`                  | `CONTIGUOUS` — proven to follow the preceding published row for this outcome<br />`RESET` — the first published row for this outcome, or a later row whose connection to the preceding published row could not be proven. The row is still a complete orderbook and can be used on its own. |
| `path_index`         | `integer`               | Zero-based order within one emitted path. Several rows with the same `timestamp` are ordered by this field. It is not a global sequence number.                                                                                                                                             |

## Reading a snapshot

Every row is a complete, independently usable orderbook. `bids` contains all bids present at that moment, and `asks` contains all asks. You do not need to apply the row to an earlier snapshot or reconstruct missing levels.

An empty `bids` or `asks` array means there were no orders on that side of the book. It does not mean “unchanged.”

Ordering matters when building a time series:

1. Read one `(market_id, outcome.id)` series at a time.
2. Order snapshots by `timestamp`, then `path_index`.
3. If duplicate copies of the same snapshot exist, keep the one with the latest `indexed_at`.
4. When `continuity = RESET`, treat that row as a fresh starting point. If an earlier row exists, do not calculate a change between the two rows or forward-fill values from the earlier row. Continue normally from the `RESET` row.

## State and continuity

`state` and `continuity` answer different questions:

* `state`: how was this row validated within its emitted path?
* `continuity`: can this path be connected to the previously published dataset state?

### Ordering rows

Read one `(market_id, outcome.id)` series at a time and order it by `timestamp`, then `path_index`. Several reconstructed states can share a timestamp; `path_index` orders those states and starts again at `0` for the next update sequence.

`indexed_at` is not source-event order. If the same row identity was written more than once, keep the copy with the latest `indexed_at`.

`RESET` means Probalytics cannot connect this row to a preceding published row. It does not describe whether the current row is final or prove that data is missing. The first published row for every outcome is always `RESET` because no earlier row exists. For a later reset, the connection to the preceding published row could not be proven. That is why the first row after a continuity break can be `INTERMEDIATE + RESET`, followed by `VERIFIED + CONTIGUOUS` in the same update sequence.

| `state`        | `continuity` | How to read the row                                                                                                                                               |
| -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VERIFIED`     | `CONTIGUOUS` | Orderbook reconstructed without gaps, with a proven link to the preceding published state.                                                                        |
| `VERIFIED`     | `RESET`      | Orderbook reconstructed without gaps, but it cannot be connected to a preceding published row. It can be the outcome's first row or a later fresh starting point. |
| `INTERMEDIATE` | `CONTIGUOUS` | Earlier retained book state from an update sequence that produced a `VERIFIED` final snapshot.                                                                    |
| `INTERMEDIATE` | `RESET`      | First retained book state after continuity was restarted. A later row in the same update sequence can be verified and contiguous.                                 |

### Choosing rows by use case

| Use case                            | Rows to use                                                                                                                                     |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Latest gap-free book                | Latest `VERIFIED` row for each outcome                                                                                                          |
| Final snapshots only                | `state = VERIFIED`                                                                                                                              |
| Every reconstructed book transition | Both `INTERMEDIATE` and `VERIFIED`                                                                                                              |
| Gap-sensitive research              | Do not calculate changes across a `RESET`; continue from the reset row                                                                          |
| Reset or feed-quality analysis      | Do not use a raw reset count as a gap count. Separate each outcome's initial reset from later resets, then investigate later resets in context. |

`INTERMEDIATE` does not mean provisional or expected to disappear. These rows are published only after the final snapshot in their update sequence passes validation.

### What continuity does not mean

`CONTIGUOUS` does not mean rows arrive at regular intervals. An inactive market can remain unchanged for hours and then continue with a proven transition.

`RESET` marks a fresh starting point, not necessarily a data gap. Every outcome contributes one expected reset when its first snapshot is published. Later resets mean only that Probalytics could not prove the transition from the previous published state; they do not tell you whether venue events were missed or how many. Causes can include processor replacement, a source sequence gap, an update that cannot be applied, or recovery from a fresh full book.

To classify a reset, check whether an earlier snapshot exists for the same `(market_id, outcome.id)`. If no earlier snapshot exists, this is the expected initialization reset. If an earlier snapshot exists, do not calculate a change between that row and the reset row. A query restricted to a date range can hide the earlier row, so it cannot classify the first reset in the result by itself.

## Timestamp, path order, and identity

Several reconstructed states can share one source timestamp:

```text theme={null}
timestamp=T, path_index=0, state=INTERMEDIATE
timestamp=T, path_index=1, state=INTERMEDIATE
timestamp=T, path_index=2, state=VERIFIED
```

Do not deduplicate by timestamp alone. Different books at the same timestamp are valid distinct rows.

The logical row identity is:

```text theme={null}
market_id,
outcome.id,
timestamp,
hash,
state,
continuity,
path_index
```

If the same identity appears more than once, keep the copy with the greatest `indexed_at`.

### `timestamp` versus `indexed_at`

* Use `timestamp` to order source events.
* Use `path_index` to order reconstructed states sharing one timestamp.
* Use `indexed_at` as the final tiebreaker and to see when Probalytics produced the row.

`indexed_at - timestamp` is observed delivery delay. It includes source-clock differences, buffering, reconstruction, and recovery—not only network time. Recovery can also publish an older source state later, so `indexed_at` must not replace event ordering.

## Hash

`hash` is a Probalytics 64-bit content hash. It covers:

* `market_id`;
* `outcome.id`;
* `timestamp`;
* every published bid price and size;
* every published ask price and size.

It does not include `indexed_at`, `state`, `continuity`, `path_index`, or platform metadata.

The stored `hash` is separate from the hash supplied by Polymarket. Polymarket verification happens before the normalized row is produced; the stored hash identifies the normalized row.

## Price and size precision

Published orderbook prices and sizes are stored as decimal values with six digits after the decimal point.

Use decimal values rather than binary floating point when exact level comparisons or hash reproduction matter.

Prediction-market prices are normally between `0` and `1`. Perpetual and margin prices use venue instrument units. Join `market_id` to markets and inspect `market_type` before combining products.

## Coverage by venue and product

| Venue      | Product                 |      Snapshots |   Markets | Coverage starts | Notes                                                                                                                            |
| ---------- | ----------------------- | -------------: | --------: | --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Polymarket | Prediction-market books | 83,248,715,002 | 2,380,433 | 2025-11-20      | Data before 2026-02-17 can have lower capture frequency and gaps. High-quality, high-frequency reconstruction begins 2026-02-17. |
| Polymarket | Perpetual books         |  1,264,049,214 |        67 | 2026-07-11      | Every published source frame is already a complete book.                                                                         |
| Kalshi     | Prediction-market books | 51,835,309,511 | 3,426,492 | 2026-05-09      | Yes and No books are published together for each reconstructed state.                                                            |
| Kalshi     | Margin books            |    974,713,894 |        13 | 2026-06-19      | Full books and changes are reconstructed using source ordering.                                                                  |

<sub>Counts as of 2026-08-27 11:59 UTC. Coverage starts use the earliest source `timestamp`. Prediction and perpetual/margin rows are separated using the linked market's `market_type`.</sub>

Orderbook rows are produced when a book changes, not on a fixed timer. An inactive market can therefore have long intervals with no rows.

The dataset updates continuously, so these values change throughout the day. Query the data warehouse for current values:

```sql theme={null}
SELECT
    s.platform,
    if(m.is_perpetual = 1, 'PERPETUAL', 'PREDICTION') AS product,
    count() AS snapshots,
    uniqExact(s.market_id) AS markets,
    min(s.timestamp) AS earliest_snapshot
FROM orderbook_snapshots AS s
LEFT ANY JOIN
(
    SELECT
        id,
        platform,
        toUInt8(1) AS is_perpetual
    FROM markets FINAL
    WHERE market_type = 'PERPETUAL'
) AS m
    ON s.market_id = m.id
   AND s.platform = m.platform
GROUP BY
    s.platform,
    product
ORDER BY
    s.platform,
    product;
```

## Polymarket prediction-market books

### Source and reconstruction

| Polymarket input          | How Probalytics uses it                                                             |
| ------------------------- | ----------------------------------------------------------------------------------- |
| Full book                 | Initializes or replaces the reconstructed book for one outcome asset                |
| Price-level change        | Applies the change to the reconstructed book and produces a new complete book state |
| Trade or tick-size change | Advances the ordered event sequence used to reconstruct the next book state         |
| Venue-provided book hash  | Compared with the hash calculated from the final reconstructed book                 |

Each outcome asset has its own published row. Multiple source connections are reconstructed independently. Equivalent states are deduplicated, and a healthy source can continue publication when its state is anchored to the last published book.

### What `VERIFIED` means for Polymarket prediction markets

`VERIFIED` guarantees that the orderbook was reconstructed without gaps. For Polymarket prediction markets, the final reconstructed book must reproduce the venue-provided book hash. `INTERMEDIATE` rows are earlier book states from that same verified update sequence.

`continuity` remains separate. A `VERIFIED + RESET` row matches the venue hash, but its connection to the preceding published row cannot be proven. Treat it as a fresh starting point.

## Polymarket perpetual books

### Source and reconstruction

Each published source frame contains the complete bid and ask book for one instrument. Probalytics publishes it against the instrument's synthetic `Long` outcome.

| Polymarket perpetual input | How Probalytics uses it                                     |
| -------------------------- | ----------------------------------------------------------- |
| Instrument ID              | `market_id`, `market_platform_id` through the linked market |
| Full bids                  | Complete `bids` array                                       |
| Full asks                  | Complete `asks` array                                       |
| Source timestamp           | `timestamp`                                                 |

### What `VERIFIED` means for Polymarket perpetuals

Every source frame is already a complete book, so a published frame is `VERIFIED` without reconstructing it from level changes or comparing a book hash. The first frame for an instrument starts with `continuity = RESET`; later frames are `CONTIGUOUS` while the processor retains that instrument's published state.

## Kalshi prediction-market books

### Source and reconstruction

Kalshi supplies bid books for Yes and No. Probalytics publishes one conventional two-sided book for each outcome.

```text theme={null}
Yes ask price = 1 - No bid price
No ask price  = 1 - Yes bid price
```

The size at the opposing bid becomes the size at the derived ask. Kalshi asks are therefore derived from the opposite outcome's bids, not supplied as independent ask orders.

| Kalshi input                      | How Probalytics uses it                                                                                       |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Yes bid levels in a full snapshot | Publishes them as Yes `bids` and uses them to derive No `asks`                                                |
| No bid levels in a full snapshot  | Publishes them as No `bids` and uses them to derive Yes `asks`                                                |
| A Yes or No bid-level change      | Applies the change, recalculates the derived ask side, and produces new complete Yes and No books             |
| Source sequence number            | Orders source messages; a detected gap makes that source stream unhealthy until a fresh full snapshot arrives |

### What `VERIFIED` means for Kalshi prediction markets

`VERIFIED` guarantees that the orderbook was reconstructed without gaps. If Probalytics detects a source sequence gap or cannot apply a change, it stops publishing from that source stream until a fresh full snapshot rebuilds the book.

`continuity` answers a separate question. A `VERIFIED + RESET` row is gap-free itself, but Probalytics cannot prove that it connects to the preceding published row. Treat it as a fresh starting point. This can happen during processor redeployments, service downtime, software updates, or recovery from a fresh full book.

The Yes and No rows for one reconstructed state share the same `timestamp` and `path_index`. A market-level reset therefore normally appears as two rows - one for each outcome.

## Kalshi margin books

### Source and reconstruction

Kalshi margin supplies full bid/ask books and subsequent level changes for each instrument. Probalytics publishes the reconstructed book against the instrument's synthetic `Long` outcome.

| Kalshi margin input     | How Probalytics uses it                                                                                       |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| Margin ticker           | `market_id`, `market_platform_id` through the linked market                                                   |
| Full bids and asks      | Initializes or replaces the reconstructed book                                                                |
| Bid or ask level change | Applies the change to the specified side and produces a new complete book                                     |
| Source sequence number  | Orders source messages; a detected gap makes that source stream unhealthy until a fresh full snapshot arrives |

### What `VERIFIED` means for Kalshi margin

Kalshi margin uses the same `VERIFIED` and `continuity` rules as Kalshi prediction-market books.

## Historical rows

Some quality fields were added after the first orderbook rows were stored. Older rows can contain these compatibility values:

| Field        | Historical value |
| ------------ | ---------------- |
| `hash`       | `0`              |
| `path_index` | `0`              |

Historical `VERIFIED` rows were also checked to ensure that their orderbooks were reconstructed without gaps. The `hash = 0` and `path_index = 0` values only indicate that those fields were not recorded when the rows were originally written.

See [Tables & Schemas](/docs/sql-guide/tables#orderbook_snapshots) for access-specific database types and query examples.
