Skip to main content
Everything on this page was checked against production on 19 September 2026.

One endpoint

A global load balancer routes the connection to the nearest region (Frankfurt or Tokyo). There is no separate host per region and no separate host per stream family.

Authentication

Authenticate during the handshake, with the same API key you use for REST: A handshake without a valid key is refused with HTTP 401 before the connection opens. Browsers cannot set handshake headers, so use the query parameter there and a header everywhere else.
On connect, the server sends:

Heartbeat, and the 180-second cutoff

The server sends a JSON ping every 60 seconds:
Answer each one with {"method": "pong"}. A connection that never answers is closed after about 180 seconds with close code 4000 and the reason timeout. This is measured behaviour: a silent client was cut at 182 seconds, a client that replied stayed open.

Two families of streams on the same socket

Both families are subscribed the same way, {"method": "subscribe", "subscription": {"type": "<name>"}}, but they differ in what a data frame looks like. Check the type/channel key rather than assuming. The optional ?mode=mirror parameter restricts a connection to the live family. It is not required: without it, the same socket serves both, which is what the examples above do.
Three streams described in this section, completed_trades, fills_spot and recent_activity, are refused by the public endpoint today with {"type":"error","message":"Unsupported subscription: ..."}. Use the REST equivalents (completed trades, spot fills) and contact us if you need them pushed.

Managing subscriptions

One socket carries many subscriptions. An unknown name is answered with an error frame and the connection stays open:

Billing and per-plan limits

Ten delivered events count as one credit, pooled with your REST credits. The same numbers are in Rate Limits & Pricing, which is the reference if the two ever disagree.

Reconnecting

  • Reconnect with exponential backoff and jitter; do not reconnect in a tight loop after a 401, the key will not become valid by retrying.
  • Re-send your subscriptions after every reconnect, the server keeps no state for you.
  • There is no replay: a stream resumes at the present moment. For anything you cannot afford to miss, backfill the gap over REST using the timestamps of the last frame you processed.