Skip to main content
Address fields refer to the wallet the user trades from.
Base URL:
Connect with transports: ["websocket"]. The server accepts the websocket transport only, on both namespaces, so a client left on the Socket.IO default — which opens with HTTP long-polling — is refused. For /user API key signatures, see Developer Authentication.

Namespaces

/

Authentication: Public Public order book and event data.

/user

Authentication: API key HMAC User-specific balances, positions, orders and trades.

Public Client Messages

PingPayload:

Subscribe to Token Order Books

Authentication: Public Subscribe to one or more outcome token IDs. Use the market tokenId1 and tokenId2 values from market data when you want both sides of a binary market. Payload type: OrderbookTokenIds.
Socket.IO example:
On subscribe, the backend joins one order book room per token ID and requests an initial snapshot for each token. Successful snapshots are emitted on orderbook as an OrderBook[]. Live level changes are emitted later on orderbook-price-change. If an initial snapshot cannot be loaded because of a transient backend failure, the server emits orderbook-error with the affected tokenIds. Unknown token IDs may produce no snapshot and no error. Two per-socket limits apply to this message, and both answer with an orderbook-error rather than dropping your message silently:
  • At most 20 orderbook-market-connect messages per 10 seconds. A message over that rate is dropped before it is parsed and answered with reason: "rate_limited", carrying maxMessages and windowMs and an empty tokenIds. Resend it once the window has passed.
  • At most 500 distinct token subscriptions held at once (configurable, and the same number as the per-message cap). A message that would take you past it is rejected in full and answered with reason: "subscription_limit_reached", carrying maxTokenIds and a sample of your token IDs. Token IDs you already hold do not count against it. Send orderbook-market-disconnect for books you no longer need, then resend.

Unsubscribe from Token Order Books

Authentication: Public Stop receiving order book snapshots and deltas for one or more outcome token IDs. Payload type: OrderbookTokenIds.
Socket.IO example:
The backend does not emit a dedicated unsubscribe confirmation event. OrderbookTokenIds:

Public Server Events

PongPayload: AppError: OrderBook: OrderBookLevel: OrderBookPriceChange: OrderBookPriceLevel: OrderBookError: Branch on retryable before reason. retryable: false means resending the same message fails identically — change it rather than retry it. snapshot_unavailable, rate_limited and subscription_limit_reached are retryable; too_many_tokens and invalid_payload are not. Treat an unrecognised reason as transient only when retryable is true. EventOnchainUpdatePublic: EventOnchainUpdateRaw: TickSizeChange: OrderSpeedBumpPending: CryptoPrice: CryptoPriceHistory: CryptoPriceError has two shapes, and they do not carry the same fields: A crypto-price-connect whose payload is invalid — not an array, empty, more than 20 symbols, or a symbol longer than 32 characters — is ignored with no frame at all, as is a symbol that is not on the allowlist. Only the rate breach is answered. GlobalTrade uses the TradeActivity shape, including anonymous and marketDisplayName. event-trade uses the same payload as global-trade, but is emitted only to the room for the trade’s parent event. Send event-connect with that event UUID to receive it. LiveVolume:

User Client Messages

UserConnectPayload: TradingApiKeyAuth:

User Server Events

UserAuthenticated: BalanceUpdate: UserPositionUpdate:

Binding events to your orders

Bind an event to your order by its hash rather than by matching price and size: two orders with the same shape are indistinguishable that way. If you sign your own orders, you can compute the hash locally before you submit, while id is server-minted and only reaches you with the HTTP response — which the first event for that order often precedes. Three gaps make the hash the only reliable link:
  • A maker’s fill produces no user-order event. Only the taker is notified on a match, so as a maker you learn of your fill from user-trade and bind it through maker_orders[].order_hash.
  • A fully filled order produces no terminal user-order event. Its last event is user-trade.
  • Only GTC orders produce user-order events, apart from a REJECTION. The only event naming a FOK or FAK order is user-trade, or a REJECTION. Because a liquidation is now a CANCELLATION rather than a REJECTION, it no longer takes that exception — so do not rely on a frame arriving for every order the platform removes. Reconcile against GET /orders instead.
UserOrderEvent:
An order removed because your balance no longer backs it is now a CANCELLATION, not a REJECTION. It ends CANCELLED and carries cancellation_reason: "insufficient_balance", where it previously ended REJECTED and carried rejection_reason: "insufficient_balance". If you detect liquidations by watching for REJECTION frames, you will stop detecting them. Both shapes can appear while the release is rolling out, so handle each until it completes.
TradeEvent: TradeMakerOrder: RewardClaimUpdate: TransactionUpdate: