DOCS/CONCEPTS

Schema reference

Every venue, every dataset, one set of columns. A Binance trade and a Hyperliquid trade have the same shape, the same types and the same clock, so a query written for one venue runs on all of them.

This page documents schema version 0.9 (draft), which becomes 1.0 when the v1 API goes live with Phase 1. Column names on this page are final for 1.0; we may still add columns before then, and we will not remove or rename any without a changelog entry. Every response and file states the version it was written with (FDC-Schema-Version header on REST, fdc.schema_version in Parquet metadata).

Conventions

  • Timestamps are int64 nanoseconds since the Unix epoch, UTC. No time zones, no ISO strings, no floats.
  • Prices and sizes are decimal128(38,18) in Parquet and strings in JSON and CSV, so nothing is lost to binary floating point. Trailing zeros are dropped: a venue's "0.10" becomes "0.1".
  • Sizes are in base units on every venue. Contract counts are converted with contract_size from instruments, which is why a Binance coin-margined contract and a Hyperliquid perpetual can be summed directly.
  • Enums are lowercase strings, dictionary-encoded in Parquet. New enum values can appear in minor versions; code that reads them should pass unknown values through instead of failing.
  • Null means the venue does not publish the value for that row. We never fill a missing value with zero or a guess.

Types

TypeParquetJSON
stringUTF-8 stringstring
int32 / int64INT32 / INT64number
decimal128(38,18)FIXED_LEN_BYTE_ARRAY, DECIMAL(38,18)string, for example "104318.5"
float64DOUBLEnumber
boolBOOLEANtrue / false
enumstring, dictionary-encodedstring
list<string>LIST of stringarray of strings
JSON numbers above 253 lose precision in JavaScript. Nanosecond timestamps are around 1.8 × 1018, so parse with a library that keeps 64-bit integers (for example json-bigint) or use Parquet.

Common columns

Every market-data table (all tables on this page except instruments, gaps and the two chain tables) starts with these columns, in this order.

ColumnTypeDescription
venueenumVenue id, lowercase: hyperliquid, binance, bybit, okx and so on. Full list on Venues.
symbolstringNormalized symbol, for example BTC-PERP or BTC-USDT. Rules on Symbology.
venue_symbolstringThe venue's native symbol, unchanged: BTC on Hyperliquid, BTCUSDT on Binance, BTC-USDT-SWAP on OKX.
ts_exchangeint64Venue timestamp in nanoseconds since the Unix epoch, UTC. Scaled up from the venue's native precision, so a millisecond venue always ends in six zeros. Null when the venue sends no timestamp for the message type.
ts_captureint64Our receive timestamp in nanoseconds since the Unix epoch, UTC, from a PTP-disciplined clock on the capture host. Null only on venue_archive rows, which we did not capture. See Timestamps & clocks.
seqint64Venue sequence number for the stream the row came from. Rows produced by one venue message share a seq. Null for venue_archive rows and for the few streams where a venue publishes no sequence (listed per venue on Venues).
sourceenumfdc_capture for rows we captured live, venue_archive for rows backfilled from a venue's published archive, fdc_derived for rows we compute (candles, hourly book snapshots, extended fields).
regionenumCapture region that supplied the row after merging: apne1 (Tokyo), euw1 (Ireland), use1 (N. Virginia, from Phase 2). Null for venue_archive rows.

A row's identity is (venue, symbol, seq) plus its position within the message. Where seq is null, use (venue, symbol, ts_exchange, trade_id) for trades.

Datasets

Columns below are listed after the common columns. Tags show the lowest plan that includes the dataset; plan details are on Pricing.

trades

RESEARCHERPARQUET · CSV · JSON

One row per execution as printed by the venue. When a single aggressive order sweeps several levels, venues differ: some print one trade per maker, some print one aggregated trade. We keep the venue's granularity; taker_order_id lets you aggregate where it is published.

Primary key: (venue, symbol, trade_id)

