tastytradeDeveloper Docs
Legacy ↗

Stream account updates

The account streamer is a one-directional WebSocket that pushes notifications whenever your account data changes — orders, balances, and positions, plus public watchlists and quote-alert triggers. Instead of polling REST endpoints to learn that an order went from Routed to Filled, you receive a push message as the status changes.

This guide walks through opening the socket, subscribing, heartbeating, and handling inbound notifications. For background on how this relates to the DXLink market-data streamer, see /docs/concepts/streaming.

Before you start

You need a valid tastytrade OAuth access token. Every message you send over the socket includes an auth-token — the same value you send in the Authorization header for REST calls. Access tokens last 15 minutes, so include a currently valid auth-token in every message; when your token expires, obtain a new one, and reconnect if the server drops your session. See /docs/get-started for the full token flow, including the required User-Agent: product/version header on the REST call that mints the token.

Pick the host that matches your environment:

EnvironmentWebSocket host
Sandboxwss://streamer.cert.tastyworks.com
Productionwss://streamer.tastyworks.com

These pair with the REST hosts https://api.cert.tastyworks.com (sandbox) and https://api.tastyworks.com (production).

1. Open the WebSocket connection

Open a connection to the host above using your WebSocket client of choice, then wait for the open event before sending anything.

const WebSocket = require('ws')

const host = 'wss://streamer.cert.tastyworks.com'
const websocket = new WebSocket(host)

websocket.addEventListener('open', () => {
  // Send the connect message, then schedule heartbeats
})

websocket.addEventListener('message', (messageEvent) => {
  // Parse and handle inbound notifications
})

Order matters. If you heartbeat before you connect, you may get a not implemented error — only start heartbeats after a successful connect.

2. Send the connect message

A connect message subscribes you to account updates for whichever account numbers you provide. Each message carries an action, a value, and your auth-token. The request-id is optional and is echoed back in the response so you can correlate messages.

{
  "action": "connect",
  "value": [ "5WT00000", "5WT00001" ],
  "auth-token": "<access token>",
  "request-id": 2
}

The server replies with a session id:

{
  "status": "ok",
  "action": "connect",
  "web-socket-session-id": "5b6e2799",
  "value": [ "5WT00000", "5WT00001" ],
  "request-id": 2
}

Other available actions are heartbeat, public-watchlists-subscribe, and quote-alerts-subscribe. Quote alerts are scoped to the user, not an individual account, and their value is left blank.

3. Send periodic heartbeats

Once connected, send a heartbeat on a 2s–1m interval. This keeps the socket open and lets you detect connection drops. The value is blank for heartbeats.

{
  "action": "heartbeat",
  "auth-token": "<access token>",
  "request-id": 1
}

The server acknowledges each one:

{
  "status": "ok",
  "action": "heartbeat",
  "web-socket-session-id": "5b6e2799",
  "request-id": 1
}

If you stop heartbeating, the server may drop the connection. Reconnect with backoff on any drop — see /docs/guides/rate-limits-and-backoff.

4. Handle inbound notifications

Notifications use the same JSON object representations as the REST API and always contain the full object — never a partial or differential update. Each message carries a type (the class of data), a data payload, and a timestamp. Note the dasherized JSON keys (account-number, ext-client-order-id), consistent with the rest of the API.

For example, an order status change arrives as a type: Order notification:

{
  "type": "Order",
  "data": {
    "id": "1",
    "account-number": "5WT00000",
    "time-in-force": "Day",
    "order-type": "Market",
    "size": "100",
    "underlying-symbol": "AAPL",
    "underlying-instrument-type": "Equity",
    "status": "Live",
    "cancellable": true,
    "editable": true,
    "edited": false,
    "legs": [
      {
        "instrument-type": "Equity",
        "symbol": "AAPL",
        "quantity": "100",
        "remaining-quantity": "100",
        "action": "Buy to Open",
        "fills": []
      }
    ]
  },
  "timestamp": 1688595114405
}

As the order advances (for example to Filled), you receive a new notification with the full updated object — no re-fetch required.

Notes

  • The account streamer reports order state; it does not place orders. Submit orders over REST and watch the streamer for Order notifications as the status advances.
  • Include a currently valid auth-token in every message you send. If your token expires, obtain a new one — and reconnect if the server drops the session.
  • For token-endpoint error codes (400/401/403/404/422/429/5xx), see /reference/errors. REST object schemas (such as the Order payload) live in /reference under the orders group; the websocket message schemas (connect/heartbeat requests, acks, and the notification envelope) are defined in the streaming AsyncAPI spec — JSON or YAML.