Prediction Market — Orderbook WebSocket Push API (Overview)
1. Overview
1.1 Business Description
The Prediction service pulls real-time orderbook (bid/ask) data from upstream market makers (Predict.fun) and broadcasts it via the Binance SApi WebSocket channel to all subscribers. Use cases include:
- Client display of top-N bid/ask depth
- Trading terminals computing best execution price in real time
- Third-party market making / arbitrage strategies
- Data analytics platform feeds
1.2 Channel Characteristics
| Item | Description |
|---|---|
| Protocol | WebSocket (WSS) |
| Gateway | Binance SApi WSS |
| Routing mode | Broadcast by topic (any connection subscribed to the topic receives it; NOT routed by userId) |
| Delivery semantics | at-most-once |
| Ordering | No strict ordering is guaranteed for the same marketId; use the updateTimestampMs field for ordering |
| Offline messages | Not cached — fetch the latest snapshot via REST API after reconnect |
| Latency | Delivered within < 200 ms after upstream event triggers (excluding network) |
| Per-message size | < 4 KB (typical markets ~0.5–2 KB) |
1.3 Business Constraints
| Constraint | Description |
|---|---|
| Active markets only | Only continuously updating active markets are pushed; resolved / closed markets are not pushed |
| Upstream dependency | Quotes come from Predict.fun; if upstream disconnects, this channel pauses (no empty data is pushed) |
| Price / Size precision | price ∈ [0, 1] (2–6 decimals), size typically integer or with up to 6 decimals |
2. WebSocket Connection
The basic connection specification fully follows Binance CMS General Info. This section only lists orderbook-specific examples.
2.1 Connection URL Examples
Subscribe to a single market's orderbook (dynamic topic):
wss://api.binance.com/sapi/wss?random={random}&topic=web3_prediction_orderbook_8859231&recvWindow=30000×tamp={timestamp}&signature={signature}
Subscribe to the aggregated topic (one stream covers all markets):
wss://api.binance.com/sapi/wss?random={random}&topic=web3_prediction_orderbook_data&recvWindow=30000×tamp={timestamp}&signature={signature}
Subscribe to multiple markets (separated by |):
?topic=web3_prediction_orderbook_8859231|web3_prediction_orderbook_8859232
2.2 Authentication & Signature
Identical to user event push (refer to the auth section in Binance CMS General Info):
- Header:
X-MBX-APIKEY: <api_key> - Signature: HMAC SHA256(query string, secret_key)
- query string sorted alphabetically by parameter name
2.3 Subscribe / Heartbeat / Rate Limit
Fully follow CMS spec, not duplicated here:
- Client sends PING every 30 seconds
- Per-connection rate limit: 5 messages/second
- Single connection valid for 24h then must reconnect
3. Push Message Structure
3.1 Envelope
Each orderbook push is delivered by the SApi gateway. The business payload is a JSON string inside the data field:
{
"type": "TOPIC",
"topic": "web3_prediction_orderbook_8859231",
"data": "{\"msgType\":\"orderbook\",\"marketId\":8859231,\"updateTimestampMs\":1717420800123,\"asks\":[[\"0.32\",\"500\"],[\"0.33\",\"1200\"]],\"bids\":[[\"0.31\",\"800\"],[\"0.30\",\"2000\"]]}"
}
⚠️ The
datafield is a stringified JSON. Requires a secondJSON.parse.
3.2 Full Business Payload
{
"msgType": "orderbook",
"marketId": 8859231,
"updateTimestampMs": 1717420800123,
"asks": [
["0.32", "500"],
["0.33", "1200"],
["0.34", "300"]
],
"bids": [
["0.31", "800"],
["0.30", "2000"],
["0.28", "1500"]
]
}
3.3 Field Definitions
| Field | Type | Required | Description |
|---|---|---|---|
msgType | string | ✅ | Fixed value "orderbook", used by clients to dispatch message types |
marketId | number (long) | ✅ | Binance internal market ID (mapped from upstream vendor ID), aligned with REST API |
updateTimestampMs | number (long) | ✅ | Quote update millisecond UTC timestamp; use this for out-of-order detection |
asks | array | ✅ | List of ask levels, sorted by price ascending; empty array means no asks |
bids | array | ✅ | List of bid levels, sorted by price descending; empty array means no bids |
3.4 Level Data Structure (asks / bids)
Each level is a 2-element array of stringified numbers:
[<price>, <size>]
| Index | Field | Type | Description |
|---|---|---|---|
[0] | price | string | Price ∈ (0, 1), in outcome share/USDT ratio, e.g. "0.32" means 0.32 USDT/share |
[1] | size | string | Quantity (outcome shares), may include decimals, e.g. "500" / "500.5" |
Notes
- Numbers are transmitted as strings to avoid JS floating-point precision loss. Parse with
BigDecimal/BigNumberbefore use. size = 0does not appear: upstream filters empty levels; size is always > 0.- Depth: typically top N levels (the value depends on upstream policy, generally ≤ 50).
4. Topic List
Prediction orderbook push provides two independent topic modes. Choose based on your use case (or subscribe to both).
4.1 Dynamic Topic (per-market subscription)
web3_prediction_orderbook_{marketId}
| Item | Description |
|---|---|
| Naming rule | Prefix web3_prediction_orderbook_ + market internal ID |
| Example | web3_prediction_orderbook_8859231 |
| Use case | Only care about specific markets (e.g., orderbook component, single-market arbitrage) |
| Pros | Minimum traffic, each market subscribed independently |
| Cons | When listening to many markets, you must subscribe to many topics (mind the 5 msg/s limit) |
4.2 Aggregated Topic (single stream for all markets)
web3_prediction_orderbook_data
| Item | Description |
|---|---|
| Naming rule | Fixed string |
| Use case | Data collection / quote aggregation / cross-market analytics |
| Pros | Subscribe to one topic to receive all market quotes |
| Cons | High traffic, client must filter by marketId field |
4.3 Selection Guide
| Scenario | Recommended Topic |
|---|---|
| App / Web viewing a single market detail page | Dynamic topic (sub/unsub on page enter/leave) |
| Trading terminal watching ≤ 10 markets | Dynamic topic (concatenate ≤ 10 topics in one subscribe) |
| Data collection / cross-market strategy / quote warehouse | Aggregated topic |
| Hybrid (homepage aggregation + detail page depth) | Subscribe to both — aggregated for homepage, dynamic for detail page |
4.4 Note on Subscribing to Both
If a client subscribes to both dynamic and aggregated topics, the same quote will be pushed twice (once on each topic). Use
marketId + updateTimestampMsfor idempotency to avoid double UI refresh.
5. Push Frequency & Recommendations
5.1 Push Frequency
| Item | Value |
|---|---|
| Per-market update peak | ~10 messages/sec (when upstream pushes full depth on active markets) |
| Per-market update average | ~1-3 messages/sec |
| Aggregated peak (cross-market) | hundreds of messages/sec (peak times when all markets stack up) |
5.2 Client Processing Recommendations
| Item | Recommendation |
|---|---|
| Throttling / debouncing | Debounce UI rendering at 100ms to avoid blocking the rendering thread |
| Out-of-order detection | Must compare updateTimestampMs and discard messages older than the current snapshot |
| Reconnect compensation | After reconnect, first fetch a snapshot via REST API, then apply WSS deltas (CMS does not cache offline messages) |
| Price / size parsing | Use BigDecimal / BigNumber.js to parse, avoid precision loss |
| Empty market filtering | Both asks and bids empty means no orders (paused / about-to-resolve markets); decide whether to render |
5.3 Rate Limit Protection
If subscribing to N dynamic topics at once:
- Use a single SUBSCRIBE command concatenating all topics (separated by |) to avoid hitting 5 msg/s
- When switching many topics, use UNSUBSCRIBE to release unrelated markets and control bandwidth
- Use ONE WSS connection for all prediction business (user events + orderbook); do NOT open separate connections per topic category