Skip to main content
Totalis moves data over four channels. Each covers a different phase of a trade and a different delivery guarantee — pick by what you’re doing, not by protocol preference:
Need the full moment-by-moment map — every event name on every channel, side by side, plus the field names that mean the same thing across them? See the event catalog.
All four authenticate with the same API key.

One trade, three phases

  • Pricing is SSE. Every quote request gets its own stream at GET /v1/quote-requests/{id}/stream; a cashout request gets one at GET /v1/cashout-requests/{id}/stream. The stream exists only while the request is live and closes after a terminal event. Market makers watch the firehose variant, GET /v1/mm/quote-requests/stream.
  • From commit onward, it’s events. The moment you commit, the quote request becomes an RFQ and the SSE stream ends. Everything after — acceptance, confirmation, on-chain execution, settlement — arrives on the WebSocket and as webhooks.
  • State is always readable. The read endpoints return current truth whenever you ask — they’re how you backfill after downtime and reconcile what the push channels told you.

WebSocket or webhooks?

Both deliver post-trade lifecycle events, and for most of the lifecycle they overlap. They differ in the delivery guarantee — and in one case, in coverage:
  • WebSocket pushes to a connected client in real time. If you disconnect, missed events are not redelivered — on reconnect, reconcile with the read endpoints. Choose it for live UIs and trading bots where latency matters.
  • Webhooks POST to your server with at-least-once delivery: HMAC-signed, retried with backoff, dead-lettered, and replayable. Choose them for accounting, notifications, and any system of record.
The two channels are not full parity, but not over cash-out closes: position:bought_back is delivered over WebSocket (to the seller and the winning market maker) as well as by webhook. The gap is the other exit outcome — a winning bid that acquires a position emits nothing to the buyer on either channel, so an acquiring market maker learns of it only by reconciling against the read endpoints. See the event catalog for the full picture.
Serious integrations often run both: the WebSocket for immediacy, webhooks for the durable record.

Typical integrations

Trading bot

  1. Create a quote request — POST /v1/quote-requests.
  2. Watch its SSE stream for best_quote events; store book_seq and the quote id.
  3. Commit when the price is right.
  4. Follow the trade live on the WebSocket rfq:{rfq_id} channel, or durably via the parlay.status_changed webhook.
  5. Record the outcome from the position.settled webhook, or read it from GET /v1/rfqs/{id}.

Read-only dashboard

  1. Pull state with GET /v1/portfolio, GET /v1/rfqs, and GET /v1/pnl.
  2. Subscribe to rfq:{rfq_id} on the WebSocket for live position updates.
  3. On reconnect, reconcile against the read endpoints.

Market maker

  1. Stream quote requests and cashout requests from GET /v1/mm/quote-requests/stream.
  2. Submit quotes as requests arrive.
  3. Listen on the WebSocket mm:quotes:{mm_id} channel for quote:accepted, then confirm before the deadline.
  4. Keep the durable record with an MM webhook endpoint (?owner_kind=mm).
See Market making for the full loop, including cashout pricing.