Data

Data dictionary

Files are daily Parquet (zstd). Kalshi files are one per series per UTC day; Polymarket and Limitless books are one per market. Timestamps are UTC nanoseconds. Kalshi prices are dollars between 0 and 1, and Kalshi sizes are contracts. Schema version 1.

Layout

Files are partitioned hive-style, so DuckDB, Polars, Spark, and pyarrow can read a downloaded folder as one dataset and skip days and series you filter out.

Read a folder of files
import duckdb
duckdb.sql("""
  SELECT ticker, minute, mid_close
  FROM read_parquet('kalshieye-data/bbo_1m/*/*/*.parquet', hive_partitioning = true)
  WHERE series = 'KXBTC15M' AND date >= '2026-10-12'
""").df()

Every dataset below has a sample file. For a whole day, the free sample on Hugging Face has October 13, 2026 for seven Kalshi series in this layout, and the examples on GitHub query it in place.

DatasetWhat it holdsPlan
book_l2Every price level and every change to the YES and NO bid books. Snapshot rows set a level; delta rows add to it.Full book
book_snap_1sThe top ten YES bid and ask levels at the end of every second in which the book changed.Research
bboBest YES bid and ask with sizes, one row each time any of the four values changes.Research
bbo_1mMinute bars of the YES mid with closing bid and ask, plus trade count and volume.Explorer
tradesEvery recorded fill with YES price, size, and taker side.Explorer
spotBest bid, ask, and last for each crypto underlying on Coinbase, Bitstamp, and Kraken, every update.Research
marketsOne row per market open at any time during the day: terms, strikes, times, tick size, rules, fees, and outcome.Explorer
settlementsEvery market that settled during the day: result, settlement value, the underlying value it settled on, and when.Explorer
seriesEvery Kalshi series: title, category, frequency, fee schedule, settlement sources, and contract terms.Explorer
incidentsEvery hour of the day where the recorder was blind, missed sequence numbers, or dropped messages.Explorer
polymarket_l2Every Polymarket CLOB snapshot and price-level change, for both outcome tokens of every market.Full book
polymarket_tradesEvery Polymarket CLOB trade: outcome price, size, taker side, fee, and transaction hash.Research
polymarket_fillsEvery OrderFilled log from the Polymarket exchange contracts on Polygon.Research
polymarket_marketsEvery Polymarket market that was accepting CLOB orders during the day: question, outcomes, tick size, and end time.Explorer
chainlinkChainlink oracle prices carried on Polymarket's real-time stream, one row per update.Research
limitless_l2Every Limitless CLOB book update. Each message is a full book, stored as one row per price level.Full book
limitless_marketsEvery active Limitless CLOB market seen during the day.Explorer

Order book (L2, incremental) book_l2

Every price level and every change to the YES and NO bid books. Snapshot rows set a level; delta rows add to it.

Plan: Full book and up. Sample: CSV · Parquet

Path: flat/v1/book_l2/date={date}/series={series}/book_l2-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
seriesstringKalshi series ticker, e.g. KXBTC15M.
seqint64 · nullableKalshi sequence number for the book message.
is_snapshotboolTrue for rows that belong to a full book snapshot. Clear the book for this ticker on the first snapshot row of a new ts_recv, then apply its levels.
sidestring · nullableyes or no. Kalshi books are bids only: a NO bid at p is a YES ask at 1 - p. Null on an empty snapshot (the book was cleared).
pricefloat64 · USD · nullablePrice level.
sizefloat64 · contracts · nullableSnapshot rows: resting size at the level. Delta rows: signed change in size.
  • Each daily file opens with a snapshot (ts_recv = 00:00:00 UTC) of every book carried from the previous day, so a file replays on its own.
  • Rows are in recorder order: ts_recv ascending for each ticker.
  • Rebuild a book: on a snapshot, replace the side's levels; on a delta, add size to the level and drop levels at or below zero.

Order book snapshots (top 10, 1 second) book_snap_1s

The top ten YES bid and ask levels at the end of every second in which the book changed.

Plan: Research and up. Sample: CSV · Parquet

Path: flat/v1/book_snap_1s/date={date}/series={series}/book_snap_1s-{series}-{date}.parquet

