Skip to main content
Public market prices use a separate socket: Market data.

Subscribe

Send one frame after the upgrade:
Response:
A first frame that is not a valid subscribe, or arrives late, closes with INVALID_SUBSCRIPTION. A subscription your key may not use closes with SUBSCRIPTION_DENIED. There is no unsubscribe: close the socket.

Frames

Every server frame is { "channel": ..., "data": ... }.
event_type selects the shape of payload. Ignore event types you do not recognize.

Snapshot

The snapshot is your current state and the cursor it matches. Replace your local state with it, then apply events after that cursor. A class cut short is listed in truncated with the route that pages the rest:
Page that route once from the first page. Balances, positions and maker capital are not snapshot classes: read them over HTTP when you connect, and again on their events.

Apply events

  • Delivery is at least once. Skip an event whose event_id you have seen, or whose cursor.sequence is not above yours.
  • Apply events in sequence order. Sequences skip numbers; a skipped number is not a gap.
  • Save the event’s cursor after you apply it.

Resume

Send your last applied cursor. Resuming needs replay:read.
The stream is the only replay; there is no HTTP event log. The replay window is on Limits.

Heartbeats, drain and reset

  • Keepalive is WebSocket ping and pong, every heartbeat_interval_ms.
  • On drain, open a new connection, resume from your cursor, then close the old one. The server closes it with CONNECTION_DRAIN by deadline.
  • On reset, discard local state and reconnect without a cursor.
Every close carries a code from Errors as its reason. Its retry says what to do: