Skip to main content
WSS
/
ws
Messages
Authentication Request
type:object

Authenticate with a JWT token

Subscribe Request
type:object

Subscribe to real-time updates

Unsubscribe Request
type:object

Unsubscribe from updates

Ping
type:object

Keep-alive ping

Authentication Expired
type:object

Session has expired

Refresh Authentication Warning
type:object

Session expires soon, re-authentication recommended

Order Update
type:object

Real-time order update

Position Update
type:object

Real-time position update

Balance Update
type:object

Real-time balance update

Account Info Update
type:object

Real-time account information update

P&L Candle Update
type:object

Real-time P&L candle data

Watchlist Update
type:object

Real-time watchlist updates

News Update
type:object

Real-time news updates

Error
type:object

Generic error response

Key Features

Order Status Updates

Real-time notifications when orders are placed, filled, partially filled, or cancelled. Track order lifecycle with millisecond latency.

Position Changes

Live updates when positions are opened, modified, or closed. Monitor both stock and option positions in real-time.

Balance Updates

Instant account balance updates including buying power, equity, cash movements, and margin changes.

P&L Candles

Real-time profit/loss candles at various intervals (15m, 1h, 4h, 1d, 1w, 1m, 1y) for performance tracking.

Watchlist Updates

Live updates when symbols are added, updated, or removed from user watchlists.

News Feed

Real-time news updates relevant to your portfolio and watchlist symbols.

Authentication Required

Authentication is required and must be completed within 5 seconds of connection. This WebSocket contains sensitive account information and requires a valid JWT token.
All connections must use WSS (WebSocket Secure) protocol. Each user receives only their own account updates, ensuring data privacy and security.

Session Management

Sessions expire after 65 minutes (3900000ms). The server:
  • Sends a refresh warning 5 minutes before expiration
  • Closes the connection when the session expires
  • Requires re-authentication after expiration

Security Best Practices

  • Always use WSS in production
  • Store JWT tokens securely
  • Implement automatic re-authentication on expiration warnings
  • Monitor connection status and implement reconnection logic

Account Updates (accUpdates)

Subscribe to all account-level updates in a single subscription:
  • Orders: Order status changes (new, filled, partial, cancelled, rejected)
  • Positions: Position changes for stocks and options
  • Balance: Buying power, equity, margin, and cash updates
  • Account: Account information changes
Requires: Account ID in subscription dataInitial Snapshot: Server sends current orders, positions, and balance upon subscription

P&L Candles (pnlCandle)

Subscribe to profit/loss candle data at specified intervals for performance tracking.Supported Intervals: 15m, 1h, 4h, 1d, 1w, 1m, 1yRequires: Account ID and interval in subscription data

Watchlist Updates (watchlistUpdates)

Subscribe to user’s watchlist changes (add/update/delete events).Requires: None (user-level subscription)

News Updates (newsUpdates)

Subscribe to real-time news feed updates relevant to your portfolio.Requires: None (user-level subscription)

Ping/Pong Keepalive

Send periodic pings to keep the WebSocket connection alive and detect network issues:Recommendation: Send a ping every 30-60 seconds to maintain connection health.

Handling Disconnects

Always implement reconnection logic with exponential backoff:
  • Start with 1 second delay
  • Double the delay on each retry (2s, 4s, 8s)
  • Cap maximum delay at 60 seconds
  • Re-authenticate after reconnection

Connection States

StateDescription
ConnectedWebSocket connection established
AuthenticatedSuccessfully authenticated, ready to subscribe
SubscribedActively receiving updates
Refresh WarningSession expiring in 5 minutes
ExpiredSession expired, connection closing
Monitor the connection state and handle state transitions gracefully in your application.

Trading Applications

Real-time order status for trading platforms. Display live order fills, rejections, and modifications.

Portfolio Monitoring

Track position changes, P&L, and balance updates for portfolio management dashboards.

Risk Management

Monitor buying power, margin levels, and position sizes in real-time for risk control systems.

Order Notifications

Push notifications to mobile apps when orders are filled or positions change.

Performance Analytics

Real-time P&L candles for performance tracking and analytics dashboards.

News Alerts

Real-time news feed integration for trading signals and market sentiment analysis.

Connection Lifecycle

Subscription Flow

  1. Connect to WebSocket endpoint
  2. Authenticate within 5 seconds
  3. Subscribe to desired update types
  4. Receive initial snapshot (for accUpdates)
  5. Stream real-time updates
  6. Unsubscribe when done
  7. Monitor session expiration warnings

Common Errors

ErrorCauseResolution
authentication timeoutDid not authenticate within 5 secondsAuthenticate immediately after connecting
unauthorizedInvalid JWT tokenVerify token is valid and not expired
missing account IDAccount ID not provided in subscriptionInclude account field in subscription data
unknown subscription typeInvalid subscription typeUse valid type: accUpdates, pnlCandle, watchlistUpdates, newsUpdates
authentication expiredSession expired (65 minutes)Re-authenticate and resubscribe

Error Response Format

{
  "action": "error",
  "error": "error message",
  "id": "req-id",
  "timestamp": 1703001234567
}
Always implement comprehensive error handling to gracefully handle network issues, authentication failures, and server errors.

Performance Optimization

  • Subscribe once per account to accUpdates to receive all account events
  • Use specific intervals for P&L candles based on your needs
  • Implement batching for handling high-frequency updates
  • Store state locally to avoid unnecessary re-subscriptions

Reliability

  • Monitor connection health with periodic pings (30-60 second intervals)
  • Implement exponential backoff for reconnections
  • Handle session expiration proactively using refresh warnings
  • Store subscription state to restore after reconnection

Security

  • Rotate tokens periodically
  • Use environment variables for connection URLs and tokens
  • Log authentication events for audit trails
  • Validate all incoming messages before processing

Development

  • Use development environment for testing
  • Test failure scenarios (disconnects, authentication failures, malformed messages)
  • Monitor bandwidth usage in production
  • Implement message queuing for high-volume scenarios

Authentication

Authenticate Connection

Authentication must be completed within 5 seconds of connection establishment.
{
  "action": "auth",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "id": "req-001"
}

Authentication Success Response

{
  "action": "authSuccess",
  "id": "req-001",
  "timestamp": 1703001234567,
  "data": {
    "expiresIn": 3900000
  }
}
The expiresIn field indicates session duration in milliseconds (65 minutes = 3900000ms).
If authentication is not completed within 5 seconds, the server will close the connection with an authRequired error.

Subscribing to Updates

Subscribe to Account Updates

Subscribe to all account-level updates including orders, positions, balance, and account information.

Basic Subscription

Subscribe to All Account Updates

Get orders, positions, balance, and account info for a specific account:
{
  "action": "subscribe",
  "type": "accUpdates",
  "data": {
    "account": "ACC123456"
  },
  "id": "req-002"
}

Response with Initial Snapshot

The server responds with current account state:
{
  "action": "subscribe",
  "type": "accUpdates",
  "id": "req-002",
  "timestamp": 1703001234567,
  "data": {
    "orders": [
      {
        "ordId": "ORD-001",
        "symbol": "AAPL",
        "side": "buy",
        "qty": "100",
        "price": "150.50",
        "status": "filled"
      }
    ],
    "positions": [
      {
        "symbol": "AAPL",
        "qty": "100",
        "avgCost": "150.45",
        "marketValue": "15200.00"
      }
    ],
    "balance": {
      "accountId": "ACC123456",
      "totalEquity": "50000.00",
      "netBuyingPower": "25000.00"
    }
  }
}
The initial snapshot includes current orders, positions, and balance. After this, you’ll receive real-time updates as changes occur.

Subscribe to 15-Minute P&L Candles

Track profit/loss at 15-minute intervals:
{
  "action": "subscribe",
  "type": "pnlCandle",
  "data": {
    "account": "ACC123456",
    "interval": "15m",
    "startTime": "2024-01-01T00:00:00Z"
  },
  "id": "req-003"
}

Subscribe to Hourly P&L Candles

{
  "action": "subscribe",
  "type": "pnlCandle",
  "data": {
    "account": "ACC123456",
    "interval": "1h"
  },
  "id": "req-004"
}

Supported Intervals

IntervalDescription
15m15 minutes
1h1 hour
4h4 hours
1d1 day
1w1 week
1m1 month
1y1 year
The startTime parameter is optional. If omitted, the subscription starts from the current time.

Subscribe to Watchlist Updates

Get notified when symbols are added, updated, or removed from watchlists:
{
  "action": "subscribe",
  "type": "watchlistUpdates",
  "id": "req-005"
}

Subscribe to News Updates

Receive real-time news relevant to your portfolio:
{
  "action": "subscribe",
  "type": "newsUpdates",
  "id": "req-006"
}
Watchlist and news subscriptions are user-level and don’t require an account ID. You’ll receive updates for all watchlists and news relevant to your account.

Real-Time Update Messages

Order Updates

Receive notifications when order status changes.

Order Filled

{
  "action": "update",
  "type": "accUpdates",
  "timestamp": 1703001234567,
  "data": {
    "contentType": "orders",
    "data": {
      "ordId": "ORD-12345",
      "clOrdId": "CLIENT-001",
      "accountId": "ACC123456",
      "symbol": "AAPL",
      "side": "buy",
      "type": "limit",
      "timeInForce": "day",
      "qty": "100",
      "price": "150.50",
      "status": "filled",
      "cumQty": "100",
      "leavesQty": "0",
      "avgPrice": "150.45",
      "currency": "USD",
      "exDestination": "NASDAQ",
      "securityType": "stock",
      "category": "equity",
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-15T10:30:05Z"
    }
  }
}

Order Status Values

StatusDescription
newOrder has been accepted
partiallyFilledOrder partially executed
filledOrder fully executed
canceledOrder has been cancelled
rejectedOrder was rejected
pendingOrder is pending submission

Position Updates

Receive notifications when positions change.

Long Stock Position

{
  "action": "update",
  "type": "accUpdates",
  "timestamp": 1703001234567,
  "data": {
    "contentType": "positions",
    "data": {
      "accountId": "ACC123456",
      "symbol": "AAPL",
      "securityType": "stock",
      "qty": "100",
      "avgCost": "150.45",
      "buyingPowerUsed": "15045.00",
      "marketValue": "15200.00",
      "unRealizedPL": "155.00",
      "realizedPL": "0",
      "todayPL": "155.00",
      "side": "long",
      "instrument": "stock",
      "createdAt": "2024-01-15T10:30:05Z",
      "updatedAt": "2024-01-15T14:30:00Z"
    }
  }
}

Balance Updates

{
  "action": "update",
  "type": "accUpdates",
  "timestamp": 1703001234567,
  "data": {
    "contentType": "balance",
    "data": {
      "accountId": "ACC123456",
      "sodPositionsMarketValue": "48000.00",
      "netBuyingPower": "25155.00",
      "stockBuyingPower": "50310.00",
      "dayTradeBuyingPower": "100620.00",
      "optionBuyingPower": "25155.00",
      "totalEquity": "50155.00",
      "settledFunds": "35000.00",
      "unsettledFunds": "0",
      "maintReq": "7646.50",
      "realizedPL": "0",
      "unRealizedPL": "167.00",
      "PDT": 0,
      "startOfDayCash": "35000.00",
      "valueBought": "15293.00",
      "valueSold": "0"
    }
  }
}

P&L Candle Updates

{
  "action": "update",
  "type": "pnlCandle",
  "timestamp": 1703001234567,
  "data": {
    "accountId": "ACC123456",
    "interval": "15m",
    "timestamp": 1703001000000,
    "open": "50000.00",
    "high": "50300.00",
    "low": "49900.00",
    "close": "50155.00",
    "realizedPnL": "0",
    "unrealizedPnL": "155.00",
    "totalPnL": "155.00"
  }
}

Watchlist Updates

{
  "action": "update",
  "type": "watchlistUpdates",
  "timestamp": 1703001234567,
  "data": {
    "msgType": "add",
    "data": {
      "id": "WL-001",
      "symbol": "TSLA",
      "name": "Tesla Inc",
      "lastPrice": "242.50",
      "change": "+2.35",
      "changePercent": "+0.98"
    }
  }
}

News Updates

{
  "action": "update",
  "type": "newsUpdates",
  "timestamp": 1703001234567,
  "data": {
    "msgType": "add",
    "data": {
      "id": "NEWS-001",
      "headline": "Fed Announces Rate Decision",
      "summary": "Federal Reserve maintains interest rates...",
      "source": "Reuters",
      "publishedAt": "2024-01-15T14:30:00Z",
      "symbols": ["SPY", "QQQ"]
    }
  }
}

Unsubscribing from Updates

Stop receiving updates for specific subscription types.

