DOCS
SDKs & libraries
Official Python, Node, Go and Rust clients covering every endpoint — REST and WebSocket, with the timestamp and symbol conventions handled for you.
Four official clients — Python, Node, Go and Rust — over the same protocol. Each one covers all 21 endpoints, the 12 option-history request types and all 4 streaming channels, manages reconnection and backoff, and authenticates with your API key.
Coverage is not a claim we make by hand: the endpoint list is generated from the gateway's own router, and a build fails if any client falls behind it. Every call below is exercised against production before a release ships.
Install
pip install "tickstream[stream]"
# omit [stream] for REST only — then it has zero dependenciesnpm i @tickstream/client
# Node 22+ needs nothing else; on older Node also: npm i wsgo get github.com/Alx90s/tickstream-gocargo add tickstream Browser: the Node package works unchanged in a browser through any bundler — it
uses the platform's own fetch and WebSocket. Never ship a live key to a
browser, though: put your key behind your own endpoint and proxy what the page needs.
Quickstart
from tickstream import Tickstream
ts = Tickstream() # reads TICKSTREAM_API_KEY
print(ts.quote("NQ"))
# dealer gamma as it stood on a past session
gex = ts.gex("NQ", date="2026-07-15")
print(gex["callWall"], gex["flipLevel"])
for tick in ts.stream("NQ", "ES"):
print(tick["symbol"], tick["price"])import { Tickstream } from "@tickstream/client";
const ts = new Tickstream(); // reads TICKSTREAM_API_KEY
console.log(await ts.quote("NQ"));
const gex = await ts.gex("NQ", { date: "2026-07-15" });
console.log(gex.callWall, gex.flipLevel);
for await (const tick of ts.stream("NQ", "ES")) {
console.log(tick.symbol, tick.price);
}ts := tickstream.New("") // "" reads TICKSTREAM_API_KEY
q, err := ts.Quote(ctx, "NQ")
gex, err := ts.GEX(ctx, "NQ", tickstream.Params{"date": "2026-07-15"})
ticks, errs := ts.Stream(ctx, tickstream.Ticks, "NQ", "ES")
for t := range ticks {
fmt.Println(t.Symbol, t.Price)
}let ts = tickstream::Client::from_env()?;
let q = ts.quote("NQ").await?;
let gex = ts.gex("NQ", &[("date", "2026-07-15".into())]).await?;
let mut stream = ts.stream(Channel::Ticks, &["NQ", "ES"]).await?;
while let Some(t) = stream.next().await {
println!("{} {}", t.symbol, t.price);
} The whole surface
Method names are shown in Python form; Node matches it, Go and Rust use their own casing.
| What | Call |
|---|---|
| Latest quote | quote(symbol) |
| Streamable roots | symbols() |
| Recent ticks (7-day window) | ticks(symbol, start, end) |
| Deep tick archive | history.ticks(symbol, start, end) |
| Deep Level 2 book | history.book(symbol, start, end) |
| Live option chain with greeks | options.chain(underlying) |
| Option history — 12 request types | options.eod(…) · options.greeks_history(…) · … |
| Dealer gamma, live | gex(underlying) |
| Dealer gamma, a past session | gex(underlying, date) · gex(underlying, at) |
| Participant flow | participants(underlying) |
| CFTC positioning | cot(symbol, weeks) |
| Algo catalogue, record, signals | algos.list() · algos.track(id) · algos.signal(id) |
| Orders, positions, fills | exec.orders() · exec.positions() · exec.fills() |
| Place, close, protect | exec.order(…) · exec.close(…) · exec.protect(…) |
| Stream ticks, book, L3, options | stream(…symbols, channel) |
Three things that will bite you otherwise
1. ticks() without start returns one hour. Not seven
days — one hour. The window reaches back seven days on any plan, and years with an archive plan,
but you have to ask for it. This is the most common integration surprise we see.
2. Timestamps come in two units. Range arguments are unix seconds; tick
rows are stamped in microseconds. They differ by a factor of a million, and comparing
them returns nothing rather than raising — so the SDKs convert for you
(as_datetime(), asDate(), Tick.Time(),
Tick::time()) instead of documenting it and hoping.
3. Two opposite symbol conventions. gex() and
participants() take the futures or stock symbol
(NQ, ES, AAPL) and map onto the deep ETF surface
internally. options and history.options take the
ETF or index root (QQQ, SPY, SPX).
Passing QQQ to gex() is a 400 unsupported_symbol.
Streaming, and why silence is not always a bug
Every frame carries a type, ticks included. A filter that skips
anything with a type therefore drops all the data and leaves a socket that looks
connected and delivers nothing — the SDKs handle that for you. Error frames are never swallowed
either: a refused symbol is exactly the failure that reads as a quiet market.
Index levels (SPX, VIX, NDX, RUT) are quotes
rather than trade prints — they update on change, roughly every two seconds, so a flat VIX
genuinely sends nothing. A liquid future going quiet for minutes is worth reporting.
The welcome frame lists what was actually subscribed, so check it against what you asked for.
Errors
Every failure carries the API's machine-readable code — stable, and worth branching
on. A 403 whose code ends in _required means the endpoint works and
your key does not hold that package, which is a different problem from an invalid key and
should not need prose-parsing to tell apart.
Endpoints and what they need
| Endpoint | Needs | Parameters |
|---|---|---|
GET /v1/algos | included | — |
GET /v1/algos/:id/events | included | — |
GET /v1/algos/:id/signal | included | — |
GET /v1/algos/:id/track | included | — |
GET /v1/cot | included | symbol, weeks |
POST /v1/exec/close | execution | — |
GET /v1/exec/fills | included | — |
POST /v1/exec/order | execution | — |
GET /v1/exec/orders | included | — |
GET /v1/exec/positions | included | — |
POST /v1/exec/protect | execution | — |
GET /v1/gex | gex | underlying, symbol, weight, dte, at, date, key |
GET /v1/history/book | nq-ticks archive | end, limit, start, symbol |
GET /v1/history/options | options-data archive | end, limit, source, start, underlying |
GET /v1/history/ticks | nq-ticks archive | end, limit, start, symbol |
GET /v1/options | options stream | underlying |
GET /v1/options/:req | options | — |
GET /v1/participants | gex | underlying |
GET /v1/quote | included | symbol |
GET /v1/symbols | included | — |
GET /v1/ticks | included | end, start, symbol |
included means any plan that can reach the API. The rest are product packages — see
pricing. Option-history request types:
eod, greeks, greeks_first_order, greeks_history, greeks_second_order, greeks_third_order, ohlc, oi, quote, trade, trade_greeks, trade_quote.
No client for your stack? The WebSocket and REST APIs are plain JSON — anything that speaks HTTP works. For AI agents, llms-full.txt is the whole API in one machine-readable file, and there is an MCP server too.