WebSocket Overview
Spot WebSocket provides real-time pushes for market quotes, order book, K-lines, trade records, and private channels for order and balance updates.
Connection Endpoints
| Type | Endpoint |
|---|---|
| Public channel | ws://<host>:9004/ws |
| Private channel | ws://<host>:9004/ws (send auth after connection) |
Client Request Format
All client requests use the unified {op, args} structure.
Subscribe
{
"op": "subscribe",
"args": ["ticker@BTC_USDT", "depth@BTC_USDT,20"]
}
Unsubscribe
{
"op": "unsubscribe",
"args": ["ticker@BTC_USDT"]
}
Authentication (Private Channels)
Login uses the same HmacSHA256 signing mechanism as the REST API. For details, see Common Module · WebSocket Interface.
Heartbeat
{ "op": "ping" }
Server Response Format
Push Message Format
All push messages use the following format:
{
"ch": "<channel>",
"d": { ... }
}
| Field | Description |
|---|---|
ch | Channel name |
d | Data payload |
Channel Summary
| Channel Type | Format | Example | Access |
|---|---|---|---|
| Ticker | ticker@{symbol} | ticker@BTC_USDT | Public |
| Order book snapshot | depth@{symbol},{level} | depth@BTC_USDT,20 | Public |
| Order book delta | depth_update@{symbol} | depth_update@BTC_USDT | Public |
| K-line | kline@{symbol},{interval} | kline@BTC_USDT,1m | Public |
| Trade | trade@{symbol} | trade@BTC_USDT | Public |
| Mark price (3s) | {symbol}@markPrice | BTC_USDT@markPrice | Public |
| Mark price (1s) | {symbol}@markPrice@1s | BTC_USDT@markPrice@1s | Public |
| Order | order | order | Private |
| Balance | balance | balance | Private |
Error Messages
| Error Message | Description |
|---|---|
invalid message format | Invalid message format |
invalid channel format | Invalid channel format |
unknown operation | Unknown operation |
authentication required | Authentication required |
invalid token | Invalid token |
max subscriptions reached | Subscription limit reached |
Quick Start Example
const ws = new WebSocket('ws://host:9004/ws');
ws.onopen = () => {
ws.send(JSON.stringify({
op: 'subscribe',
args: ['ticker@BTC_USDT', 'depth@BTC_USDT,20']
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.ch) {
console.log('Channel:', msg.ch, 'Data:', msg.d);
} else if (msg.op) {
console.log('Response:', msg);
}
};
// Heartbeat, recommended every 30 seconds
setInterval(() => ws.send(JSON.stringify({ op: 'ping' })), 30000);