DOCS
Historical data archive
Full tick, Level 2 and option-chain history since 2019 over REST — for backtesting and research.
The historical archive serves the complete record — every trade tick, every Level 2
book update, and daily option-chain snapshots (full greeks & open interest) — back to 2019, straight from our
Parquet stores as JSON. It's the same data our own research and live-tested
algos run on. Base URL: https://api.tick-stream.xyz/v1.
These endpoints require a data-archive package (or All-in-One):
/history/ticks and /history/book need the NQ ticks archive,
/history/options needs the options archive. Each package comes in two forms —
a one-time purchase (the archive up to your purchase date, yours forever; ranges past your
snapshot date are clamped and the response carries snapshot_until) or the
updates subscription (same price up front, then $10/mo; the archive always reaches live).
Cancelling the updates subscription converts it into a snapshot at the end of the last paid month — you
keep everything you paid for. Want to evaluate first? A free 2-month NQ tick sample
(Feb – Mar 2025, 22.9M trades, plus two full days of Level-2 depth, same schemas) is downloadable without signup. The live snapshot endpoints (/quote, /ticks)
are separate and come with any realtime plan.
Common parameters
All three endpoints share the same range and paging contract.
| Param | Required | Description |
|---|---|---|
start / end | no | ISO-8601 (2022-06-13 or 2022-06-13T13:30:00Z) or Unix seconds. Defaults to a short window ending now — pass an explicit range for the archive. |
limit | no | Max rows per call (default 50,000, max 500,000). |
Every response carries count and truncated. When truncated is
true, fetch the next page by setting start to the last returned
ts (rows are time-ordered, oldest first). Timestamps are Unix seconds (UTC).
GET /history/ticks
Full trade-tick archive for a futures symbol. NQ ticks plan.
| Param | Required | Description |
|---|---|---|
symbol | yes | Futures root, e.g. NQ, ES. |
curl "https://api.tick-stream.xyz/v1/history/ticks?symbol=NQ&start=2022-06-13&end=2022-06-14" \
-H "Authorization: Bearer sk_live_…"from tickstream import Client
c = Client("sk_live_…")
rows = c.history_ticks("NQ", start="2022-06-13", end="2022-06-14")
print(len(rows), "ticks"){
"symbol": "NQ",
"start": 1655085600, "end": 1655172000,
"count": 48213, "truncated": false,
"ticks": [
{ "ts": 1655127000, "price": 12043.25, "size": 2, "side": "buy" }
]
} Each tick: ts, price, size, and side (the aggressor — "buy" or "sell").
Aggressor provenance. From March 2026 onward, ticks are our own live capture and side is the exchange-reported aggressor. For 2019 – Feb 2026 the archive is built from a historical BBO tape (every trade print plus the prevailing best bid/ask); side is inferred with the standard quote rule — trade at the ask = "buy", at the bid = "sell", tick rule inside the spread (<1% of prints remain "unknown"). Re-encoded 2026-07-03; daily volume now matches real contract volume across the whole archive. If you downloaded tick history before that date, re-pull it — the earlier encoding exposed raw quote updates alongside trades.
GET /history/book
Level 2 order-book depth archive — every bid/ask update. NQ ticks plan.
| Param | Required | Description |
|---|---|---|
symbol | yes | Futures root, e.g. NQ. |
curl "https://api.tick-stream.xyz/v1/history/book?symbol=NQ&start=2024-01-10T14:30:00Z&end=2024-01-10T15:00:00Z" \
-H "Authorization: Bearer sk_live_…"{
"symbol": "NQ", "count": 12044, "truncated": false,
"book": [
{ "ts": 1704897000, "side": "bid", "level": 1, "price": 16942.50, "size": 14, "flag": 0 }
]
} Each row: ts, side ("bid"/"ask"), level (1-based depth rank, 1 = best level in the stream's window), price, size, and flag.
Two eras, two models. From June 2026 onward rows are our own live capture: full-book snapshots at a ~250 ms cadence (≈4/s) — all levels of both sides re-stated in each snapshot, flag always 0. Group rows by ts and replace the whole book; no event-sourcing needed.
For the 2019 – Feb 2026 archive the source is an incremental depth tape and flag is the book action: 0 = add, 1 = update, 2 = remove. The replay rules below were derived empirically against two full days (24M events) and are the best-performing of ~10 candidate rule sets we measured:
- remove → delete by price; the
levelfield on removes is window bookkeeping (reads 10) — ignore it. A miss is a no-op (measured miss rate ~2–4%). - add → dedupe the price, then insert sorted (bids descending, asks ascending). An add is "a level entered the visible window" — do not insert at the
levelindex (bottom entries report as level 9). - update at level
Lwith priceP— three cases vs. the current occupant of slotL: same price → size update;Pbetter (closer to the touch) → insert atL(upward ladder shift);Pworse → overwrite slotL(downward shift — the displaced level dies implicitly, no remove is sent for it). Always drop any other slot holdingP. - Apply no cap and no re-sort of your own — the window maintains itself through the feed's add/remove flow (depth settles at ~9 per side).
Measured on full-day replays (2025-03-03 / 2025-06-13): whole-book consistency 72% / 61% of observations, top-3 levels clean 89% / 82%. The residual inconsistency lives in the lower ranks and is inherent to the vendor tape; for a guaranteed-consistent view, optionally drop any level that breaks strict monotonicity (top-down walk). Rows are stored and served in exact event order; replay each day from its first row (each day opens with an add-sequence snapshot, L1…L9 per side).
Archive window caveat. In the archive era the depth window sits behind the touch: the vendor streams best bid/ask separately, and the book stream's level 1 is typically one tick behind the true best (mode +1 tick, ~75% of the time). Treat the archive book as depth/liquidity structure, not as an exact top-of-book reference — for touch-sensitive work use the trade prints from the tick dataset alongside it, or the June-2026+ snapshot era, which is exact.
GET /history/options
Option-chain snapshot archive with full greeks. Options plan.
| Param | Required | Description |
|---|---|---|
underlying | yes | Option underlying — historical archive covers QQQ, SPY, DIA, IWM. |
curl "https://api.tick-stream.xyz/v1/history/options?underlying=QQQ&start=2024-01-10&end=2024-01-11" \
-H "Authorization: Bearer sk_live_…"{
"underlying": "QQQ", "count": 8800, "truncated": false,
"options": [
{ "ts": 1704902400, "expiry": "2024-01-19", "strike": 410, "right": "C",
"bid": 2.41, "ask": 2.44, "last": 2.42, "oi": 15234, "volume": 812,
"iv": 0.142, "delta": 0.55, "gamma": 0.04, "theta": -0.08, "vega": 0.21 }
]
} Each row: ts, expiry, strike, right ("C"/"P"), bid, ask, last, oi, volume, iv, and Black-76 greeks delta, gamma, theta, vega.
Pulling a large range? Page in chunks (e.g. one trading day at a time) and watch truncated. For continuous live data use the WebSocket stream; for recent backfill without the archive plan use /v1/ticks.