From aggregated levels to individual orders.
Every book we capture is stored as snapshots plus every delta, checked against the venue's sequence numbers. Rebuild the book at any nanosecond in our history, at the depth your model needs.
What L2, L3 and L4 each show you.
The same book, three resolutions. Use the tabs on any panel to switch between them.
Aggregated levels
Total resting size at each price. Good for spreads, depth, slippage estimates and imbalance across levels. Planned on every venue we list.
Order by order
Every resting order, in queue order, with add, modify, cancel and fill events. Needed for queue position, order lifetimes and cancel behaviour.
Attributed flow
L3 plus the participant behind each order, where the venue publishes it. On Hyperliquid that is the on-chain user address of every order.
| L2 | L3 | L4 | |
|---|---|---|---|
| Table | book_l2 | book_l3 | book_l4 |
| Row | A price level changed: new total size. | An order event: add, modify, cancel or fill. | An order event plus participant_id. |
| Tells you | How much is resting at each price. | Which orders are resting, in what sequence, and for how long. | Who placed them, as an address or venue id. |
| Typical use | Spread, depth, OFI, slippage, RESIL. | Queue position, fill probability, CXL/FILL, QUEUE. | Participant behaviour, PART, chain intelligence. |
| Venues planned | 12 | 12 | 7 |
| Plan | Researcher and above | Desk and above | Desk and above |
Rebuild any book at any moment.
Each book is stored as a stream of deltas between full snapshots. We write a full-depth snapshot of every book at each UTC hour boundary from our own reconstructed state, and we also keep every snapshot the venue sends, for example after a reconnect. Snapshot rows are marked is_snapshot = true, and snapshot_reason says which kind: file_start (00:00 UTC), checkpoint (every other hour) or venue.
To rebuild the book at time T, start from the last snapshot at or before T and apply deltas in seq order up to T. The hourly snapshot means at most one hour of deltas to replay, and every daily S3 file opens with the 00:00 snapshot, so each file stands on its own.
is_snapshot at or before T.size, remove it at zero. L3: add, modify, cancel or fill by order_id.gaps for the interval. If a gap overlaps it, the book is valid again from the next snapshot.from decimal import Decimal
from fdc import Client
fdc = Client(api_key="fdc_live_...")
T = "2027-03-12T14:30:00.250Z"
# start at the hour: the first rows are the hourly snapshot
msgs = fdc.book(venue="hyperliquid", symbol="BTC-PERP",
depth="L2", start="2027-03-12T14:00:00Z", end=T)
book, in_snap = {"bid": {}, "ask": {}}, False
for m in msgs:
if m["is_snapshot"] and not in_snap:
book = {"bid": {}, "ask": {}} # new snapshot
in_snap = m["is_snapshot"]
px, sz = Decimal(m["price"]), Decimal(m["size"])
if sz == 0:
book[m["side"]].pop(px, None)
else:
book[m["side"]][px] = sz
best_bid, best_ask = max(book["bid"]), min(book["ask"])curl -G https://api.financedatacloud.com/v1/gaps \
-H "Authorization: Bearer fdc_live_..." \
-d venue=hyperliquid -d symbol=BTC-PERP -d dataset=book_l2 \
-d start=2027-03-12T14:00:00Z -d end=2027-03-12T14:30:01Z
# {"data": [], "next_cursor": null} no gaps: the rebuild is completeSequence numbers, checksums and gaps.
Three checks run on every book we capture. When one fails, the failure is written to a table you can query.
Merged by sequence number
Each venue is captured independently from Tokyo and Ireland. The two streams are merged on the venue's own sequence number, so a message dropped in one region is filled from the other. seq is kept on every row.
Checksums verified
Where a venue publishes a book checksum, we verify it on every update at capture time. Our hourly snapshots carry their own checksum, a CRC32 over the top 25 levels in a documented format, so you can verify your own rebuild.
Gaps recorded, not hidden
A sequence break that survives the merge, or a checksum mismatch, is written to gaps with its start, end and reason. The book resyncs from a fresh venue snapshot. Nothing is interpolated.
| gaps column | Type | Meaning |
|---|---|---|
dataset | string | Affected table, e.g. book_l3. |
seq_start seq_end | int64 | First and last missing venue sequence numbers, where known. |
ts_start ts_end | int64 | Interval during which the book is not guaranteed, ns, capture clock. |
reason | enum | seq_break, checksum_mismatch, venue_outage or disconnect. |
regions_missing | list<string> | Regions that missed it; a gap is only recorded when every capturing region did. |
resync | bool | True when the book was rebuilt from a fresh venue snapshot after the gap. |
detected_by | enum | Which check found the gap, e.g. seq or checksum. |
Book table columns.
All three tables carry the common columns: venue, symbol, venue_symbol, ts_exchange, ts_capture, seq, source.
BOOK_L2
| Column | Type | Meaning |
|---|---|---|
side | string | "bid" or "ask". |
price | decimal | Level price. |
size | decimal | New total size at the level. Zero removes it. |
is_snapshot | bool | Row belongs to a full snapshot. |
snapshot_reason | string | venue, file_start or checkpoint on snapshot rows; null on deltas. |
is_last | bool | Last row of one venue message. Read the book only after it. |
checksum | int64 | Our CRC32 of the top 25 levels, on file-start and hourly snapshot rows. |
checksum_ok | bool | Result of the venue checksum check at capture, where the venue publishes one. |
level_count | int32 | Orders at the level, where the venue publishes it. |
BOOK_L3
| Column | Type | Meaning |
|---|---|---|
order_id | string | Venue order id, unchanged. |
event | string | add, modify, cancel or fill. |
side | string | "bid" or "ask". |
price | decimal | Order price. |
size | decimal | Remaining resting size after the event. |
fill_size | decimal | Size filled, on fill events. |
trade_id | string | Matching row in trades, on fill events. |
is_snapshot | bool | Row belongs to a full snapshot (add events in queue order). |
snapshot_reason is_last | As in book_l2. |
BOOK_L4
| Column | Type | Meaning |
|---|---|---|
all book_l3 columns | Identical meaning. | |
participant_id | string | Participant as published by the venue. On Hyperliquid, the user's on-chain address. |
counterparty_id | string | The participant on the other side, on fill events. |
entity_id | string | Anonymous cross-venue entity, e.g. E-4417, with the chain intelligence add-on. Null otherwise. |
L4 plus entity_id is what we call L4+. See chain intelligence.
L2 and L3 planned on all twelve venues, L4 on seven.
Hyperliquid L2, L3 and L4 ship in Phase 1. Every other venue below is planned, subject to a data agreement with the exchange, and L4 is offered if that agreement includes participant-level data.
Full coverage matrixRead next.
Full depth, with proof nothing is missing.
Pre-register for Hyperliquid L2, L3 and L4 history from November 2025, with early access targeted for Q1 2027.
EARLY ACCESS · PRE-SALE PRICINGPre-register for early access → DANIEL GARCIA · CEO & FOUNDERdaniel@financedatacloud.com →