Skip to main content
OCX pushes real-time data over Server-Sent Events (SSE), not WebSockets. Connect with any SSE client, apply the initial snapshot, then fold in later events. On any disconnect, reconnect and start again from the fresh snapshot — streams do not resume mid-stream.
Browsers can use EventSource with withCredentials: true to send the session cookie. EventSource cannot set headers, so a bot that authenticates with Authorization: Bearer needs an SSE client that supports custom headers (for example a fetch-based reader).

The streams

Futures order book

GET /fut/book-stream — public depth for one futures market.

Futures market stream

GET /fut/stream/events — one market’s book plus your fills and positions in it.

Futures account stream

GET /fut/stream/user — your futures fills and positions across all markets.

Option board

GET /markets/board/stream — public marks, IV, and delta for one underlying.

Portfolio balances

GET /portfolio/balances/stream — your balance and margin summary.
book-stream and board/stream are public. The other three require a session (cookie or Authorization: Bearer) and carry only your own fills, positions, and balances.

Futures order book — public

string
required
number
Levels per side. Default 25, range 1–100.
number
Emit cadence. Default 100, range 50–2000.
GET /fut/book-stream — pure market data. The first event is snapshot; after that an update event is sent whenever the book changes. Every event carries the full depth-limited book, so you can replace your local book on each one. Each event has an SSE id:; a :heartbeat comment is sent after 15 seconds without changes.

Futures market stream — private

string
required
One market per connection.
number
Default 25, max 250.
boolean
Restrict positions to open ones.
number
Default 500, range 100–5000.
GET /fut/stream/events — Session. One market’s order book, your fills, and your positions. Events are snapshot, then delta; an error event carries { code, message, retryable }. Each event’s data is an envelope:
eventType is PerpStreamSnapshot, PerpStreamDelta, or PerpStreamError (legacy names — this is the futures stream).
object
Snapshot: the full book. Delta: only changed levels; a level with size: "0" was removed.
array
Your fills: { id, orderId, marketId, side, price, quantity, liquidity, createdAt }, where liquidity is maker or taker.
array | object
Snapshot: your positions { id, marketId, side, quantity, entryPrice, realizedPnl, status, updatedAt }. Delta: { upserts, removedIds }.
On this stream eventSeq follows the market’s internal event sequence and is not contiguous per connection — do not treat a jump as a gap. Reconnect on disconnect instead.

Futures account stream — private

GET /fut/stream/user — Session. Your fills and positions across all futures markets on one connection, with no order book. This is the stream to use for account-wide fill tracking. Params: openOnly, intervalMs (default 500, range 100–5000). Events are snapshot, delta, and error, with eventType PerpUserStreamSnapshot, PerpUserStreamDelta, and PerpUserStreamError. Here eventSeq increases by exactly one per event, so a jump means you missed data — reconnect. A : heartbeat comment is sent after 5 seconds without events.
A fill arrives as a trade plus a position update. See the Market makers guide for a full consumer.

Option board — public

string
e.g. SPX or NDX. Always pass it.
GET /markets/board/stream — data-only messages (no event: line), each an envelope { eventId, eventType: "OptionsBoardSnapshot", eventSeq, engineTs, sourceTs, payload }. The payload is the full board, the same shape as GET /markets/board. A new snapshot is sent when the board changes — at most about once per second — with : unchanged comments in between.
eventSeq on this stream is shared across all connections and is not contiguous per client. Each message is a full board, so simply replace your local copy.
The board is the reference marks surface — its bid and ask come from the OCX order book. For a single option’s full depth, poll GET /orderbook/{marketId}.

Portfolio balances — private

GET /portfolio/balances/stream — Session. event: snapshot with { type: "snapshot", payload } on connect, then event: update with { type: "update", payload } whenever your balances change. The payload matches GET /portfolio/balances. A :keepalive comment is sent every 15 seconds; event: error carries { message }.

Consumption checklist

1

Connect and snapshot

Open the stream and apply the first snapshot as your full state.
2

Fold in updates

Replace (book stream, board stream) or merge (delta events) as described per stream; treat a level with size: "0" as removed.
3

Watch for silence and gaps

Use the account stream’s contiguous eventSeq and the heartbeat comments to detect a dead or lossy connection.
4

Reconnect and re-snapshot

On any drop or gap, reconnect with backoff and rebuild from the new snapshot.