ColumnTypeDescription
tstimestamp[ns, UTC] · nsEnd of the second (exclusive). The book as it stood at this instant.
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
seriesstringKalshi series ticker, e.g. KXBTC15M.
bid_px_0float64 · USD · nullableYES bid price, level 0 (0 = best).
bid_px_1float64 · USD · nullableYES bid price, level 1 (0 = best).
bid_px_2float64 · USD · nullableYES bid price, level 2 (0 = best).
bid_px_3float64 · USD · nullableYES bid price, level 3 (0 = best).
bid_px_4float64 · USD · nullableYES bid price, level 4 (0 = best).
bid_px_5float64 · USD · nullableYES bid price, level 5 (0 = best).
bid_px_6float64 · USD · nullableYES bid price, level 6 (0 = best).
bid_px_7float64 · USD · nullableYES bid price, level 7 (0 = best).
bid_px_8float64 · USD · nullableYES bid price, level 8 (0 = best).
bid_px_9float64 · USD · nullableYES bid price, level 9 (0 = best).
bid_sz_0float64 · contracts · nullableYES bid size, level 0.
bid_sz_1float64 · contracts · nullableYES bid size, level 1.
bid_sz_2float64 · contracts · nullableYES bid size, level 2.
bid_sz_3float64 · contracts · nullableYES bid size, level 3.
bid_sz_4float64 · contracts · nullableYES bid size, level 4.
bid_sz_5float64 · contracts · nullableYES bid size, level 5.
bid_sz_6float64 · contracts · nullableYES bid size, level 6.
bid_sz_7float64 · contracts · nullableYES bid size, level 7.
bid_sz_8float64 · contracts · nullableYES bid size, level 8.
bid_sz_9float64 · contracts · nullableYES bid size, level 9.
ask_px_0float64 · USD · nullableYES ask (1 - NO bid) price, level 0 (0 = best).
ask_px_1float64 · USD · nullableYES ask (1 - NO bid) price, level 1 (0 = best).
ask_px_2float64 · USD · nullableYES ask (1 - NO bid) price, level 2 (0 = best).
ask_px_3float64 · USD · nullableYES ask (1 - NO bid) price, level 3 (0 = best).
ask_px_4float64 · USD · nullableYES ask (1 - NO bid) price, level 4 (0 = best).
ask_px_5float64 · USD · nullableYES ask (1 - NO bid) price, level 5 (0 = best).
ask_px_6float64 · USD · nullableYES ask (1 - NO bid) price, level 6 (0 = best).
ask_px_7float64 · USD · nullableYES ask (1 - NO bid) price, level 7 (0 = best).
ask_px_8float64 · USD · nullableYES ask (1 - NO bid) price, level 8 (0 = best).
ask_px_9float64 · USD · nullableYES ask (1 - NO bid) price, level 9 (0 = best).
ask_sz_0float64 · contracts · nullableYES ask (1 - NO bid) size, level 0.
ask_sz_1float64 · contracts · nullableYES ask (1 - NO bid) size, level 1.
ask_sz_2float64 · contracts · nullableYES ask (1 - NO bid) size, level 2.
ask_sz_3float64 · contracts · nullableYES ask (1 - NO bid) size, level 3.
ask_sz_4float64 · contracts · nullableYES ask (1 - NO bid) size, level 4.
ask_sz_5float64 · contracts · nullableYES ask (1 - NO bid) size, level 5.
ask_sz_6float64 · contracts · nullableYES ask (1 - NO bid) size, level 6.
ask_sz_7float64 · contracts · nullableYES ask (1 - NO bid) size, level 7.
ask_sz_8float64 · contracts · nullableYES ask (1 - NO bid) size, level 8.
ask_sz_9float64 · contracts · nullableYES ask (1 - NO bid) size, level 9.
  • Only seconds with at least one book change get a row; carry the last row forward for quiet seconds.
  • Asks are in YES terms: ask_px_i = 1 - (i-th best NO bid). Null means the level is empty.
  • Replayed from book_l2, so it matches book_l2 exactly at each second boundary.

Top of book (every change) bbo

Best YES bid and ask with sizes, one row each time any of the four values changes.

Plan: Research and up. Sample: CSV · Parquet

Path: flat/v1/bbo/date={date}/series={series}/bbo-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
seriesstringKalshi series ticker, e.g. KXBTC15M.
yes_bidfloat64 · USD · nullableBest YES bid.
yes_bid_sizefloat64 · contracts · nullableSize at the best YES bid.
yes_askfloat64 · USD · nullableBest YES ask (1 - best NO bid).
yes_ask_sizefloat64 · contracts · nullableSize at the best YES ask.
  • Derived from book_l2 by replaying the book. Null means that side was empty.

