Cessio Docs
Guides

Subscribe to RFQs

The WebSocket stream, snapshot semantics, and the REST fallback

The stream

import WebSocket from "ws";

const ws = new WebSocket("wss://<host>/maker/stream", {
  headers: { "X-API-Key": process.env.CESSIO_API_KEY },
});

The key rides the X-API-Key upgrade header. Browser-native WebSocket cannot set upgrade headers and therefore cannot authenticate this maker stream; use a Node client such as ws. A missing or unknown key closes the socket with code 4401 before you receive anything.

Every frame is JSON {type, payload} — the full catalog is on WS Events.

Snapshot: reconnect IS resync

On connect the server immediately replays the current state:

  1. rfq.created for every active RFQ you are invited to;
  2. quote.created + quote.status for each of your active quotes.

Then live events follow. This means you never need a separate bootstrap call and never need to persist state across reconnects — drop your local state on disconnect and rebuild it from the snapshot:

ws.on("close", () => {
  tracked.clear();               // stale by definition
  setTimeout(connect, 1000);     // snapshot rebuilds everything
});

If the server itself loses state it sends resync {} — treat it exactly like a disconnect: close, reconnect, consume the fresh snapshot.

REST fallback for simple bots

The socket is not just a feed — it is also presence: the desk only offers a taker your hint while your /maker/stream socket is open, so a bot with no open socket is never invited and /rfq/incoming stays empty forever, no error, nothing to catch. Keep the socket connected even if you drive everything off REST; then, if reacting to events is inconvenient, poll instead of parsing frames:

curl -H "X-API-Key: $API_KEY" $API_URL/rfq/incoming

It returns the same RFQs as the snapshot, each with myQuote — your active quote or null. The honest trade-offs: polling latency eats into the RFQ deadline, and you do not see quote statuses or settlement progress (trade.step, trade.settled) — you would have to infer outcomes from GET /maker/trades and GET /wallet/holdings. The WebSocket is the canonical path.

On this page