ColumnTypeDescription
pricedecimal128(38,18)Execution price in quote currency.
sizedecimal128(38,18)Executed quantity in base units (contracts converted to base using contract_size from instruments).
sideenumAggressor side: buy when the taker bought, sell when the taker sold. Null on the rare venue records that do not identify the aggressor.
trade_idstringVenue trade id as published. Stored as a string because several venues use ids longer than 64 bits or non-numeric ids.
notionaldecimal128(38,18)price × size in quote currency, computed by us. Inverse contracts report notional in USD.
taker_order_idstringOrder id of the aggressing order, where the venue publishes it (Hyperliquid, Coinbase, Deribit). Null elsewhere.
maker_order_idstringOrder id of the resting order. Joins to order_id in book_l3.
is_blockboolTrue for block trades and RFQ fills reported on the public tape (Deribit, OKX). False for on-book matches.
JSON · ONE ROW
{"venue":"hyperliquid","symbol":"BTC-PERP","venue_symbol":"BTC",
 "ts_exchange":1789482600127000000,"ts_capture":1789482600131482113,
 "seq":1094102785458213,"source":"fdc_capture","region":"apne1",
 "price":"104318.5","size":"0.0421","side":"buy","trade_id":"812774190531627",
 "notional":"4391.80885","taker_order_id":"141092377410","maker_order_id":"141092371988",
 "is_block":false}

quotes

RESEARCHER

Level 1: best bid and offer. One row each time either side of the top of book changes.

ColumnTypeDescription
bid_pricedecimal128(38,18)Best bid price. Null when the bid side is empty.
bid_sizedecimal128(38,18)Total size resting at the best bid, base units.
ask_pricedecimal128(38,18)Best ask price. Null when the ask side is empty.
ask_sizedecimal128(38,18)Total size resting at the best ask, base units.
originenumvenue when the venue publishes a top-of-book feed, book when we derive L1 from our L2 reconstruction. Both are emitted for venues that publish L1 separately, so you can compare them.

candles

RESEARCHER

OHLCV bars built by us from trades, bucketed on ts_exchange (source = fdc_derived), or taken from a venue's licensed historical archive, where the agreement with that venue includes one (source = venue_archive). Intervals with no trades produce no row. For candles, ts_exchange is the time of the last trade in the bucket, ts_capture is when the bucket closed in our pipeline and seq is the sequence of the last trade.

Primary key: (venue, symbol, interval, ts_open)

ColumnTypeDescription
intervalenum1s, 1m, 5m, 1h or 1d.
ts_openint64Bucket start, nanoseconds, aligned to UTC. Buckets are assigned on ts_exchange so they line up with the venue's own charts.
opendecimal128(38,18)First trade price in the bucket.
highdecimal128(38,18)Highest trade price.
lowdecimal128(38,18)Lowest trade price.
closedecimal128(38,18)Last trade price.
volumedecimal128(38,18)Traded quantity, base units.
quote_volumedecimal128(38,18)Traded notional, quote currency.
buy_volumedecimal128(38,18)Base volume where the aggressor bought. volume − buy_volume is aggressor-sell volume.
trade_countint64Number of trades.
vwapdecimal128(38,18)Volume-weighted average price. Null when trade_count is 0.

book_l2

RESEARCHERSNAPSHOTS + DELTAS

Price-level order book. One row per level per update. Order books are never backfilled: history starts on the day our capture of the venue began (Hyperliquid: November 2025). Read Order book depth before replaying: the semantics of snapshots, truncation and is_last matter.

ColumnTypeDescription
sideenumbid or ask.
pricedecimal128(38,18)Price level.
sizedecimal128(38,18)New total size resting at this level, base units. "0" removes the level. Sizes are never incremental.
is_snapshotboolTrue on rows of a full-depth snapshot, which replaces the whole book. Snapshots are written at every UTC hour (so each daily file opens with the 00:00 snapshot) and whenever the venue sends one, for example after a resync. False on deltas, which set one price level.
snapshot_reasonenumWhy a snapshot was written: venue (sent by the venue, for example on subscribe or after a resync), file_start (the 00:00 UTC snapshot that opens each daily file) or checkpoint (our hourly full-depth snapshot, and the synthetic snapshot that starts a REST or SDK response). Null on deltas.
is_lastboolTrue on the final row of one venue message. Apply rows up to and including is_last before reading the book, so you never observe a half-applied update.
checksumint64On file_start and checkpoint snapshot rows: CRC32 of the top 25 levels of our snapshot, computed as described on Order book depth. Null on other rows. Venue checksum values stay in the raw tier.
checksum_okboolResult of validating the venue checksum against the raw message at capture time, on venues that publish one (OKX, Kraken, Bitget, Bitfinex). Null on venues without a checksum.
level_countint32Number of orders at the level, where the venue publishes it (OKX, Bitget, Kraken). Null elsewhere.

