tickstreamdocs

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 dependencies
npm i @tickstream/client
# Node 22+ needs nothing else; on older Node also: npm i ws
go get github.com/Alx90s/tickstream-go
cargo 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.

WhatCall
Latest quotequote(symbol)
Streamable rootssymbols()
Recent ticks (7-day window)ticks(symbol, start, end)
Deep tick archivehistory.ticks(symbol, start, end)
Deep Level 2 bookhistory.book(symbol, start, end)
Live option chain with greeksoptions.chain(underlying)
Option history — 12 request typesoptions.eod(…) · options.greeks_history(…) · …
Dealer gamma, livegex(underlying)
Dealer gamma, a past sessiongex(underlying, date) · gex(underlying, at)
Participant flowparticipants(underlying)
CFTC positioningcot(symbol, weeks)
Algo catalogue, record, signalsalgos.list() · algos.track(id) · algos.signal(id)
Orders, positions, fillsexec.orders() · exec.positions() · exec.fills()
Place, close, protectexec.order(…) · exec.close(…) · exec.protect(…)
Stream ticks, book, L3, optionsstream(…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

EndpointNeedsParameters
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.

any language

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.