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.
ChannelWhat it carriesUse it for
SSE streamsPretrade pricing — live best_quote updates on a quote request or cashout requestWatching prices while you decide whether to commit
WebSocketPosttrade events, live — quote acceptance, confirmation, position created/settledLive UIs and bots that hold a connection
WebhooksPosttrade events, durable — most of the same lifecycle moments as HMAC signed POSTs with retries and replay, plus one moment WebSocket doesn’t carry at all (early cashout buyback — see the event catalog)Server systems of record that must never miss an event
REST readsState on demand — portfolio, parlays, settlement detail, P&L, balancesBackfill, reconciliation, on demand display
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 posttrade 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: early cashout buyback (position.bought_back) is a webhook only event today, with no WebSocket equivalent. A latency sensitive bot that only holds a WebSocket connection won’t learn a position was bought out until it reconciles 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; heartbeat every 30 seconds.
  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.