WebSocket

Connect to the 4rho WebSocket for real-time market data and user notifications.

Connection

wss://api.4rho.com/ws

Authentication (Optional)

Market channels are public. User channels require authentication via one of:

Option 1: Authorization header (JWT)

Authorization: Bearer YOUR_JWT_TOKEN

Option 2: HMAC API key headers

Include the standard HMAC headers in the WebSocket upgrade request:

  • X-4RHO-API-KEY
  • X-4RHO-SIGNATURE
  • X-4RHO-TIMESTAMP
  • X-4RHO-PASSPHRASE

Browser caveat: the new WebSocket(url) constructor cannot set custom headers. SDK consumers running in the browser must either (a) connect to the public market channels only, or (b) use a server-side proxy that performs the upgrade with the Authorization header attached. A ?token=… query-param shortcut is on the roadmap but is not currently supported by the server — passing a token in the URL will be ignored and the connection will subscribe as unauthenticated.

Message Format

All messages are JSON with this envelope:

{
  "channel": "market",
  "type": "trade",
  "market_id": "...",
  "data": { ... },
  "seq": 12345,
  "ts": 1709136000000
}
FieldTypeDescription
channelstringMessage category
typestringSpecific message type
market_idstringMarket ID (market channel only)
dataobjectMessage payload
seqintSequence number
tsintTimestamp (Unix ms)

Subscribing

Send a subscribe message after connecting:

{
  "channel": "subscribe",
  "data": {
    "markets": ["market-id-1", "market-id-2"],
    "user": true
  }
}

Confirmation

{
  "channel": "system",
  "type": "subscribed",
  "data": {
    "channel": "market",
    "market_id": "market-id-1"
  }
}

Unsubscribing

{
  "channel": "unsubscribe",
  "data": {
    "markets": ["market-id-1"],
    "user": false
  }
}

Market Channel Messages

Trade

Emitted when a trade executes in a subscribed market.

{
  "channel": "market",
  "type": "trade",
  "market_id": "...",
  "data": {
    "market_id": "...",
    "trade_id": "...",
    "price": "0.50",
    "amount": "1000000",
    "side": "BUY",
    "outcome_index": 0,
    "timestamp": 1709136000000
  }
}

Book Delta

Emitted when the order book changes (order placed, cancelled, or filled).

{
  "channel": "market",
  "type": "book_delta",
  "market_id": "...",
  "data": {
    "market_id": "...",
    "action": "add",
    "side": "buy",
    "price": "0.49",
    "quantity": "2000000",
    "outcome_index": 0
  }
}
ActionDescription
addNew price level or quantity
removePrice level removed
updateQuantity changed at level

BBO

Emitted when the best bid or offer changes.

{
  "channel": "market",
  "type": "bbo",
  "market_id": "...",
  "data": {
    "market_id": "...",
    "best_bid": "0.49",
    "best_ask": "0.51",
    "bid_size": "5000000",
    "ask_size": "3000000",
    "outcome_index": 0
  }
}

User Channel Messages

Requires authentication. Subscribe with "user": true.

Fill

Emitted when your order is filled (you are either maker or taker).

{
  "channel": "user",
  "type": "fill",
  "data": {
    "trade_id": "...",
    "order_id": "...",
    "order_hash": "0x...",
    "market_id": "...",
    "side": "BUY",
    "role": "maker",
    "price": "0.50",
    "amount": "1000000",
    "outcome_index": 0,
    "timestamp": 1709136000000
  }
}

Order Status

Emitted when your order's status changes.

{
  "channel": "user",
  "type": "order_status",
  "data": {
    "order_id": "...",
    "order_hash": "0x...",
    "market_id": "...",
    "status": "cancelled",
    "side": "BUY",
    "price": "0.50",
    "remaining": "0",
    "filled_amount": "500000",
    "reason": "user_cancelled",
    "timestamp": 1709136000000
  }
}

Ping/Pong

Send pings to keep the connection alive:

{ "channel": "ping" }

Response:

{
  "channel": "system",
  "type": "pong"
}

The server also sends WebSocket-level pings every 45 seconds. Connections that don't respond with a pong within 60 seconds are closed.

Connection Limits

  • Maximum message size: 4 KB
  • Send buffer: 256 messages
  • Slow consumers will have messages dropped (non-blocking delivery)