Websocket

Real-time orderbook, trade, and market updates via WebSocket.

Connection

wss://api.turbinefi.com/api/v1/stream

No authentication is required. The WebSocket endpoint is public.

Connection Lifecycle

  • The server sends a ping every 54 seconds.
  • Clients must respond with a pong within 60 seconds or the connection is closed.
  • On subscribe, you receive a confirmation message followed by the current orderbook snapshot.

Example

const ws = new WebSocket("wss://api.turbinefi.com/api/v1/stream");

ws.onopen = () => {
  console.log("Connected");
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log(msg.type, msg.data);
};

Subscribe

Subscribe to real-time updates for a market. You can optionally filter by outcome.

Request

{
  "type": "subscribe",
  "marketId": "0x1234...abcd"
}

With outcome filter:

{
  "type": "subscribe",
  "marketId": "0x1234...abcd",
  "data": {
    "outcome": 0
  }
}
FieldTypeDescription
typestring"subscribe"
marketIdbytes32Market to subscribe to
data.outcomeuint8Optional. 0 = YES only, 1 = NO only. Omit for all outcomes

Response

You receive a subscription confirmation followed by the initial orderbook snapshot:

{
  "type": "subscribe",
  "marketId": "0x1234...abcd",
  "data": {
    "status": "subscribed"
  }
}

Unsubscribe

Stop receiving updates for a market.

Request

{
  "type": "unsubscribe",
  "marketId": "0x1234...abcd"
}

Response

{
  "type": "unsubscribe",
  "marketId": "0x1234...abcd",
  "data": {
    "status": "unsubscribed"
  }
}

Event Types

All server messages follow this format:

{
  "type": "<event_type>",
  "marketId": "0x...",
  "data": { ... }
}

orderbook

Full orderbook snapshot sent on subscribe and after each trade or order change.

FieldTypeDescription
bidsarrayBuy orders, sorted by price descending
asksarraySell orders, sorted by price ascending
bids[].priceuint64Bid price (6 decimals). 450000 = $0.45
bids[].sizeuint64Total size at this price (6 decimals). 20000000 = 20 shares
asks[].priceuint64Ask price (6 decimals). 550000 = $0.55
asks[].sizeuint64Total size at this price (6 decimals)
lastUpdateuint64Unix timestamp of last update

trade

Sent when a trade is executed.

FieldTypeDescription
priceuint64Trade price (6 decimals). 550000 = $0.55
sizeuint64Trade size (6 decimals). 10000000 = 10 shares
outcomeuint80 = YES, 1 = NO
timestampuint64Unix timestamp
tradeHashstringUnique trade identifier
makeraddressLimit order placer
takeraddressMarket order placer
sideuint8Taker's side: 0 = BUY, 1 = SELL

trade_error

Sent when an on-chain trade settlement fails.

FieldTypeDescription
buyeraddressBuyer's wallet address
selleraddressSeller's wallet address
priceuint64Trade price (6 decimals)
sizeuint64Trade size (6 decimals)
txHashstringFailed transaction hash
errorstringError description

order_cancelled

Sent when an order is cancelled, either by the user or by the system (e.g., during market rebalancing).

FieldTypeDescription
orderHashstringCancelled order hash
marketIdstringMarket identifier
sidestring"buy" or "sell"
traderaddressOrder owner
reasonstringCancellation reason (e.g., "user_cancelled", "market_rebalancing")

quick_market

Broadcast to all connected clients when a quick market is created or resolved.

FieldTypeDescription
data.typestring"new_market" or "resolved"
data.assetstringAsset symbol (e.g., "BTC")
data.marketIdstringMarket identifier
data.quickMarketobjectQuick market details
Quick market events are sent to all connected clients regardless of subscriptions.

Full Example

const ws = new WebSocket("wss://api.turbinefi.com/api/v1/stream");

ws.onopen = () => {
  // Subscribe to a market (YES outcome only)
  ws.send(JSON.stringify({
    type: "subscribe",
    marketId: "0x1234...abcd",
    data: { outcome: 0 }
  }));
};

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

  switch (msg.type) {
    case "subscribe":
      console.log("Subscribed:", msg.data.status);
      break;
    case "orderbook":
      console.log("Bids:", msg.data.bids);
      console.log("Asks:", msg.data.asks);
      break;
    case "trade":
      console.log(`Trade: ${msg.data.size} shares at $${msg.data.price / 1000000}`);
      break;
    case "trade_error":
      console.error("Settlement failed:", msg.data.error);
      break;
    case "order_cancelled":
      console.log("Order cancelled:", msg.data.orderHash, msg.data.reason);
      break;
    case "quick_market":
      console.log("Quick market:", msg.data.type, msg.data.asset);
      break;
  }
};

ws.onclose = () => {
  console.log("Disconnected");
};
import websocket
import json

def on_message(ws, message):
    msg = json.loads(message)
    print(f"{msg['type']}: {msg.get('data')}")

def on_open(ws):
    ws.send(json.dumps({
        "type": "subscribe",
        "marketId": "0x1234...abcd"
    }))

ws = websocket.WebSocketApp(
    "wss://api.turbinefi.com/api/v1/stream",
    on_message=on_message,
    on_open=on_open
)
ws.run_forever()