Top of book (1-minute bars) bbo_1m

Minute bars of the YES mid with closing bid and ask, plus trade count and volume.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/bbo_1m/date={date}/series={series}/bbo_1m-{series}-{date}.parquet

ColumnTypeDescription
minutetimestamp[ns, UTC] · nsBar start (inclusive).
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
seriesstringKalshi series ticker, e.g. KXBTC15M.
mid_openfloat64 · USD · nullableFirst YES mid in the minute.
mid_highfloat64 · USD · nullableHighest YES mid in the minute.
mid_lowfloat64 · USD · nullableLowest YES mid in the minute.
mid_closefloat64 · USD · nullableLast YES mid in the minute.
yes_bid_closefloat64 · USD · nullableBest YES bid at the end of the minute.
yes_ask_closefloat64 · USD · nullableBest YES ask at the end of the minute.
book_updatesint64Top-of-book changes in the minute.
trade_countint64Trades in the minute.
trade_volumefloat64 · contractsContracts traded in the minute.
  • Quiet minutes between a market's first and last activity in the day carry the previous close forward (book_updates = 0).
  • Mid is null when either side of the book is empty.

Trades trades

Every recorded fill with YES price, size, and taker side.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/trades/date={date}/series={series}/trades-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
seriesstringKalshi series ticker, e.g. KXBTC15M.
trade_idstring · nullableKalshi trade id.
yes_pricefloat64 · USDTrade price in YES terms.
sizefloat64 · contractsContracts traded.
taker_sidestring · nullableyes or no.
  • Deduplicated on trade_id.

Underlying spot (crypto) spot

Best bid, ask, and last for each crypto underlying on Coinbase, Bitstamp, and Kraken, every update.

Plan: Research and up. Sample: CSV · Parquet

Path: flat/v1/spot/date={date}/asset={asset}/spot-{asset}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
assetstringUnderlying symbol, e.g. BTC.
sourcestringExchange: coinbase, bitstamp, or kraken.
bidfloat64 · USD · nullableBest bid.
askfloat64 · USD · nullableBest ask.
midfloat64 · USD · nullable(bid + ask) / 2.
lastfloat64 · USD · nullableLast price the exchange reported.
  • One file per asset per day, sorted by ts_recv and deduplicated.
  • Join to Kalshi data on ts_recv (same recorder clock). Kalshi crypto markets settle on CF Benchmarks indices; these exchange quotes are a close proxy, not the settlement source.
  • Filtering by series keeps the assets those series reference (KXBTC* keeps BTC).

Markets (point-in-time universe) markets

One row per market open at any time during the day: terms, strikes, times, tick size, rules, fees, and outcome.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/markets/date={date}/markets-{date}.parquet

ColumnTypeDescription
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
event_tickerstring · nullableKalshi event ticker.
seriesstringKalshi series ticker, e.g. KXBTC15M.
titlestring · nullableMarket title.
yes_sub_titlestring · nullableShort label for the YES outcome.
categorystring · nullableArchive category id.
market_typestring · nullablebinary or scalar.
statusstring · nullableStatus when the file was written.
resultstring · nullableSettlement result (yes / no) when known.
open_tstimestamp[ns, UTC] · ns · nullableMarket open.
close_tstimestamp[ns, UTC] · ns · nullableLast trading time.
expected_expiration_tstimestamp[ns, UTC] · ns · nullableWhen Kalshi expects to determine the outcome.
floor_strikefloat64 · nullableLower strike, when the market has one.
cap_strikefloat64 · nullableUpper strike, for between / less markets.
strike_typestring · nullablegreater, greater_or_equal, less, between, structured, ...
tick_structurestring · nullableKalshi price_level_structure, e.g. linear_cent or tapered_deci_cent.
price_rangesstring · nullableJSON list of {start, end, step} tick bands.
can_close_earlybool · nullableWhether the market can close before close_ts.
fee_typestring · nullableSeries fee schedule: quadratic, quadratic_with_maker_fees, flat, ...
fee_multiplierfloat64 · nullableSeries fee multiplier.
rules_primarystring · nullableSettlement rule text.
rules_secondarystring · nullableAdditional rule text.
  • Includes markets that later settled or closed, so it is a survivorship-free universe for that day.
  • Kalshi taker fee per contract is fee_multiplier x 0.07 x P x (1 - P), rounded up to the cent per order.
  • Join to the other datasets on ticker.