book_l3

DESKORDER EVENTS

Order-by-order book: every add, modify, cancel and fill, on venues that publish order-level data. Hyperliquid L3 is built from validator node output, so it covers every order on the book.

ColumnTypeDescription
order_idstringVenue order id. Stable for the life of the order, including across modifies that keep the id.
eventenumadd, modify, cancel or fill.
sideenumbid or ask: the side the order rests on.
pricedecimal128(38,18)Order price after the event.
sizedecimal128(38,18)Remaining resting size after the event, base units. 0 after a full fill or a cancel.
fill_sizedecimal128(38,18)Quantity filled by this event. Null unless event = fill.
trade_idstringFor fills, the trade this fill belongs to. Joins to trades.trade_id.
is_snapshotboolTrue on snapshot rows: add events that list every resting order in queue order, written at every UTC hour and after a resync. False on live events.
snapshot_reasonenumvenue, file_start or checkpoint, as in book_l2. Null on live events.
is_lastboolSame meaning as in book_l2: final row of one venue message or block.
prev_pricedecimal128(38,18)Price before a modify. Null for other events.
prev_sizedecimal128(38,18)Resting size before the event. Lets you compute the change without keeping state.
keeps_priorityboolFor modifies, whether the order keeps its place in the queue under the venue's rules (a size decrease usually does, a price change never does).
order_typeenumlimit, post_only, ioc, stop or trigger, where the venue publishes it. Null otherwise.
reduce_onlyboolReduce-only flag, where published.

book_l4

DESKL3 + PARTICIPANT

All book_l3 columns, in the same order, plus participant_id, counterparty_id and entity_id. Participant attribution comes from the venue, where it publishes it; entity_id needs the chain intelligence add-on. Chain-derived attribution across venues (L4+) lives in the chain tables.

ColumnTypeDescription
participant_idstringAccount identifier published by the venue. On Hyperliquid this is the trader's on-chain address, lowercase hex with 0x prefix (42 characters). Null where the venue does not attribute the order.
counterparty_idstringFor fills, the participant on the other side. Null for other events.
entity_idstringEntity that controls participant_id, from our chain intelligence. Joins to chain_entities. Populated only with the chain intelligence add-on (included in Enterprise); null otherwise, and null when the address is not resolved.

funding

RESEARCHER

Predicted and settled funding rates for perpetuals. One settled row per contract per interval; predicted rows at the venue's publication cadence. Venues settle every hour, every 4 hours or every 8 hours, so compare venues on rate_1h.

Primary key: (venue, symbol, kind, ts_funding, ts_exchange)

ColumnTypeDescription
kindenumpredicted (published continuously during the interval) or settled (the rate actually paid at ts_funding).
ratedecimal128(38,18)Rate for one funding interval as published by the venue, as a fraction (0.0001 = 1 bp). Positive means longs pay shorts.
interval_sint32Funding interval in seconds: 3600 on Hyperliquid, 28800 on most Binance, Bybit and OKX contracts, with exceptions that change over time.
rate_1hdecimal128(38,18)rate scaled to one hour: rate × 3600 / interval_s. The column to compare across venues.
rate_anndecimal128(38,18)rate_1h × 8760. Simple annualization, no compounding.
ts_fundingint64Settlement time of the interval this rate applies to, nanoseconds.
accrualdecimal128(38,18)On predicted rows, the funding accrued so far in the current interval where the venue publishes it. On settled rows, equal to rate.
mark_pricedecimal128(38,18)Mark price at publication, where the venue includes it.
index_pricedecimal128(38,18)Index price at publication, where included.

Hourly grid

Funding is also published on a UTC hourly grid, one row per perpetual per hour, so venues with different intervals line up without resampling. Grid rows carry the common columns plus:

ColumnTypeDescription
ts_gridint64The UTC hour this row describes, nanoseconds.
predicted_rate_1hdecimal128(38,18)The latest predicted rate at ts_grid, scaled to one hour.
staleboolTrue when the latest predicted rate is older than the venue's normal publication cadence allows, for example during an outage.
age_sint32Seconds between the predicted row used and ts_grid.

