WebSocket Streaming
Receive indicator values pushed to you as candles close, over a persistent connection.
The streaming service pushes indicator updates over a WebSocket connection. Instead of polling the REST API, you subscribe to indicators and receive values as they are computed.
wss://v2.taapi.io/streaming
Connection flow
- Open a WebSocket connection to
wss://v2.taapi.io/streaming. - Send an auth message with your API key. You must authenticate before subscribing.
- Send subscribe messages for the indicators you want.
- Receive update messages as indicator values are computed.
- Send unsubscribe messages when you no longer need an indicator, or list to see active subscriptions.
Authentication
Send this message immediately after connecting. All subsequent messages are ignored until authentication succeeds.
{ "type": "auth", "token": "Bearer YOUR_API_KEY" }
{ "type": "auth_ok" }
{ "type": "auth_error", "error": "Invalid or inactive token" }
Connections that fail authentication are closed by the server.
Subscribe
After authenticating, send a subscribe message for each indicator you want.
{
"type": "subscribe",
"id": "my-rsi-id",
"exchange": "binance",
"symbol": "BTCUSDT",
"interval": "1m",
"indicator": "rsi",
"params": { "period": 14 }
}
| Field | Required | Description |
|---|---|---|
type | Yes | Must be "subscribe". |
id | Yes | Subscription identifier, e.g. my-rsi-id. It is required and will be included in the update events. |
exchange | Yes | Exchange identifier, e.g. binance. |
symbol | Yes | Trading pair, e.g. BTCUSDT. |
interval | Yes | Candle interval: 1m, 5m, 15m, 1h, 4h, 1d, 1w. |
indicator | Yes | Indicator name, e.g. rsi, ema, macd. |
params | No | Indicator-specific parameters, e.g. { "period": 14 }. |
Receiving updates
After subscribing, the server sends update messages as values are computed.
{
"type": "update",
"subscription": "binance:btcusdt:1m",
"data": {
"binance_btcusdt_1m_my-rsi-id": {
"value": [45.2],
"timestamp": [1782389580]
}
}
}
The subscription key is lowercase and uses the format exchange:symbol:interval. The data object is keyed by a compound string combining exchange, symbol, interval, and the id you provided when subscribing.
Subscribe bulk
Subscribe to many indicators, symbols, and timeframes in one message using a subscribe_bulk message.
{
"type": "subscribe_bulk",
"exchange": "binance",
"symbols": ["BTCUSDT", "ETHUSDT"],
"intervals": ["1m", "5m"],
"indicators": [
{ "id": "my-rsi", "name": "rsi", "params": { "period": 14 } },
{ "id": "my-ema", "name": "ema", "params": { "period": 9 } }
]
}
The server will subscribe to every combination of symbol × interval × indicator. Each indicator entry requires its own id and uses name (not indicator) for the indicator name.
Unsubscribe
To remove a single subscription, send an unsubscribe message with the generated compound ID that was returned when you subscribed. This ID is formed by the server as exchange_symbol_interval_yourId (all lowercase), for example:
- You subscribed with
id: "my-rsi-id"onbinance / BTCUSDT / 1m - The server assigned the compound ID
binance_btcusdt_1m_my-rsi-id - Use that full compound ID to unsubscribe
{
"type": "unsubscribe",
"id": "binance_btcusdt_1m_my-rsi-id"
}
{
"type": "unsubscribed",
"id": "binance_btcusdt_1m_my-rsi-id"
}
You can retrieve the compound IDs for all your active subscriptions at any time by sending a list message (see below).
To remove all active subscriptions at once, send an unsubscribe_all message. No acknowledgement is sent for this variant — confirm with a subsequent list.
{ "type": "unsubscribe_all" }
List subscriptions
{ "type": "list" }
{
"type": "subscriptions",
"data": {
"binance:btcusdt:1m": [
{ "id": "binance_btcusdt_1m_my-rsi-id", "indicator": "rsi", ... }
]
}
}
Pass "unpack": true to receive a flat array instead of the grouped object — useful when you want to iterate subscriptions directly.
{ "type": "list", "unpack": true }
{
"type": "subscriptions",
"data": [
{ "id": "binance_btcusdt_1m_my-rsi-id", "indicator": "rsi",
"exchange": "binance", "symbol": "BTCUSDT", "timeframe": "1m", ... },
{ "id": "binance_ethusdt_5m_my-ema-id", "indicator": "ema",
"exchange": "binance", "symbol": "ETHUSDT", "timeframe": "5m", ... }
]
}
Throttle limits
Error messages
The server sends error messages for invalid subscribe/unsubscribe requests without closing the connection:
{
"type": "error",
"error": "Human-readable description of the problem"
}
Reconnection and heartbeat
WebSocket connections can drop due to network issues or server restarts. Build your client to handle disconnects gracefully:
- Reconnect with exponential backoff. Start with a 1-second delay and double it on each failed attempt, up to a maximum (e.g. 30 seconds). Reset the counter on a successful reconnect.
- Re-authenticate and re-subscribe after reconnecting. The server does not restore subscriptions automatically — you must repeat the
authmessage and allsubscribemessages after each reconnect. - Ping/pong. Send a WebSocket ping frame periodically (every 30 seconds is common) to keep the connection alive through proxies and firewalls. The server will respond with a pong frame.
const WebSocket = require('ws');
let ws;
let delay = 1000;
function connect() {
ws = new WebSocket('wss://v2.taapi.io/streaming');
ws.on('open', () => {
delay = 1000; // reset backoff
ws.send(JSON.stringify({ type: 'auth', token: 'Bearer YOUR_API_KEY' }));
});
ws.on('message', (raw) => {
const msg = JSON.parse(raw);
if (msg.type === 'auth_ok') {
// re-subscribe after connect/reconnect
ws.send(JSON.stringify({
type: 'subscribe', id: 'my-rsi-id',
exchange: 'binance', symbol: 'BTCUSDT',
interval: '1m', indicator: 'rsi',
params: { period: 14 }
}));
}
if (msg.type === 'update') {
console.log(msg.subscription, msg.data);
}
});
ws.on('close', () => {
console.log(`Disconnected. Reconnecting in ${delay}ms…`);
setTimeout(connect, delay);
delay = Math.min(delay * 2, 30000);
});
ws.on('error', (err) => {
console.error('WS error:', err.message);
ws.close();
});
// keepalive ping every 30 s
setInterval(() => { if (ws.readyState === WebSocket.OPEN) ws.ping(); }, 30000);
}
connect();
Health check
GET https://v2.taapi.io/streaming/health