For Binance, OKX and Hyperliquid perpetuals. Same API key, same symbols, one Parquet file per month of history and per day since August 2026. Metrics stay the fast path; raw is for when you need the ticks.
Six raw datasets, counted separately from the 19 metric datasets. Every file starts with exchange_timestamp, local_timestamp and local_timestamp_kind; exchange and symbol come from the path. Hyperliquid's derivative feed carries no exchange time, so for Hyperliquid we serve trades and quotes only.
Every print, with the venue’s trade id and taker side.
Every trade printed on the venue, with its trade id, taker side, price and size.
Every change at the top of the book.
Top-of-book updates: best bid and best ask with their sizes, one row per change.
Mark and index price, funding and open interest, one row per change.
The venue’s mark price, one row each time it changes.
The venue’s index price for the contract’s underlying, one row each time it changes.
The current funding rate and the next funding time, one row each time either changes.
Open interest as the venue reports it, one row each time it changes.
| Dataset | Binance USDⓈ-M | OKX | Hyperliquid |
|---|---|---|---|
| trades | Mar 2020 → Sep 27, 2026 | May 2019 → Sep 27, 2026 | Nov 2024 → Sep 27, 2026 |
| quotes | Jan 2020 → Sep 27, 2026 | May 2019 → Sep 27, 2026 | Dec 2024 → Sep 27, 2026 |
| mark_price | Feb 2020 → Sep 27, 2026 | May 2019 → Sep 27, 2026 | — |
| index_price | Sep 2020 → Sep 27, 2026 | Jan 2022 → Sep 27, 2026 | — |
| funding_rate | Feb 2020 → Sep 27, 2026 | May 2019 → Sep 27, 2026 | — |
| open_interest | Jun 2020 → Sep 27, 2026 | Oct 2019 → Sep 27, 2026 | — |
6+ TB of Parquet across the six datasets, and growing every day.
First and last day across all symbols of a venue; the raw catalog and /api/v1/metadata/raw list every symbol with its own first day, last day and any missing periods. Perpetuals only.
One request per dataset, symbol and date range (up to 366 days), with your usual X-API-KEY.
The response lists every Parquet file that overlaps the range, each with a download URL valid for one hour.
The Python client downloads them into the same folder layout, skipping files you already have.
Into a DataFrame
from datetime import date
import aperiodic as ap
df = ap.get_raw(api_key="YOUR_KEY", dataset="trades",
exchange="binance-futures", symbol="perpetual-BTC-USDT:USDT",
start_date=date(2025, 6, 1), end_date=date(2025, 6, 3))Sync a folder
ap.download_raw(api_key="YOUR_KEY", dataset="quotes",
exchange="okx-perps", symbol="perpetual-BTC-USDT:USDT",
start_date=date(2025, 1, 1), end_date=date(2025, 12, 31),
output_dir="raw")File layout
raw/trades/exchange=binance-futures/symbol=perpetual-BTC-USDT:USDT/ year=2025/month=06/data.parquet one file per month before 2026-08-01 year=2026/month=08/day=10/data.parquet one file per day from 2026-08-01
Monthly and daily files sit at different depths, so read with a glob and filter on exchange_timestamp:
-- DuckDB
SELECT * FROM read_parquet('raw/**/data.parquet')
WHERE exchange_timestamp >= '2025-06-01';
# polars
pl.scan_parquet("raw/**/data.parquet").filter(
pl.col("exchange_timestamp") >= datetime(2025, 6, 1, tzinfo=UTC))Try it without an account
The shared key DEMO-KEY returns the 2025-06 file of each venue's BTC perpetual, for every dataset:
curl -H "X-API-KEY: DEMO-KEY" \ "https://aperiodic.io/api/v1/data/raw/preview/trades?exchange=binance-futures&symbol=perpetual-BTC-USDT:USDT"
exchange_timestamp is the venue's own time for the event, exactly as it published it.local_timestamp is when the event reached the capture machine. For days we captured ourselves it is measured. For days before that it is modelled: exchange_timestamp plus a latency drawn from the distribution we measure on our own capture, per venue and dataset.local_timestamp_kind says measured or modelled on every row. Don't use modelled days for latency research.Raw L2 order books, liquidations, spot, dated futures and venues other than Binance, OKX and Hyperliquid. Our L2 metrics are on Prime and above.