Settlements settlements

Every market that settled during the day: result, settlement value, the underlying value it settled on, and when.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/settlements/date={date}/settlements-{date}.parquet

ColumnTypeDescription
tickerstringKalshi market ticker, e.g. KXBTC15M-26OCT121545-45.
event_tickerstring · nullableKalshi event ticker.
seriesstringKalshi series ticker, e.g. KXBTC15M.
categorystring · nullableArchive category id.
resultstring · nullableyes, no, or void.
settlement_valuefloat64 · USD · nullablePayout per YES contract.
expiration_valuestring · nullableValue of the underlying Kalshi settled on (e.g. the BRTI average or the temperature).
close_tstimestamp[ns, UTC] · ns · nullableLast trading time.
settlement_tstimestamp[ns, UTC] · ns · nullableWhen Kalshi settled the market.
ts_recvtimestamp[ns, UTC] · ns · nullableWhen the recorder first saw the settlement.
floor_strikefloat64 · nullableLower strike.
cap_strikefloat64 · nullableUpper strike.
strike_typestring · nullableStrike type.
coin_price_startfloat64 · USD · nullableCrypto markets: underlying at the window start, when recorded.
coin_price_endfloat64 · USD · nullableCrypto markets: underlying at the window end, when recorded.
  • A market appears on the UTC day it settled.

Series reference series

Every Kalshi series: title, category, frequency, fee schedule, settlement sources, and contract terms.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/series/date={date}/series-{date}.parquet

ColumnTypeDescription
seriesstringKalshi series ticker, e.g. KXBTC15M.
titlestring · nullableSeries title.
categorystring · nullableKalshi category.
frequencystring · nullablefifteen_min, hourly, daily, weekly, custom, ...
fee_typestring · nullableFee schedule.
fee_multiplierfloat64 · nullableFee multiplier.
settlement_sourcesstring · nullableJSON list of {name, url}.
contract_urlstring · nullableProduct certification PDF.
contract_terms_urlstring · nullableContract terms PDF.
tagsstring · nullableComma-separated Kalshi tags.
  • Snapshot of Kalshi's series list taken when the day was compacted.

Recorder incidents incidents

Every hour of the day where the recorder was blind, missed sequence numbers, or dropped messages.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/incidents/date={date}/incidents-{date}.parquet

ColumnTypeDescription
hour_starttimestamp[ns, UTC] · nsStart of the hour.
coverage_pctfloat64 · % · nullableShare of the hour the recorder was connected and in sequence.
blind_sint64 · sSeconds with no connection.
seq_missingint64Kalshi sequence numbers never received.
droppedint64Messages dropped by the recorder.
detailstring · nullableWhat happened.
  • Written for every compacted day; an empty file means every hour was clean.
  • Book data resumes from a fresh snapshot after each gap, so books are never stitched across one.

Polymarket order book polymarket_l2

Every Polymarket CLOB snapshot and price-level change, for both outcome tokens of every market.

Plan: Full book and up. Sample: CSV · Parquet

Path: flat/v1/polymarket_l2/date={date}/series={series}/polymarket_l2-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringOutcome token id.
seriesstringCondition id. One file per market per day.
is_snapshotboolTrue for a full book snapshot. Clear that token's book, then apply every snapshot row with this ts_recv.
sidestring · nullablebid or ask. The venue's BUY is bid and SELL is ask.
pricefloat64 · USD · nullableOutcome-token price.
sizefloat64 · shares · nullableShares resting at this price after the event. Zero removes the level.
tick_sizefloat64 · nullableMinimum price increment, when the message included one.
hashstring · nullableBook hash on the venue message.
  • This is the CLOB book tape: a snapshot replaces the token book, and a price change sets the new size at one price.
  • Polymarket sends an absolute size, not a signed delta.
  • Both outcome tokens of a market are in the same file.

Polymarket trades polymarket_trades

Every Polymarket CLOB trade: outcome price, size, taker side, fee, and transaction hash.

Plan: Research and up. Sample: CSV · Parquet

Path: flat/v1/polymarket_trades/date={date}/series={series}/polymarket_trades-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringOutcome token id.
seriesstringCondition id.
pricefloat64 · USDTrade price of the outcome token.
sizefloat64 · sharesShares traded.
sidestring · nullableBUY or SELL, the taker side on that outcome token.
fee_rate_bpsfloat64 · bps · nullableFee rate in basis points, when the venue sent one.
transaction_hashstring · nullableOn-chain transaction hash of the fill, when the venue sent one.
  • Deduplicated on transaction hash, token, price, and size.

