Skip to content

WebSocket Guide

Real-time market data via WebSocket.

Connection

wss://oracle-ws-{project}.run.app/v1/ws

Subscribing to Channels

After connecting, send JSON messages to subscribe:

{"action": "subscribe", "channel": "book:abc123def456..."}

Available channels:

Channel Events Description
trades:{market_id} Trade Individual fills on a market
book:{market_id} BookUpdate Order book changes with prices
markets MarketUpdate Market status changes (resolution, halt)
user:{pubkey} Trade Trades involving a specific user

Unsubscribe:

{"action": "unsubscribe", "channel": "book:abc123def456..."}

Server acknowledgement:

{"status": "ok", "action": "subscribed", "channel": "book:abc123def456..."}

Event Types

Trade

Emitted on every fill. Sent to trades:{market_id} and user:{maker} / user:{taker} channels.

{
  "type": "trade",
  "market_id": "abc123...",
  "trade": {
    "maker_order_id": 10,
    "taker_order_id": 42,
    "maker": "4xR2kF7b...",
    "taker": "7yQ3mH9a...",
    "quantity": 100,
    "price": 6200,
    "settlement_type": "mint",
    "maker_side": "sell",
    "taker_side": "buy",
    "outcome": "yes",
    "timestamp": 1700000000,
    "taker_fee": 12,
    "maker_rebate": 3
  }
}

BookUpdate

Emitted after every order submission, cancellation, or fill. Contains the full order book snapshot plus live prices.

{
  "type": "book_update",
  "market_id": "abc123...",
  "snapshot": {
    "market_id": "abc123...",
    "yes_bids": [{"price": 6200, "size": 500, "order_count": 3}],
    "yes_asks": [{"price": 6300, "size": 200, "order_count": 1}],
    "no_bids": [{"price": 3700, "size": 200, "order_count": 1}],
    "no_asks": [{"price": 3800, "size": 500, "order_count": 3}],
    "yes_price": 6250,
    "no_price": 3750,
    "best_yes_bid": 6200,
    "best_yes_ask": 6300,
    "best_no_bid": 3700,
    "best_no_ask": 3800,
    "spread": 100,
    "total_volume": 150000,
    "timestamp": 1700000000,
    "sequence": 42
  }
}

Use sequence to detect gaps. If you see a jump, re-fetch via GET /v1/markets/{id}/book.

MarketUpdate

Emitted when a market's status changes (resolved, halted).

{
  "type": "market_update",
  "market_id": "abc123...",
  "market": {
    "market_id": "abc123...",
    "status": "resolved",
    "resolved_outcome": "yes",
    "yes_price": 10000,
    "no_price": 0
  }
}

Backpressure

The server buffers up to 4096 messages per client. If your client falls behind:

{"type": "error", "code": "lagged", "message": "Dropped 50 messages due to slow consumption"}

When you receive a lagged error, re-fetch current state via REST for all subscribed markets.

Keepalive

Send a WebSocket ping frame every 30 seconds to keep the connection alive. The server responds with pong.

Example (JavaScript)

const ws = new WebSocket('wss://oracle-ws.example.com/v1/ws');

ws.onopen = () => {
  // Subscribe to order book updates for a market
  ws.send(JSON.stringify({
    action: 'subscribe',
    channel: `book:${marketId}`
  }));

  // Subscribe to trades
  ws.send(JSON.stringify({
    action: 'subscribe',
    channel: `trades:${marketId}`
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  if (data.type === 'book_update') {
    // Update order book display
    updateOrderBook(data.snapshot);
    // Update price display
    updatePrice(data.snapshot.yes_price, data.snapshot.no_price);
  }

  if (data.type === 'trade') {
    // Add to trade history
    addTrade(data.trade);
  }
};