Skip to main content
Three streams complement the REST API. All frames are JSON text.

Connecting

Browsers cannot set headers on websocket upgrades, so authentication uses a short-lived ticket passed as a query parameter:
1

Mint a ticket

POST /auth/ws-ticket from a session (ticket carries read), or POST /auth/ws-ticket/signed with an HMAC-signed request (ticket inherits the key’s scopes).
2

Connect within 30 seconds

Tickets expire after 30 seconds. Mint one per connection attempt, immediately before connecting. An invalid or expired ticket rejects the upgrade with an HTTP error before the socket opens.

Subscribing

/ws/user needs no subscription: it streams your events as soon as the socket opens. /ws/rfq and /ws/market expect one handshake frame naming the markets to watch, immediately after connecting:
The server replies with one snapshot frame of current state for those markets (open requests on /ws/rfq; the order book, with a seq_num, on /ws/market), then streams incremental events. A malformed handshake gets an error frame and the connection closes.

Event frames

Every event after the snapshot has the same envelope:
The event payload matches the corresponding REST schema: an RFQRequest carries the same shape as a quote request from GET /rfq/request, and an RFQMatch the same terms as GET /rfq/matches. Ignore event_kind values you do not recognize: new kinds may be added without notice.

Reconnecting

Connections carry no resume token. On disconnect:
  1. Mint a fresh ticket (the old one is long expired).
  2. Reconnect and re-handshake. The new snapshot frame replaces any state you were tracking, so nothing is missed by rebuilding from it.
  3. For /ws/user, events published while disconnected are not replayed; on reconnect, reconcile through the REST reads (/rfq/matches, /custody/get-ledger).