Skip to main content
Every server-to-client push uses the same canonical envelope:
{
  "type": "<event_type>",
  "sid": 12,
  "channel": "token_trades",
  "id": "60550363974013526...",
  "data": { ... }
}
FieldMeaning
typeConcrete event type (e.g. trade, book_snapshot, platform_status)
sidConnection-local subscription id you got from the subscribed response
channelOne of the channel names from the catalog
idThe token / condition / system id that matched (omitted on user_activity since the channel is wallet-scoped)
dataEvent-specific payload (see below)
Use sid to route inside your client; use id to identify which specific subscribed entity the event belongs to.

Event catalog

user_activity (/ws/user, no id)

typedata
order_placedexchange payload verbatim
order_cancelledexchange payload verbatim
trade_matchedoff-chain match — exchange payload + recipient-side side. Trade is in DB but not yet on-chain confirmed; do NOT treat as a balance commit.
trade_fillon-chain settlement confirmed — { side: 'maker' | 'taker', orderHash, makerVault, takerVault, makerAssetId, takerAssetId, makerAmount, takerAmount, fee, blockNumber, txHash }. After this, /api/me/balances reflects the trade.
trade_failedsettlement-leg revert — { orderId, reason, reasonText, txHash }. Locked balance refunded; treat as never settled.
vault.deploy_confirmedauto-deploy job mined — { vaultAddress, txHash, blockNumber }
vault.deposit_confirmedchain.deposit indexed — { vaultAddress, token, amount, ledgerAfter, txHash }
user_paused{ user, untilBlock, txHash, blockNumber } (minimum)
user_unpaused{ user, txHash, blockNumber } (minimum)

vault_activity (/ws/user, ids = vault address[])

Same shape as user_activity but keyed by vault address, not authenticated wallet. Use when a single API key needs to watch many vaults (multi_wallet partners with N sub-accounts, custodial brokers managing many end-user vaults). Subscription must include at least one vault id. Required scope: portfolio:read.
typedata
trade_fillSame as user_activity → trade_fill; id is the lower-cased vault address

all_trades (/ws/market, no id) — firehose

Public chain-confirmed trade firehose across every market. Same payload as token_trades → trade, emitted regardless of token. Filter client-side by data.tokenId / data.marketSymbol.

all_books (/ws/market, no id) — firehose

Public order-book delta firehose across every token. Use sparingly — book deltas are the noisiest WS surface; subscribe to token_book for specific markets where possible.

token_trades (/ws/market, id = tokenId)

typedata
trade{ tokenId, price, qty, side, ts, tradeId?, txHash?, blockNumber? }
Example:
{
  "type": "trade",
  "sid": 12,
  "channel": "token_trades",
  "id": "12345...",
  "data": {
    "tokenId": "12345...",
    "price": "0.52",
    "qty": "30",
    "side": "buy",
    "ts": 1776949200000,
    "tradeId": "t-987",
    "txHash": "0x...",
    "blockNumber": 1234567
  }
}

token_book (/ws/market, id = tokenId)

typedata
book_snapshot{ tokenId, bids, asks, seq, ts }
book_delta{ tokenId, seq, prevSeq, changes, ts }
seq is monotonically increasing. After subscribe, server pushes one book_snapshot immediately, then book_delta events with prevSeq == previous_seq. If your client sees a gap (delta.prevSeq != last_seen_seq), unsubscribe and resubscribe to force a fresh snapshot. See Reconnect.

condition_status (/ws/market, id = conditionId)

typedata
market_paused{ conditionId, txHash?, blockNumber?, ts }
market_unpaused{ conditionId, txHash?, blockNumber?, ts }
market_resolved{ conditionId, resolution, payouts?, txHash?, blockNumber?, ts }
market_status{ conditionId, status, reason?, ts }

system (/ws/market, id = "platform_status")

typedata
platform_statuspassthrough payload from the platform-status producer
Example:
{
  "type": "platform_status",
  "sid": 15,
  "channel": "system",
  "id": "platform_status",
  "data": {
    "frozen": true,
    "reason": "scheduled-maintenance",
    "since": "2026-04-23T18:00:00Z",
    "etaUnfreeze": "2026-04-23T18:30:00Z"
  }
}

Where the upstream gaps are today

The protocol contract above is the target. As of the current dev build:
  • ✅ Implementable now: user_activity (orders, trades, account-control), token_trades, system
  • ⚠️ Indexed on-chain but not yet routed to the WebSocket gateway: user_paused / user_unpaused
  • ⚠️ Public producers still symbol-based — token_trades and token_book will resolve to native ids in the next iteration
  • ⚠️ Authoritative orderbook snapshot source for token_book is still in flight
The client contract is stable; new event types will land on these existing channels without protocol changes.