open_interest

RESEARCHER

Open interest per derivative contract, at the venue's push cadence or sampled every 5 seconds where the venue only offers a REST endpoint.

ColumnTypeDescription
oi_contractsdecimal128(38,18)Open interest in the venue's contract units, as published.
oi_basedecimal128(38,18)Open interest in base units, converted with contract_size.
oi_notional_usddecimal128(38,18)Open interest in USD, using the venue's own valuation when published, otherwise oi_base × mark_price.
originenumstream when pushed by the venue, poll when sampled from a REST endpoint. Polled rows have seq null.

liquidations

RESEARCHER

Forced closures as published by the venue. Coverage follows what each venue publishes and is confirmed with the venue before capture starts; see Venues.

ColumnTypeDescription
sideenumSide of the liquidation order: sell closes a long, buy closes a short.
pricedecimal128(38,18)Execution price, or the bankruptcy price where the venue reports only that (noted in price_kind).
price_kindenumexecution or bankruptcy.
sizedecimal128(38,18)Liquidated quantity, base units.
notional_usddecimal128(38,18)Liquidated notional in USD.
methodenumbook (sent to the order book), backstop (taken over by a liquidity vault, such as Hyperliquid's HLP), adl (auto-deleveraging).
participant_idstringParticipant liquidated, where the venue attributes it (Hyperliquid addresses). Null elsewhere.
throttledboolTrue when the venue's feed is sampled (for example, at most one liquidation per symbol per second), so this row may stand for several liquidations. Sum notional_usd from such feeds with care.
trade_idstringTrade id of the resulting fill, where it can be matched.

mark_index

RESEARCHER

Mark, index and oracle prices for derivatives, at the venue's publication cadence.

ColumnTypeDescription
mark_pricedecimal128(38,18)Venue mark price used for margin and liquidation.
index_pricedecimal128(38,18)Venue index price (the spot reference).
oracle_pricedecimal128(38,18)Oracle price where the venue runs a separate oracle (Hyperliquid validators publish one roughly every 3 seconds). Null elsewhere.
basis_bpsfloat64(mark_price / index_price − 1) × 10,000, computed by us.

options_chain

RESEARCHERPHASE 2+

Top of book, mark, implied volatility and greeks per option, as published by the venue (planned for Deribit, OKX, Bybit and Binance). In v1 we do not compute IV or greeks ourselves. A full-chain snapshot is written every minute, with change rows in between.

ColumnTypeDescription
underlyingstringNormalized underlying, for example BTC.
expiryint64Expiry time, nanoseconds.
strikedecimal128(38,18)Strike price.
option_typeenumcall or put.
bid_pricedecimal128(38,18)Best bid, quoted in the venue's premium currency (see premium_ccy).
ask_pricedecimal128(38,18)Best ask.
bid_sizedecimal128(38,18)Size at best bid, contracts.
ask_sizedecimal128(38,18)Size at best ask, contracts.
mark_pricedecimal128(38,18)Venue mark price.
premium_ccystringCurrency the prices are quoted in: BTC on Deribit inverse options, USDT or USDC on linear ones.
underlying_pricedecimal128(38,18)Underlying or forward price the venue used for greeks.
mark_ivfloat64Implied volatility of the mark, annualized, as a fraction (0.52 = 52%).
bid_ivfloat64IV of the best bid. Null where not published.
ask_ivfloat64IV of the best ask. Null where not published.
deltafloat64Venue-published delta.
gammafloat64Venue-published gamma.
vegafloat64Venue-published vega.
thetafloat64Venue-published theta.
open_interestdecimal128(38,18)Open interest, contracts.
is_snapshotboolTrue on rows of the full-chain snapshot written every minute, which lists every listed option once. False on change rows between snapshots.

instruments

ALL PLANSREFERENCE

Reference data with full history, versioned daily. Each row describes one instrument for one period; a tick size change closes the old row and opens a new one. Join on (venue, symbol) with valid_from <= ts < valid_to to get the contract specs in force at any moment. Common columns present: venue, symbol, venue_symbol, source.

Primary key: (venue, symbol, valid_from)

ColumnTypeDescription
instrument_idint64Our stable id. Survives venue renames where the venue keeps the same contract and book.
instrument_typeenumspot, perp, future or option.
venue_marketstringThe venue's own market or product type, where one native symbol is reused across markets (Binance spot and USD-M, Bitget product types). Null where the venue has a single market.
basestringBase asset, normalized (BTC, never XBT).
quotestringQuote asset.
settlestringSettlement asset. USDC for Hyperliquid perpetuals, BTC for inverse BTC contracts.
contract_kindenumlinear, inverse or quanto. Null for spot.
contract_sizedecimal128(38,18)Base units per contract. Sizes in every other table are already converted with this value.
multiplierint32Symbol multiplier for contracts listed in units of 1,000 or 1,000,000 (for example 1000PEPE-PERP). 1 otherwise.
tick_sizedecimal128(38,18)Minimum price increment.
lot_sizedecimal128(38,18)Minimum size increment, base units.
funding_interval_sint32Default funding interval in seconds for perpetuals (3600, 14400 or 28800). Null for other instruments. Each funding row also carries the interval in force for that print in interval_s.
min_notionaldecimal128(38,18)Minimum order notional, quote currency, where published.
max_leverageint32Maximum leverage at the time of the row, where published.
expiryint64Expiry, nanoseconds. Null for spot and perpetuals.
strikedecimal128(38,18)Strike, options only.
option_typeenumcall or put, options only.
statusenumtrading, halted, reduce_only, expired or delisted.
listed_atint64Venue listing time where the venue publishes it, otherwise the first trade we or the venue archive recorded.
delisted_atint64Delisting or expiry time. Null while live.
successor_idint64For a contract the venue replaced with a new listing, the instrument_id of the replacement.
valid_fromint64Start of the period this row describes. Reference data is versioned daily: we take each venue's instrument list once per UTC day, and any change to tick size, lot size, status or symbol opens a new row starting at 00:00 UTC of the day it was first observed.
valid_toint64End of the period. Null for the current row.

extended

RESEARCHER100 MS GRID + EVENTS

Derived microstructure fields computed on ts_capture. Stored in long format: one row per field, variant and timestamp. The SDK (wide=True) and REST (layout=wide) can return a wide layout instead, with one column per field and variant (ofi_ml_l1, ofi_ml_l5, vpin and so on). Field definitions, parameters and units are on Extended fields.

ColumnTypeDescription
fieldenumField key: ofi_ml, vpin, queue, cxl_fill, resil, lambda, markout or part.
variantstringOutput of the field, such as l5 for OFI-ML or buy_1s for markouts.
valuefloat64Field value. Units per field on Extended fields.
on_gridboolTrue for rows on the 100 ms ts_capture grid, false for event-driven rows.
emitenumgrid or event. The same information as on_grid, as a string for readable filters.
ts_availableint64When the value became knowable, nanoseconds on the ts_capture clock. Equal to ts_capture except on per-trade markout events (trade time plus 60 s) and sweep events (when the measurement closed).
ref_idstringOn per-trade markout events, the trade_id. Null otherwise.

chain_entities

ENTERPRISEL4+

Address-to-entity links from our blockchain intelligence. Core columns are below; the full column list, methods and coverage are on Chain intelligence.

ColumnTypeDescription
entity_idstringOur entity id, stable across addresses and venues.
addressstringOn-chain address linked to the entity.
chainenumChain of the address.
labelstringEntity label where one is established.
entity_typeenumCategory: exchange, protocol, bridge or unlabeled.
confidencefloat64Confidence of the address-to-entity link, 0 to 1.
valid_fromint64Start of the period the link is valid for.
valid_toint64End of the period. Null while current.

chain_flows

ENTERPRISEL4+

On-chain transfers between resolved entities and venue wallets. Core columns are below; direction, trade links and confidence are documented on Chain intelligence.

ColumnTypeDescription
ts_blockint64Block timestamp, nanoseconds.
chainenumChain.
tx_hashstringTransaction hash.
from_entitystringSending entity_id, where resolved.
to_entitystringReceiving entity_id, where resolved.
assetstringAsset transferred.
amountdecimal128(38,18)Amount in asset units.
venueenumVenue on either end of the flow, when one side is a known venue wallet.

gaps

ALL PLANS

Every interval that survived dual-region merging without data. A gap is recorded, never filled. How gaps are detected is on Data quality.

Primary key: gap_id

ColumnTypeDescription
gap_idstringStable id, for example gap_hl_20260611_0007.
venueenumVenue id.
datasetenumAffected dataset, such as book_l3. One outage can produce rows for several datasets.
symbolstringAffected symbol. Null when the whole venue stream was affected.
seq_startint64First missing sequence number, where the stream is sequenced.
seq_endint64Last missing sequence number.
ts_startint64Last good ts_capture before the gap, nanoseconds.
ts_endint64First good ts_capture after the gap. Null while the gap is still open on the live stream.
reasonenumseq_break (sequence discontinuity), checksum_mismatch (venue checksum failed), venue_outage (venue stopped publishing, including maintenance) or disconnect (our connections dropped in every region).
regions_missinglist<string>Regions that missed the interval. A row exists only when every capturing region missed it.
resyncboolTrue when the book was rebuilt from a fresh venue snapshot after the gap. The first book rows after ts_end are then a snapshot.
detected_byenumHow the gap was found: seq (venue sequence check), checksum (venue checksum), region_compare (the two regions' streams compared), snapshot_compare (a full venue snapshot disagreed with our book) or trade_reconcile (trade ids or counts checked against the venue's REST history after the day closes).
detected_atint64When our pipeline recorded the gap.
revisionint32Data revision in which this row first appeared.
notestringPlain-text detail, such as the venue's maintenance notice id.

Parquet layout

Bulk files follow one path pattern for every dataset. Access is granted per customer through cross-account S3 permissions; setup is on Bulk S3.

PATH
s3://fdc-archive/{dataset}/venue={venue}/date={YYYY-MM-DD}/{symbol}.parquet

s3://fdc-archive/book_l3/venue=hyperliquid/date=2026-09-15/BTC-PERP.parquet
s3://fdc-archive/trades/venue=hyperliquid/date=2026-09-15/ETH-PERP.parquet
  • Partitioning. One file per symbol per UTC day. A row belongs to the day of its ts_capture. Rows with source = venue_archive (from a venue's licensed historical archive, where the agreement with that venue includes one) have null ts_capture and seq; they are partitioned and sorted by ts_exchange.
  • Sort order. Rows are sorted by ts_capture, then seq, then position within the message. Row group statistics on ts_capture let Arrow, DuckDB, Polars and Spark skip row groups when you filter on time.
  • Row groups. Up to 1,000,000 rows each. Compression is zstd level 3. Enum and string columns are dictionary-encoded.
  • Book files start with the 00:00 UTC full-depth snapshot, so each daily file can be replayed on its own. Further snapshots follow at every UTC hour.
  • Names use the normalized symbol. Characters outside [A-Z0-9-] do not occur in symbols, so no escaping is needed.

File metadata

Each file carries key-value metadata in its Parquet footer.

KeyExampleMeaning
fdc.schema_version0.9Schema version the file was written with.
fdc.datasetbook_l3Dataset name.
fdc.revision1Data revision. Starts at 1; a corrected file is republished with the next number. See Data quality.
fdc.row_count48210377Rows in the file, for a cheap completeness check.
fdc.gap_count0Rows in gaps that overlap this file.
fdc.seq_range1094042255360000-1095332003840411First and last seq in the file.
fdc.sha2569f2c…e41aDigest of the row data, stable across re-encodings of the same revision.

Reading a file

import polars as pl

path = "s3://fdc-archive/trades/venue=hyperliquid/date=2026-09-15/BTC-PERP.parquet"
df = (
    pl.scan_parquet(path)
      .filter(pl.col("ts_capture") >= 1789482600000000000)  # 14:30 UTC
      .select("ts_capture", "price", "size", "side")
      .collect()
)

CSV and JSON

CSV and newline-delimited JSON contain the same columns in the same order as Parquet. CSV files have a header row, use a comma separator, quote only when a value contains a comma, and write null as an empty field. JSON rows omit nothing: null values are written as null. Both are gzip-compressed in bulk delivery (.csv.gz, .jsonl.gz).

Versioning

Within a major schema version, changes are additive: new columns go at the end of a table and new enum values may appear. Renaming a column, changing its type or changing its meaning requires a new major version, announced at least 90 days ahead on the changelog, with both versions served in parallel for at least 12 months. Data corrections are a separate mechanism (revisions, not schema versions) and are covered on Data quality.