Skip to main content
Every server → client push uses the same envelope:
Use sid to route inside your client; use id to identify which specific subscribed entity matched.

user_orders (/ws/user, no id) ✅ live


user_fills (/ws/user, no id) ✅ live


vault_positions (/ws/user, ids = vault address[]) ✅ live

vault_position_balance_changed.reason is the chain-event tag carried through from Erc1155MirrorService. Known values: "OUTF" (output filled — trade-side credit), "INFL" (inflow from a non-trade source), "SPLT" (split), "MERG" (merged), "REDM" (redeemed), "XFER" (direct ERC-1155 transfer between vaults). The list is open- ended; treat unknown tags as a generic balance change, don’t drop them. Required scope: portfolio:read. Subscription must include at least one vault id, and the API key’s associated_vault row must cover each requested vault — vaults outside the grant come back under rejected[] with forbidden.

token_trade_matches (/ws/market, id = tokenId) ✅ live

Fires the moment the matcher prints a trade — fastest tape feed, arrives several seconds before the chain settlement. tradeId is the matcher-assigned id; pair it with the tradeId echoed on trade_settled to correlate matcher output to chain settlement.
No backfill on subscribe — query GET /api/markets/{symbol}/trades for history.

token_trade_settlements (/ws/market, id = tokenId) ✅ live

Fires when chain-watcher indexes the on-chain OrderFilled event for the matched trade. Use this for accounting-grade trade confirmations. orderHash lets you tie this back to the order/matched trade in your own ledger.

token_ohlc (/ws/market, id = tokenId) ✅ live

5-second candles emitted by the matcher whenever a trade prints inside the active window. isClosed: false while the bar is still accumulating; isClosed: true is the final tick of the bar. For history: GET /api/markets/{symbol}/ohlc?interval=s5.

token_book (/ws/market, id = tokenId) ✅ live

book_update is the raw full-depth replacement; book_delta is the computed diff. Most integrators want book_delta; book_update is there for clients that prefer to replay state wholesale. Live book_update is dropped if an upstream frame is missing seq / prevSeq — the gateway never emits a divergent delta. seq is monotonically increasing. After subscribe the server pushes exactly one book_snapshot (depth 100), then book_update / book_delta events where delta.prevSeq == previously_seen_seq. On a sequence gap or unexpected silence, issue get_book_snapshot to refresh without unsubscribing. See Reconnect — orderbook resync.

condition_lifecycle (/ws/market, id = conditionId) ⚠️ pending

Subscription is accepted today; most events not yet emitted by the upstream producer.

market_lifecycle (/ws/market, id = market symbol) ✅ live

Market-scoped counterpart of condition_lifecycle: keyed by the app symbol (lower-cased) rather than the on-chain conditionId, so one subscription per market page carries status, dispute, resolution and — on a crypto window — the frozen open.
Null fields are omitted rather than sent as null — treat every optional key above as “may be absent”. Frames are a low-latency hint; re-fetch GET /api/markets/{slug} for the authoritative state.

crypto_price_tick (/ws/market, id = instrumentId) ✅ live

The price of the coin (BTC-USD), not of a market. Keyed by instrument, so every crypto market on that asset shares one feed. price is an unscaled integer as a decimal string — render as price / 10 ** decimals, never Number(price) (18 decimals overflows Number.MAX_SAFE_INTEGER).
src distinguishes the two producers: "datastreams" (live spot, ~1/s, drives short Up/Down windows) and "candlestick" (one-minute candle close, ~1/min, drives long-dated markets). Plot points at their own at, de-duplicate on it, and expect silence when no producer is active for the instrument. No backfill on subscribe — seed the curve from GET /api/markets/{symbol}/crypto-price-history. Full guide: Crypto price feeds.

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