Unsubscribe from Account Updates

{
  "action": "unsubscribe",
  "type": "accUpdates",
  "data": {
    "account": "ACC123456"
  },
  "id": "req-007"
}

Response

{
  "action": "unsubscribe",
  "type": "accUpdates",
  "account": "ACC123456",
  "id": "req-007",
  "timestamp": 1703001234567
}

Connection Management

Ping/Pong Keepalive

Send periodic pings to maintain connection health and detect network issues. Ping Request:
{
  "action": "ping",
  "id": "ping-001"
}
Pong Response:
{
  "action": "pong",
  "id": "ping-001",
  "timestamp": 1703001234567
}
Recommendation: Send a ping every 30-60 seconds to keep the connection alive.

Session Expiration

Refresh Warning (5 minutes before expiration):
{
  "action": "refreshAuth",
  "timestamp": 1703001234567,
  "data": {
    "message": "authentication expires soon, please re-authenticate",
    "expiresIn": 300000
  }
}
Session Expired:
{
  "action": "authExpired",
  "error": "authentication expired",
  "timestamp": 1703001234567
}
When you receive a refreshAuth warning, you should re-authenticate or be prepared to reconnect. The connection will be closed when the session expires.

Error Handling

Error Response Format

All errors follow this format:
{
  "action": "error",
  "error": "error message description",
  "id": "correlation-id",
  "timestamp": 1703001234567
}

Common Error Scenarios

Authentication Timeout

{
  "action": "authRequired",
  "error": "authentication timeout",
  "timestamp": 1703001234567
}
Cause: Did not authenticate within 5 seconds of connection.Resolution: Send authentication request immediately after connecting.

Invalid Token

{
  "action": "error",
  "error": "unauthorized",
  "timestamp": 1703001234567
}
Cause: JWT token is invalid or expired.Resolution: Generate a new token and re-authenticate.

Missing Account ID

{
  "action": "subscribe",
  "type": "accUpdates",
  "error": "missing account ID",
  "id": "req-002",
  "timestamp": 1703001234567
}
Cause: Account ID not provided in accUpdates or pnlCandle subscription.Resolution: Include account field in subscription data.

Unknown Subscription Type

{
  "action": "error",
  "error": "unknown subscription type",
  "id": "req-003",
  "timestamp": 1703001234567
}
Cause: Invalid subscription type specified.Resolution: Use valid types: accUpdates, pnlCandle, watchlistUpdates, newsUpdates.

Best Practices

Reliable Connection Handling

Implement exponential backoff for reconnections:
let reconnectDelay = 1000; // Start with 1 second

function reconnect() {
  setTimeout(() => {
    connectWebSocket();
    reconnectDelay = Math.min(reconnectDelay * 2, 60000); // Cap at 60 seconds
  }, reconnectDelay);
}

ws.onclose = () => {
  console.log('Connection closed, reconnecting...');
  reconnect();
};

ws.onopen = () => {
  reconnectDelay = 1000; // Reset delay on successful connection
  authenticate();
};

Handle Session Expiration

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  if (message.action === 'refreshAuth') {
    console.log('Session expiring in 5 minutes');
    // Option 1: Get a new token and re-authenticate
    getNewToken().then(token => authenticate(token));

    // Option 2: Prepare to reconnect
    scheduleReconnect();
  }

  if (message.action === 'authExpired') {
    console.log('Session expired, reconnecting...');
    reconnect();
  }
};

Efficient Subscription Management

Subscribe once to account updates for all order, position, balance, and account changes:
// Good: Single subscription for all account updates
{
  "action": "subscribe",
  "type": "accUpdates",
  "data": { "account": "ACC123456" }
}

// Avoid: Multiple subscriptions (not supported)
// You can't subscribe to orders, positions, and balance separately

Store State Locally

Keep local state to avoid unnecessary re-subscriptions:
let subscriptions = new Set();

function subscribe(type, data) {
  const key = `${type}:${JSON.stringify(data)}`;

  if (subscriptions.has(key)) {
    console.log('Already subscribed to', type);
    return;
  }

  ws.send(JSON.stringify({
    action: 'subscribe',
    type: type,
    data: data
  }));

  subscriptions.add(key);
}

ws.onclose = () => {
  // Clear subscriptions on disconnect
  subscriptions.clear();
};