Skip to main content
The realtime gateway streams orderbook, ticker, trade, and private user events.
  • The token is optional — without it you can still subscribe to public channels.
  • The token is required for the private user channel. Get one from POST /v1/auth/ws-token (single-use, 60s TTL). See Authentication.
Every message — inbound and outbound — is JSON with a type field. Invalid JSON gets { "type": "error", "message": "Invalid JSON" }.

Inbound messages (client → server)

Ping

The server replies { "type": "pong" }. There is no server-initiated heartbeat — send ping yourself periodically.

Subscribe

Public channels require condition_id + chain_id:
The private channel requires only the channel name (events are wallet-scoped):
The server acks:
For the book channel, a book_snapshot is pushed immediately after the ack.

Unsubscribe

Same shape as subscribe; the server acks with type: "unsubscribed".

Channels

Public

Private

The user channel is a single unified stream — filter client-side on event.type. Subscribing to it without a valid token returns:
One market (condition_id, chain_id) yields three public subscriptions: book, ticker, and trades. There is no wildcard subscription — subscribe per market.

Outbound messages (server → client)

book_snapshot

Sent once after subscribing to book, and again on reconnect.
Adopt seq as your sequence anchor. Each book level is { price, remainingSize } as decimal strings.

book_delta_batch

A batch of price-level updates coalesced from a single matcher commit or cancel. Apply all deltas as a group.
Read levels from deltas[], not from the top-level message. Each entry’s size is the new aggregate size at that price — replace the level, or delete it when size is 0. The same (side, price) never appears twice in one batch.

ticker / trade

user events

The private user channel carries several event types — filter on type. Order-lifecycle events carry the full order snapshot (same shape as GET /v1/orders/{hash}):
Fill events (type: "fill") — one per match per side:
Settlement events (type: "settlement_update") — after on-chain settlement:
FAILED settlements may include error_code / error_reason.

error

code is optional.

Applying book deltas

1

Seed from the snapshot

Build bids and asks maps keyed by price from book_snapshot, using { price, remainingSize }. Record seq.
2

Apply each batch atomically

For every entry in book_delta_batch.deltas (in array order): pick the side (BUY → bids, SELL → asks). If size is 0, delete the level; otherwise set the level to size.
3

Detect gaps

Track seq per market. If a batch arrives with seq !== last + 1, you missed an update — resync by re-fetching GET /v1/markets/{id}/book or re-subscribing (which sends a fresh snapshot).
4

Render

Sort bids high→low, asks low→high, slice to the depth you need.

Reconnect

  1. POST /v1/auth/ws-token → fresh token (single-use).
  2. Open wss://api.foresight.now/v1/ws?token=<token>.
  3. Re-subscribe to every channel you need.
  4. For book, the new book_snapshot resets your baseline — drop any deltas received before it.
A slow consumer is dropped if its send buffer backs up past ~1 MiB (close code 1013). Reconnect, re-subscribe, and pull a fresh snapshot.