Skip to main content

Connecting

Open a WebSocket connection to one of the available endpoints:
wss://socket.bayse.markets/ws/v1/markets
wss://socket.bayse.markets/ws/v1/realtime
On a successful connection, the server sends a connected message:
{
  "type": "connected",
  "status": "connected",
  "clientId": "a1b2c3d4-...",
  "message": "Successfully connected to WebSocket server",
  "timestamp": 1700000000000
}
const ws = new WebSocket("wss://socket.bayse.markets/ws/v1/markets");

ws.addEventListener("open", () => {
  console.log("connected");
});

Message format

All messages are JSON. The server may batch multiple JSON objects into a single WebSocket frame separated by newlines (\n). Clients must split on newlines before parsing each line:
ws.addEventListener("message", (event) => {
  for (const line of event.data.split("\n")) {
    if (line.trim()) {
      const msg = JSON.parse(line);
      // handle msg
    }
  }
});

Client messages

Messages sent from the client to the server follow this structure:
{
  "type": "subscribe",
  "channel": "prices",
  "eventId": "EVENT_ID",
  "marketId": "MARKET_ID",
  "marketIds": ["MARKET_ID"],
  "currency": "USD",
  "symbols": ["BTCUSDT"],
  "room": "ROOM_NAME"
}
Only include the fields relevant to the channel you are using. The type field is always required.
FieldTypeDescription
typestringRequired. One of subscribe, unsubscribe, ping.
channelstringSubscription channel (e.g., activity, prices, orderbook, asset_prices).
eventIdstringPrediction event UUID. Required for activity and prices.
marketIdstringMarket UUID. Optional filter for activity.
marketIdsstring[]Market UUIDs (max 10). Required for orderbook.
currencystringUSD or NGN. Optional for orderbook.
symbolsstring[]Asset symbols (e.g., BTCUSDT). Required for asset_prices.
roomstringRoom name. Required for unsubscribe.

Server messages

Messages sent from the server to the client:
{
  "type": "price_update",
  "data": { ... },
  "timestamp": 1700000000000
}
FieldTypeDescription
typestringThe event type (e.g., price_update).
dataobjectEvent payload. Varies by event type.
timestampnumberUnix timestamp (milliseconds).
statusstringPresent on the connected message.
clientIdstringYour assigned client ID.
messagestringHuman-readable text when provided.
roomstringRoom name for subscribe/unsubscribe responses.

Subscribing and unsubscribing

Subscribe to a channel by sending a subscribe message with the required fields:
{ "type": "subscribe", "channel": "prices", "eventId": "EVENT_ID" }
Unsubscribe by sending an unsubscribe message with the room name:
{ "type": "unsubscribe", "room": "prices:EVENT_ID" }
The server confirms with an unsubscribed message:
{
  "type": "unsubscribed",
  "room": "prices:EVENT_ID",
  "message": "Unsubscribed from: prices:EVENT_ID",
  "timestamp": 1700000000000
}

Room naming

Room names are constructed from the channel and subscription parameters:
SubscriptionRoom name
Activity feedactivity:<eventId>
Activity feed (market-specific)activity:<eventId>:<marketId>
Price updatesprices:<eventId>
Orderbook (USD)orderbook:<marketId>
Orderbook (NGN)orderbook:<marketId>:NGN
Asset pricesasset_prices:<SYMBOL>

Keepalive

The server sends WebSocket-level ping frames every ~54 seconds. Most WebSocket libraries handle pong replies automatically. You can also send an application-level ping to verify the connection is alive:
{ "type": "ping" }
The server replies with:
{ "type": "pong", "timestamp": 1700000000000 }
If the server does not receive a pong within 60 seconds, the connection is closed. Ensure your client handles WebSocket ping/pong frames.

Reconnection

Connections can drop due to network issues, server restarts, or idle timeouts. Implement reconnection with exponential backoff:
function connect() {
  const ws = new WebSocket("wss://socket.bayse.markets/ws/v1/markets");
  let attempt = 0;

  ws.addEventListener("open", () => {
    attempt = 0;
    // re-subscribe to channels
  });

  ws.addEventListener("close", () => {
    const delay = Math.min(1000 * 2 ** attempt, 30000);
    attempt++;
    setTimeout(connect, delay);
  });

  return ws;
}

Limits

LimitValueScope
Message rate10 messages/secondPer connection
WebSocket upgrades are rate-limited per IP.