WebSocket API
Overview
How to connect to the WebSocket API, the message format, the topics you can subscribe to, and the rules that keep a connection open.
The WebSocket API streams live market data and the events of your own orders over one connection. You connect once, subscribe to the topics you need, and the server pushes each topic's messages as they happen.
Connect
| Network | URL |
|---|---|
| BNB Mainnet | wss://ws.predict.fun/ws |
| BNB Testnet | Not available yet |
Connections are served only on the /ws path, over TLS.
Send your API key when you connect, in one of two ways:
- The
x-api-keyheader, which is preferred. - The
apiKeyquery parameter, for clients that can't set headers, such as browsers:wss://ws.predict.fun/ws?apiKey=YOUR_API_KEY.
The key is checked once, at the handshake. A handshake that fails gets an HTTP status instead of a connection, such as 401 for an invalid key or 503 while the service is unavailable.
Messages
Every message is a JSON text frame. Field names and values are case-sensitive, and timestamps are milliseconds since the Unix epoch.
You send requests, with a method, a requestId of your choice and the request's params:
{ "method": "subscribe", "requestId": 1, "params": ["predictOrderbook/123"] }The server answers each request with a response (type: "R") that carries the same requestId:
{ "type": "R", "requestId": 1, "success": true }Everything else the server sends is a topic message (type: "M"), with the topic it belongs to and its data:
{ "type": "M", "topic": "predictOrderbook/123", "data": { "marketId": 123, "asks": [[0.62, 1500]], "bids": [[0.61, 2000]] } }The requests are Subscribe, Unsubscribe and Set language. Each subscribe or unsubscribe names one topic.
Errors
A request that fails gets a response with success: false and an error:
{
"type": "R",
"requestId": 1,
"success": false,
"error": { "code": "invalid_topic", "message": "unknown topic: predictOrderbok" }
}error.code | Cause |
|---|---|
invalid_json | The frame isn't a valid request, for example its requestId or params is missing. The response's requestId is -1. |
invalid_topic | The topic is missing or unknown, or one of its parameters is invalid. |
invalid_params | A Set language request has no language code. |
invalid_credentials | The JWT in a wallet events topic is invalid, revoked or expired. |
internal_server_error | Something failed on our side. Try again. |
Topics
| Topic | What it sends | Latest value on subscribe |
|---|---|---|
predictOrderbook/{marketId} | The market's whole order book, each time it changes. | Yes |
predictTopOfBook/{marketId} | The market's best bid and best ask, each time either changes. | Yes |
predictTradingStatus/{marketId} | Changes to the market's tradingStatus. | Yes |
predictMarketStatus/{marketId} | Changes to the market's status, such as resolution. | Yes |
predictMarketChanged/{marketId} | A notice that the market's details changed. | No |
predictCategoryChanged/{categoryId} | A notice that the category's details changed. | No |
predictWalletEvents/{jwt} | The events of your wallet's orders. The topic holds a JWT from the REST API. | No |
For the topics marked Yes, the latest value arrives right after the subscribe response, followed by live updates. It's best effort: when there's nothing to send yet, only updates arrive.
Keep the connection open
- Heartbeats. Every 15 seconds the server sends a
heartbeatmessage. Echo itsdataback before the next one, or the server closes the connection. - Reconnect notices. Before a server shuts down, it sends a reconnect notice on the
systemtopic, then closes the connection aftergraceMs. - Message size. A frame from the client can be at most 8 KiB. A larger one closes the connection.
- Keeping up. Read messages as fast as they arrive. The server disconnects a client that falls too far behind.
| Close code | Why the server closed the connection |
|---|---|
1000 | A heartbeat went unanswered, or a message from the client was over 8 KiB once decompressed. |
1001 | The server is shutting down, after a reconnect notice. The reason is server draining. |
1009 | A frame from the client was over 8 KiB. |
| None | The client fell behind, or the server dropped its connections after a gap in delivery. The server sends no close frame, so browsers report 1006. |
Reconnect after every close you didn't start. Subscriptions don't carry over to a new connection, and messages sent while you were disconnected aren't replayed. After you reconnect, subscribe again and refetch what you track from the REST API. Stay connected shows how.
How-tos
Stream an order book
Show a market's Yes and No order book as it changes.
Follow your orders
Get the events of your wallet's orders as they happen.
Stay connected
Answer heartbeats, and reconnect after a disconnect.
The client example is a complete TypeScript client with heartbeats, reconnection and typed messages.
The AsyncAPI document behind these pages is at /asyncapi/websocket.json. You can use it to generate a client.