Skip to main content
OCX pushes real-time data over Server-Sent Events (SSE), not raw WebSockets. Connect with any SSE or EventSource client, apply the initial snapshot, then fold in delta/update events. All streams diff server-side and send a comment heartbeat (:heartbeat) roughly every 15s so proxies keep the connection open.
Reconnect discipline. On any disconnect, reconnect and re-apply the fresh snapshot — do not assume you can resume mid-stream. Messages carry a monotonic sequence (id: or eventSeq); if you detect a gap, reconnect and re-snapshot rather than trusting a partial book.

The five streams

Perp order book

GET /perps/book-stream — public depth for one perp/future market.

Perp user stream

GET /perps/stream/events — book + your fills + your positions.

Options board

GET /markets/board/stream — public marks, IV, Greeks per underlying.

Options CLOB stream

GET /options/stream/events — tradable book + tape for one instrument.

Portfolio balances

GET /portfolio/balances/stream — your cross-bucket balance state.
Public streams (book-stream, board/stream) need no credentials. Private streams require a session cookie or API key; their fills, positions, and balances are scoped to the authenticated account.

Envelope & event names

Named-event streams emit event: snapshot on connect then event: delta (or event: update) on change, with a canonical envelope:
In an order-book delta, a level with size: "0" means that price level was removed. An event: error carries { code, message, retryable }.

Perp order book — public

string
required
number
Levels. Default 25, max 100.
number
Emit cadence. Default 100, range 502000.
GET /perps/book-stream — pure market data, no user fields. First snapshot is the full book; then update diffs. Each level is { price, size, total }.
data

Perp user stream — private

string
required
One market per connection.
number
Default 25, max 250.
boolean
number
Default ~500, range 1005000.
GET /perps/stream/eventsauth required. One market per connection, carrying three things: the public order book, your fills, and your positions. Pass marketId. GET /perps/stream/userauth required. Your fills and positions across all markets on one connection (no order book). This is the stream to use for account-wide fill tracking and market making — one connection instead of one per market. Params: openOnly, intervalMs (default ~250).
object
Book levels; deltas send changed levels (size:"0" = removed).
array
Your fills: { side, price, quantity, liquidity, createdAt } where liquidity is maker or taker.
array
Your positions: { side, quantity, entryPrice, realizedPnl, status }. Deltas send position upserts and removedIds.
A fill arrives as a trade plus a position delta. Market makers feed this straight into the next quotes/bulk cycle — skew or shrink quotes as inventory builds. See the Market makers guide.

Options board — public

string
e.g. BTC. Defaults to the primary underlying.
GET /markets/board/stream — ~1 update/sec, data-only messages wrapping { eventType: "OptionsBoardSnapshot", eventSeq, engineTs, payload }. The payload is the full board snapshot: underlyingPrice, underlyingSymbol, expiries[], per-expiry forwards, and options[] rows with strike, expiry, bid, ask, mark, iv, delta plus the volatility-index block.
The board is the reference marks surface — not a tradable book. For a hittable options book, use the options CLOB stream below.

Options CLOB stream — private

string
required
One option instrument.
number
Default 25, max 250.
number
Default ~100, range 502000.
boolean
Add the reference-mark overlay.
GET /options/stream/eventsauth required. Same envelope as the perp user stream: event: snapshot (OptionsStreamSnapshot) then event: delta (OptionsStreamDelta) with monotonic eventSeq. Payload: the instrument’s tradable CLOB order book, the public trade tape ({ side, price, quantity, liquidity }, no counterparty data), and — only when includeReference=true — a reference overlay { markPrice, source, tradable: false }.
The reference overlay is always flagged tradable: false — it is a marks reference, never a hittable price. Route orders against the CLOB book, not the overlay.

Portfolio balances — private

GET /portfolio/balances/streamauth required. event: snapshot ({ type: "snapshot", payload }) on connect, then event: update whenever your unified balances change across the wallet / perps / options / spot buckets. Heartbeat every 15s; event: error on upstream failure.

Consumption checklist

1

Connect and snapshot

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

Fold in deltas

Apply each delta/update; treat a level with size: "0" as removed.
3

Watch the sequence

Track id: / eventSeq. A gap means you missed data.
4

Reconnect on drop or gap

Reconnect and re-snapshot — never resume a book from a partial state.