🔍

The streaming service pushes indicator updates over a WebSocket connection. Instead of polling the REST API, you subscribe to indicators and receive values the moment each candle closes (or on every tick, depending on your configuration).

WebSocket URL
wss://v2.taapi.io/streaming

Connection flow

  1. Open a WebSocket connection to wss://v2.taapi.io/streaming.
  2. Send an auth message with your API key. You must authenticate before subscribing.
  3. Send subscribe messages for the indicators you want.
  4. Receive update messages as indicator values are computed.
  5. 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.

Send
{ "type": "auth", "token": "Bearer YOUR_API_KEY" }
Receive — success
{ "type": "auth_ok" }
Receive — failure
{ "type": "auth_error", "error": "Invalid or missing API key." }

Connections that fail authentication are closed by the server.

Subscribe

After authenticating, send a subscribe message for each indicator you want.

Subscribe — single indicator
{
  "type":       "subscribe",
  "exchange":   "binance",
  "symbol":     "BTCUSDT",
  "interval":   "1m",
  "indicator":  "rsi",
  "params":     { "period": 14 },
  "candleClose": true
}
FieldRequiredDescription
typeYesMust be "subscribe".
exchangeYesExchange identifier, e.g. binance.
symbolYesTrading pair, e.g. BTCUSDT.
intervalYesCandle interval: 1m, 5m, 15m, 1h, 4h, 1d, 1w.
indicatorYesIndicator name, e.g. rsi, ema, macd.
paramsNoIndicator-specific parameters, e.g. { "period": 14 }.
candleCloseNoWhen true, only send updates when a candle closes (not on every tick). Default: false.

Receiving updates

After subscribing, the server sends update messages as values are computed.

Receive — update
{
  "type":         "update",
  "subscription": "BINANCE:BTC/USDT:1m",
  "data":         { "rsi": 45.2 }
}

Note: the subscription key uses uppercase exchange and symbol. This is intentional — the format is EXCHANGE:SYMBOL:INTERVAL in uppercase regardless of how you sent the subscribe message.

Subscribe bulk

Subscribe to many indicators, symbols, and timeframes in one message using a subscribe_bulk message. This mirrors the structure of POST /bulk.

subscribe_bulk
{
  "type": "subscribe_bulk",
  "constructs": [
    {
      "exchange":   "binance",
      "symbol":     "BTCUSDT",
      "interval":   "1m",
      "indicators": [
        { "indicator": "rsi", "params": { "period": 14 } },
        { "indicator": "ema", "params": { "period": 9  } }
      ]
    },
    {
      "exchange":   "binance",
      "symbol":     "ETHUSDT",
      "interval":   "5m",
      "indicators": [
        { "indicator": "rsi", "params": { "period": 14 } }
      ]
    }
  ]
}
TODO(human): Verify the exact subscribe_bulk schema from the live WebSocket service, including whether candleClose applies per-construct.

Unsubscribe

Send
{
  "type":      "unsubscribe",
  "exchange":  "binance",
  "symbol":    "BTCUSDT",
  "interval":  "1m",
  "indicator": "rsi",
  "params":    {}
}

List subscriptions

Send
{ "type": "list" }
Receive
{ "type": "subscriptions", "data": [...] }

Throttle limits

TODO(human): Document per-plan subscription limits and per-connection throttle rules for the streaming service.

Error messages

The server sends error messages for invalid subscribe/unsubscribe requests without closing the connection:

Error message format
{
  "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:

Node.js — reconnect example
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', exchange: 'binance',
        symbol: 'BTCUSDT', interval: '1m',
        indicator: 'rsi', params: { period: 14 },
        candleClose: true,
      }));
    }
    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

HTTP health endpoint
GET https://v2.taapi.io/streaming/health