Skip to main content
WebSocket delivery is at-least-once during normal operation. On disconnect or reconnect you must rebuild subscriptions and reconcile against REST.

sid lifecycle

sids are connection-local. They are NOT preserved across:
  • Network drops
  • Client-side WebSocket.close() + reopen
  • Server-side restarts
After every reconnect, run a fresh subscribe for everything you need. Old sids from the previous connection are meaningless.

Heartbeat

Send ping every 25 seconds (or whenever your TCP connection feels quiet):
Server responds:
If you don’t get a pong within ~5 seconds, treat it as a dead connection — close and reconnect. ts is the server clock in ms. Use it as a clock-skew probe if you care about latency-sensitive timing on the client.

Reconnect strategy

After a successful reconnect-and-resubscribe, reconcile state from REST — don’t trust the WS to have replayed missed events from before the disconnect.

Channel-specific reconnect / resync

Orderbook resync

token_book frames carry seq on the envelope and prevSeq inside data. Apply book_snapshot + book_delta frames and track the last seq you applied per tokenId (the envelope id). Skip book_update in this flow: it shares its seq with the book_delta that follows it, so counting both would look like a gap. If a delta arrives with data.prevSeq different from your last seq, request a fresh snapshot — without dropping the existing subscription:
Keep one request in flight per token: after a gap every later delta on that token also mismatches, and re-requesting on each one spends the command rate limit. Deltas that arrive before the snapshot are already reflected in it, so dropping them is safe; seq and prevSeq are decimal strings, so compare them as strings. If the snapshot fetch fails the server pushes { "type": "book_snapshot_failed", "data": { "tokenId", "reason", "retryable", "subscriptionActive" } } on the same sid. Back off and retry, or fall back to GET /api/markets/{symbol}/orderbook?outcome=N&depth=100.

Auth on reconnect

Auth is checked at handshake. Issuing a new key doesn’t affect a socket opened with the old one; close + reopen to switch keys. Revoking a key, changing its scopes, suspending the partner, or changing the partner’s associated wallet, kind or per-wallet KYC setting closes every live socket on that key with 4401 api_key_revoked, normally within milliseconds. New handshakes with a revoked key are refused within 60 seconds at most.