DOCS
WebSocket stream
A persistent WebSocket delivers every tick the moment it prints. Subscribe, unsubscribe, and reconnect with confidence.
Streaming is a single long-lived WebSocket connection. Open it once, subscribe to the symbols you care about, and ticks arrive as compact JSON frames. The SDKs wrap all of this — heartbeats, backpressure and reconnection — behind a simple iterator.
Connect & subscribe
from tickstream import Stream
stream = Stream("sk_live_…")
for tick in stream.subscribe("ES", "NQ", "CL"):
print(tick.symbol, tick.price, tick.size, tick.side)import { Stream } from "@tickstream/client";
const stream = new Stream("sk_live_…");
for await (const t of stream.subscribe("ES", "NQ"))
console.log(t.symbol, t.price, t.size, t.side);# connect, then send a subscribe frame
wss://stream.tick-stream.xyz/v1?key=sk_live_…
{ "op": "subscribe", "channel": "ticks", "symbols": ["ES", "NQ"] } Subscribe frame
On a raw connection, send a JSON control frame after the socket opens:
| Field | Type | Description |
|---|---|---|
op | string | subscribe or unsubscribe. |
channel | string | ticks, book (L2) or options. |
symbols | string[] | One or more symbols, e.g. ["ES","NQ"]. |
The tick message
Every trade prints a tick frame:
{
"type": "tick",
"symbol": "ES",
"price": 5283.25,
"size": 3,
"side": "buy",
"exch": "CME",
"ts": 1749556800
} | Field | Type | Description |
|---|---|---|
symbol | string | The instrument, e.g. ES. |
price | number | Trade price. |
size | number | Contracts traded. |
side | string | Aggressor side: buy or sell. |
exch | string | Originating exchange (always CME today). |
ts | integer | Exchange timestamp in Unix seconds. |
Heartbeats & reconnection
The server sends a {"type":"ping"} every 15 seconds; reply with {"op":"pong"}
(the SDKs do this for you). If the connection drops, reconnect and re-send your subscribe frame —
there's no penalty for reconnecting, and the SDKs resubscribe automatically.
Need depth instead of trades? Subscribe to the Level 2 book channel. Need to seed history before going live? Use the REST backfill.