Skip to main content

Session Stream

TL;DR/v1/stream is the sole multiplexed socket: place, cancel, and modify orders, and receive order, fill, and tree-append pushes. You authenticate in-band with an op: login frame (not a ?token= query param), then subscribe to the channels you want.
The order operations, orders channel, and fills channel pages document facets of this one session.

Connect and log in

The socket upgrades unauthenticated. Every op except ping is rejected until a successful login. Login must complete within 10 seconds of opening the socket; traffic and pings do not extend that absolute window:
To refresh an expiring token, send another login on the same socket without dropping your subscriptions. The server emits an auth_expired reminder about 60 seconds before expiry. The venue also caps total sockets and concurrent sockets per account. A full venue refuses the HTTP upgrade with 503 plus Retry-After; an over-limit account receives stream error 4290 and remains unauthenticated. Reuse one multiplexed session instead of opening one socket per market or channel. A token refresh must retain the same account identity; attempting to switch accounts on an authenticated socket returns stream error 4030 and requires a new connection. For Node clients, open this URL with the verified WebSocket factory returned by createVerifiedTransport, not a stock WebSocket or an accept-any-certificate setting. That factory gates the upgrade socket against the enclave’s quote-bound, boot-scoped certificate before a login frame can leave.

Subscribe to channels

unsubscribe takes the same channels array. Each server push is tagged with a top-level channel field so you can route it. Every server frame also carries one connection-global monotonic seq. A gap, or close code 1011, means state may have been missed. Reconnect, re-read the orders you track, recover notes from chain, refresh the relevant tree snapshot, and then resume tailing. A server-side fan-out loss closes every active session with 1011, even if your own consumer was fast, so silence must never be read as completeness.

Submit orders

The order ops dispatch to the same intake and verification as POST /orders and the order operations, so the bodies are identical and an order-level trading-key signature is still required on every frame. Each carries a request_id the server echoes in its reply; later state changes arrive on the orders channel.
order.modify is an atomic cancel-and-replace under one matcher lock, the same as PUT /orders/{order_id}.

Heartbeat

Send { "op": "ping" } at least every 30 seconds; the server replies { "op": "pong" }. A session silent for more than 60 seconds is dropped. Send { "op": "logout" } for a clean client-initiated close.

What is not served here

account and settlement are not channels on this socket. Account state is reconstructed client-side from the tree channel (or the /tree/* endpoints) plus your keys, never delivered as a balance (see Account Model); settlement status is read with GET /settlement/status/{batch_id}.