Polymarket on-chain fills polymarket_fills

Every OrderFilled log from the Polymarket exchange contracts on Polygon.

Plan: Research and up. Sample: CSV · Parquet

Path: flat/v1/polymarket_fills/date={date}/series={series}/polymarket_fills-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringOutcome token id.
seriesstringOutcome token id. One file per token per day.
exchangestringExchange contract that emitted the log.
order_hashstringHash of the order this log fills.
makerstringMaker of that order.
takerstringTaker. The exchange address on a summary log.
sidestringBUY or SELL, the side of this order.
pricefloat64 · USD · nullableCollateral per share.
sizefloat64 · shares · nullableShares filled.
fee_usdcfloat64 · USDCFee in collateral, 6-decimal units scaled to USDC.
maker_amountstringRaw maker amount filled, 6-decimal token units.
taker_amountstringRaw taker amount filled, 6-decimal token units.
feestringRaw fee, 6-decimal collateral units.
is_summaryboolTrue when this log is the match total and the taker is the exchange. The other logs are the individual maker fills. Sum one of the two, not both.
transaction_hashstringPolygon transaction hash.
block_numberint64Polygon block.
log_indexint64Log index in that transaction.
  • Recorded from the CTF Exchange, the Neg Risk CTF Exchange, and the V2 protocol exchange.
  • A match writes one log per resting order plus one summary log. is_summary marks the summary.
  • The CLOB trade tape is separate. This is the settlement log.

Polymarket markets polymarket_markets

Every Polymarket market that was accepting CLOB orders during the day: question, outcomes, tick size, and end time.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/polymarket_markets/date={date}/polymarket_markets-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen this snapshot of the market was recorded.
tickerstringCondition id.
slugstring · nullableMarket slug.
questionstring · nullableMarket question.
outcomesstring · nullableJSON list of {token_id, outcome}.
tick_sizefloat64 · nullableMinimum price increment.
neg_riskbool · nullableWhether the market is neg-risk.
end_tstimestamp[ns, UTC] · ns · nullableScheduled end.
accepting_ordersbool · nullableWhether the book was accepting orders.
  • One row per condition id: the last snapshot recorded that day.

Limitless order book limitless_l2

Every Limitless CLOB book update. Each message is a full book, stored as one row per price level.

Plan: Full book and up. Sample: CSV · Parquet

Path: flat/v1/limitless_l2/date={date}/series={series}/limitless_l2-{series}-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen the recorder received the message. Use this to order rows.
ts_venuetimestamp[ns, UTC] · ns · nullableExchange timestamp on the message, when the venue sent one.
tickerstringMarket slug.
seriesstringMarket slug. One file per market per day.
token_idstring · nullableOutcome token id, when the book included one.
is_snapshotboolTrue for every row. Each timestamp replaces that market's book.
sidestring · nullablebid or ask.
pricefloat64 · USD · nullableOutcome price.
sizefloat64 · nullableSize at this price, in the venue's book units.
  • Apply every row that shares a ts_recv as one snapshot, then discard the previous book.
  • An empty book is a single row with a null side.

Limitless markets limitless_markets

Every active Limitless CLOB market seen during the day.

Plan: Explorer and up. Sample: CSV · Parquet

Path: flat/v1/limitless_markets/date={date}/limitless_markets-{date}.parquet

ColumnTypeDescription
ts_recvtimestamp[ns, UTC] · nsWhen this snapshot was recorded.
tickerstringMarket slug.
titlestring · nullableMarket title.
expirationstring · nullableExpiration as published by Limitless.
  • One row per slug: the last snapshot recorded that day.

Downloading

List and fetch files
GET  /api/v1/datasets                                # schemas, coverage, plans (public)
POST /api/v1/requests/estimate                       # size a selection (public)
GET  /api/v1/files?dataset=bbo_1m&start_date=2026-10-12&end_date=2026-10-16&series=KXBTC*
POST /api/v1/files/links   {"keys": ["flat/v1/bbo_1m/..."]}

A link is valid for an hour. Each file counts toward your monthly download allowance once per calendar month, however many times you fetch it. Every file has a sha256 in the listing; the Python client and the generated scripts check it and skip files you already have. The calls are list files, file links, and estimate. Coverage totals are coverage.