Skip to main content

Private Channels

Private channels stream account-specific events. They require a private session token for the 20-byte engine account. Issue the token over HTTP first, then use it in the WebSocket connection. Do not send owner wallet signatures or HMAC secrets inside WebSocket messages.

Channels

ChannelPurpose
ordersOrder acknowledgements, amendments, cancels, terminal states
fillsExecution events with fee and liquidity role
balancesCollateral changes, holds, releases, settlement adjustments
positionsPosition changes, realized and unrealized PnL updates
riskMargin, liquidation, and account health updates
withdrawalsWithdrawal request, checkpoint, proof, and execution status

Authentication

Issue a private WebSocket token:

POST /api/v1/ws/token
Content-Type: application/json
Authorization: Bearer <private-read-token>
{
"account": "0x2222222222222222222222222222222222222222",
"ttlMs": 600000,
"clientId": "mm-quote-engine-1",
"scope": "private"
}

Use the returned spws1... token as a bearer credential for the private WebSocket upgrade or subscribe message, according to the endpoint contract for your deployment:

GET /api/v1/ws/private/0x2222222222222222222222222222222222222222
Authorization: Bearer spws1...

The {account} path parameter is the 20-byte engine account. It is not the 32-byte accountIdHex.

Sequence scope

Private streams are sequenced by account. Clients should persist the last processed account sequence and use it during reconnect to avoid double-processing fills or terminal order states.

Delivery model

Private/drop-copy events are delivered ring-first: reads are served from an in-memory, per-account replay buffer (a bounded VecDeque) before falling back to SQL. The buffer is bounded by both a maximum event count and a retention window (max_events / retention_ms), so it covers the most recent events for each account. When a requested range is not fully covered by the buffer - for example after a long disconnect or beyond the retention window - the server transparently falls back to a SQL read to backfill the gap, then resumes from the ring.

The ring optimizes the consumer read path: it removes the database read from event fan-out to connected clients. It does not remove the database write from the projection pipeline. The produce path remains DB-write-first: each event is committed and its identifier is derived from the database sequence first, and only then pushed into the in-memory replay buffer. As a result, sequence numbers and ordering are identical whether an event is served from the ring or from SQL.

Ring-first delivery is in effect for WebSocket private channels. FIX drop-copy shares the same replay buffer.

Security notes

  • Keep delegated credentials scoped and time-limited.
  • Separate read-only stream credentials from trading credentials where possible.
  • Treat private stream disconnects as operational alerts for unattended trading.