Bulk datasets
Tick-by-tick order books captured at sub-150ms intervals, with 100+ days of history. For multi-day or multi-asset pulls, skip the REST API and download Parquet files directly from Cloudflare R2. Free egress, no rate limit, same data as the live endpoints.
How it works
- List dataset day-rows with
GET /v1/datasets— filter by token, timeframe, and date range. - List a day's markets with
GET /v1/datasets/{id}/slugs— each per-market Parquet comes back with a short-lived signed URL. - Download a single market via
GET /v1/datasets/{id}/slug/{slug}(302 redirect, or?format=jsonfor the URL), or useGET /v1/rangeto pull one slug across a date range.
File layout
Data is delivered as one Parquet file per market (per slug). Slugs are shaped <token>-updown-<5m|15m|4h>-<unixStartTs>, e.g. btc-updown-5m-1779234900. Each file contains trades, top-of-book (BBO), and 25-level depth together — there are no separate per-kind files.
- Trades — every executed trade.
- Top of book (BBO) — every best bid/offer update.
- L25 depth — 25-level order book, stored as columns
bid_price_0…bid_price_24,bid_size_0…bid_size_24, and the matchingask_price_*/ask_size_*. Included in the Parquet on both Free and Pro.
Two tiers are available: full (default — includes L25 depth) and topbook (compact: BBO + trades only, ~200× smaller). Select topbook with ?tier=topbook on the /slugs and /slug/{slug} endpoints. Topbook coverage can lag the full archive.
List datasets
| Field | Type | Description |
|---|---|---|
| token | string | Filter by token — btc (Free) or eth (Pro). |
| timeframe | string | One of 5m, 15m, 4h. |
| from | date | Lower bound on the dataset's day. |
| to | date | Upper bound on the dataset's day. |
| limit | number | Page size for pagination. |
| offset | number | Row offset for pagination. |
Example
curl https://polyreplay.dev/api/v1/datasets \ -H "Authorization: Bearer $POLYREPLAY_API_KEY" \ -G \ --data-urlencode "token=btc" \ --data-urlencode "timeframe=4h" \ --data-urlencode "from=2025-01-01" \ --data-urlencode "to=2025-01-07"
{
"plan": "pro",
"pagination": { "limit": 50, "offset": 0, "total": 7 },
"filters": { "token": "btc", "timeframe": "4h", "from": "2025-01-01", "to": "2025-01-07" },
"data": [
{
"id": "8f2c3a1b-...",
"token": "btc",
"timeframe": "4h",
"date": "2025-01-01",
"size_bytes": 12483920,
"row_count": 184231,
"market_count": 6,
"row_count_trade": 41200,
"row_count_bbo": 98031,
"row_count_book25":45000,
"window_pre_s": 900,
"window_post_s": 300,
"slugs_url": "https://polyreplay.dev/api/v1/datasets/8f2c3a1b-.../slugs"
}
]
}data array is empty with pro_only: "day_files" and a free_policy object — grab individual markets through the /slugs and /slug/{slug} endpoints instead.List a day's markets
Returns every per-slug Parquet for that dataset day, each with a signed URL valid for 5 minutes. This listing does not consume the Free daily download cap. Add ?tier=topbook for the compact top-of-book variant.
curl https://polyreplay.dev/api/v1/datasets/8f2c3a1b-.../slugs \ -H "Authorization: Bearer $POLYREPLAY_API_KEY"
{
"plan": "pro",
"tier": "full",
"dataset_id": "8f2c3a1b-...",
"token": "btc",
"timeframe": "5m",
"date": "2026-02-01",
"slug_count": 288,
"expires_in_seconds": 300,
"slugs": [
{
"slug": "btc-updown-5m-1779346200",
"size_bytes": 24576,
"market_ts": 1779346200,
"url": "https://r2.polyreplay.dev/...signed..."
}
]
}url: null and locked: "pro".Download a single market
302-redirects straight to the per-slug Parquet on R2 (5-minute TTL), or add ?format=json to get the signed URL in JSON. Each call consumes one of the Free 150-downloads-per-24h budget. Add ?tier=topbookfor the compact variant (404 if that market hasn't been backfilled to topbook yet).
curl -L -o market.parquet \ https://polyreplay.dev/api/v1/datasets/8f2c3a1b-.../slug/btc-updown-5m-1779346200 \ -H "Authorization: Bearer $POLYREPLAY_API_KEY"
One slug across a date range
Signs the same slug across a span of days in one call. Required: token, timeframe, from, to (YYYY-MM-DD), plus format=slug-only and slug=<slug>. URLs are valid for 10 minutes; up to 60 dates per call. Free keys are clamped to the last 7 days.
curl https://polyreplay.dev/api/v1/range \ -H "Authorization: Bearer $POLYREPLAY_API_KEY" \ -G \ --data-urlencode "token=btc" \ --data-urlencode "timeframe=5m" \ --data-urlencode "from=2026-02-01" \ --data-urlencode "to=2026-02-28" \ --data-urlencode "format=slug-only" \ --data-urlencode "slug=btc-updown-5m-1779346200"
/range clamped to the last 7 days. Pro adds ETH, full history, and unlimited downloads. L25 depth is in the Parquet on both plans.Reading a file
Pandas, Polars, DuckDB — anything that speaks Parquet works directly.
import polars as pl df = pl.read_parquet(url) print(df.head()) # ts_us | market_id | asset_id | outcome | bid_price | bid_size | ask_price | ask_size
For the L25 snapshots, the 25 levels are stored as separate columns (bid_price_0…bid_price_24, bid_size_0…bid_size_24, same for asks). See the book reference for the level semantics.