Skip to main content

Overview

Top 25 bid and ask price levels at every tick. Prices and sizes are stored as comma-separated strings, best level first. Available as both CSV (gzip-compressed) and Parquet (zstd-compressed).

Columns

Column
CSV typeParquet typeDescription
exchangestringstringAlways kalshi
tickerstringstringMarket ticker
local_timestampintegerint64Capture timestamp (nanoseconds since epoch)
exchange_timestampstringtimestamp_micros (nullable)Exchange timestamp
bid_pricesstringstringComma-separated bid prices (best first)
bid_sizesstringstringComma-separated bid sizes at each price level
ask_pricesstringstringComma-separated ask prices (best first)
ask_sizesstringstringComma-separated ask sizes at each price level

Fetching Data

Use the path from the list response. The download endpoint returns a 302 redirect to a signed URL; follow it with curl -L or equivalent.
import requests

def download_top_25(path, api_key):
    url = f"https://api.predictiondata.dev/v2/datasets{path}"
    headers = {"x-auth-token": api_key}

    response = requests.get(url, headers=headers, allow_redirects=True)
    response.raise_for_status()

    filename = path.split("/")[-1]
    with open(filename, "wb") as f:
        f.write(response.content)

    print(f"Downloaded to {filename}")

if __name__ == "__main__":
    api_key = "YOUR_API_KEY"
    path = "/kalshi/KXSB-26-NE/top-25/2026-02-03.csv.gz"

    download_top_25(path, api_key)

Notes

  • The orderbook is the YES orderbook. Bids are the raw YES bids from Kalshi. Asks are calculated by taking 1 - price of the NO bids. If you need the raw, unconverted data, contact calder@predictiondata.dev.
  • Prices and quantities are rounded to 4 decimal places.
  • local_timestamp is nanoseconds since Unix epoch (when our servers captured the message).
  • exchange_timestamp is when the event occurred on Kalshi. In CSV it is an RFC 3339 string; in Parquet it is stored as TimestampMicros.
  • Each export covers one UTC day (00:00:00 to 23:59:59).