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:
| Environment | WebSocket host |
|---|---|
| Sandbox | wss://streamer.cert.tastyworks.com |
| Production | wss://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
Ordernotifications as the status advances. - Include a currently valid
auth-tokenin 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 theOrderpayload) live in/referenceunder 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.