Skip to main content
WSS
/
v1
/
accounts
/
ws

Documentation Index

Fetch the complete documentation index at: https://finance.dev/llms.txt

Use this file to discover all available pages before exploring further.

What this stream gives you. Open one connection to wss://api.aries.com/v1/accounts/ws, authenticate, and the server will push updates whenever anything changes on your trading account — an order fills, a position is opened or closed, your buying power moves, news drops on a stock you hold, or a watchlist gets edited on another device. You get the same live picture a brokerage app would show, without polling.

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 (15s, 1m, 5m, 15m, 1h, 1d, 1mo) 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.

Endpoint

Connect to the accounts WebSocket endpoint for all account-related streams (orders, positions, balances, P&L candles, watchlist updates, and news):Production: wss://api.aries.com/v1/accounts/wsMigration: If you were using wss://api.ariesfinancial.com/ws, update to the URL above.After connecting, authenticate within 5 seconds, then subscribe to the topics you need: account, pnl, watchlist, or news.

Authentication Required

Send a request message to POST /auth with your token in payload.body:Auth request example:
{
  "type": "request",
  "id": "auth-001",
  "payload": {
    "method": "post",
    "path": "/auth",
    "body": {
      "token": "YOUR_ACCESS_TOKEN"
    }
  }
}
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
Each topic is a separate stream — subscribe only to what your app needs.

Account Updates (account)

One subscription covers everything that happens on a trading account:
  • Orders — order status changes as your orders move through the system (see the full status list below).
  • Positions — when a position is opened, increased, reduced, or closed, for both stocks and options.
  • Balance — buying power, equity, margin, and cash movements.
  • Account info — changes to the account record itself (type, options level, etc.).
Requires: accountId in params — the ID of the account you want to subscribe to.Initial snapshot: Right after you subscribe, the server sends a snapshot containing current account/balance fields, all open positions, legacy orders, and the new ordersV2 list, so you start with the full state.

P&L Candles (pnl)

A live time-series of your account’s profit-and-loss, broken into “candles” of a fixed length (just like price candles on a chart). Useful for plotting equity curves and intraday performance.Supported intervals — choose the candle length that matches your dashboard:
IntervalCandle lengthTypical use
15s15 secondsVery granular intraday tracking
1m1 minuteDefault — intraday equity curve
5m5 minutesSmoother intraday view
15m15 minutesHalf-day / full-day view
1h1 hourMulti-day view
1d1 dayDaily P&L history
1mo1 monthLong-term performance
Requires: accountId and startTime (an RFC3339 timestamp marking how far back to start the series) in params. interval is optional and defaults to 1m.

Watchlist Updates (watchlist)

Pushes a message every time a symbol is added to, updated in, or removed from any of your watchlists — including changes made on other devices, so apps stay in sync.Requires: Nothing extra. The subscription is tied to your authenticated user, not a specific account.

News Updates (news)

Pushes news articles relevant to your portfolio in real time.Optional params (omit for the firehose of all news):
  • symbols — array of tickers to filter by, e.g. ["AAPL", "TSLA"]. You’ll only receive news mentioning these symbols.
  • topics — array of topic categories to filter by, e.g. ["earnings"].

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 topics
  4. Receive initial snapshot (for account and pnl topics)
  5. Stream real-time updates
  6. Unsubscribe when done
  7. Monitor session expiration warnings

Common Errors

Error CodeCauseResolution
AUTH_REQUIREDDid not authenticate within 5 secondsAuthenticate immediately after connecting
INVALID_TOKENInvalid or expired JWT tokenGenerate a new token and re-authenticate
MISSING_ACCOUNT_IDaccountId not provided in paramsInclude accountId in subscription params
UNKNOWN_TOPICInvalid subscription topicUse valid topic: account, pnl, watchlist, news
MISSING_START_TIMEstartTime not provided for P&LInclude an RFC3339 timestamp in params.startTime
INVALID_INTERVALInvalid PnL candle intervalUse: 15s, 1m, 5m, 15m, 1h, 1d, 1mo
ACCESS_DENIEDUser does not own the accountVerify the account ID belongs to the authenticated user

Error Response Format

{
  "type": "response",
  "id": "req-002",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 400,
    "error": "accountId is required",
    "code": "MISSING_ACCOUNT_ID"
  }
}
Always implement comprehensive error handling to gracefully handle network issues, authentication failures, and server errors.

Performance Optimization

  • Subscribe once per account to account topic 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.
{
  "type": "request",
  "id": "auth-001",
  "payload": {
    "method": "post",
    "path": "/auth",
    "body": {
      "token": "YOUR_ACCESS_TOKEN"
    }
  }
}

Authentication Success Response

{
  "type": "event",
  "payload": {
    "action": "authSuccess",
    "data": {
      "expiresIn": 3900000
    },
    "id": "auth-001",
    "timestamp": 1703001234567
  }
}
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 authTimeout event.

Subscribing to Updates

Subscribe to Account Updates

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

Account Updates

Subscribe to All Account Updates

Get orders, positions, balance, and account info for a specific account:
{
  "type": "subscribe",
  "id": "req-002",
  "payload": {
    "topic": "account",
    "params": {
      "accountId": "ACC123456"
    }
  }
}

Response with Initial Snapshot

The server responds with a subscribed message containing current account state. Decimal values are serialized as JSON strings.
{
  "type": "subscribed",
  "id": "req-002",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 200,
    "topic": "account",
    "params": {
      "accountId": "ACC123456"
    },
    "data": {
      "account": {
        "accountNumber": "ACC123456",
        "accountType": "MARGIN",
        "accountClass": "INDIVIDUAL",
        "optionsLevel": "LEVEL_3",
        "cashAvailable": "25155.00",
        "netLiquidity": "50155.00",
        "marginEquity": "50155.00",
        "maintenanceExcess": "17508.50",
        "sma": "25155.00",
        "maintReq": "7646.50",
        "netBuyingPower": "25155.00",
        "stockBuyingPower": "50310.00",
        "dayTradeBuyingPower": "100620.00",
        "optionBuyingPower": "25155.00",
        "totalEquity": "50155.00",
        "pendingOrdersCount": 0
      },
      "positions": [
        {
          "accountId": "ACC123456",
          "symbol": "AAPL",
          "securityType": "EQUITY",
          "qty": "100",
          "avgPrice": "150.45",
          "avgCost": "150.45",
          "unRealizedPL": "155.00",
          "todayRealizedPnL": "0",
          "realizedPL": "0",
          "todayPL": "155.00",
          "instrument": "EQUITY"
        }
      ],
      "orders": [
        {
          "ordId": "ORD-001",
          "clOrdId": "CLIENT-001",
          "accountId": "ACC123456",
          "symbol": "AAPL",
          "side": "BUY",
          "type": "LIMIT",
          "timeInForce": "DAY",
          "qty": "100",
          "price": "150.50",
          "ordStatus": "FILLED"
        }
      ],
      "ordersV2": []
    }
  }
}
The initial snapshot includes merged account and balance fields, positions, legacy orders, and ordersV2. After this, you’ll receive real-time event messages as changes occur.

Subscribe to P&L Candles

Track profit/loss at specified intervals. startTime is required:
{
  "type": "subscribe",
  "id": "req-003",
  "payload": {
    "topic": "pnl",
    "params": {
      "accountId": "ACC123456",
      "interval": "1m",
      "startTime": "2024-01-01T00:00:00Z"
    }
  }
}

Supported Intervals

IntervalDescription
15s15 seconds
1m1 minute
5m5 minutes
15m15 minutes
1h1 hour
1d1 day
1mo1 month

Subscribe to Watchlist Updates

Get notified when symbols are added, updated, or removed from watchlists:
{
  "type": "subscribe",
  "id": "req-004",
  "payload": {
    "topic": "watchlist"
  }
}

Subscribe to News Updates

Receive real-time news. Optionally filter by symbols or topics:
{
  "type": "subscribe",
  "id": "req-005",
  "payload": {
    "topic": "news",
    "params": {
      "symbols": ["AAPL", "TSLA"],
      "topics": ["earnings"]
    }
  }
}
Omit params entirely to receive all news without filtering.
Watchlist and news subscriptions are user-level and don’t require an account ID.

Payload Data Types

Field groupJSON typeNotes
id, topic, params.accountId, enum fieldsstringRequest IDs and topic/account identifiers are strings.
Trading amounts and quantitiesstringDecimal fields such as qty, price, avgPrice, totalEquity, PDT, and P&L values are serialized as strings.
pendingOrdersCountintegerCount fields remain numeric integers.
timestamp, createdAt, updatedAtstringWebSocket envelopes and domain timestamps use RFC3339 strings. Auth event payload timestamps use Unix milliseconds.
expiresIn, expiresAt, tintegerAuth expiry values are Unix milliseconds. P&L t values are Unix seconds.
orders, ordersV2, positionsarrayAccount subscription snapshots return arrays for these fields.

Real-Time Update Messages

Once subscribed, the server pushes event messages as data changes.

Order Updates

Receive notifications when order status changes.

Order Filled

{
  "type": "event",
  "timestamp": "2024-01-15T10:30:05Z",
  "payload": {
    "topic": "account",
    "name": "account.order",
    "target": "account:ACC123456",
    "data": {
      "ordId": "ORD-12345",
      "clOrdId": "CLIENT-001",
      "accountId": "ACC123456",
      "symbol": "AAPL",
      "side": "BUY",
      "type": "LIMIT",
      "timeInForce": "DAY",
      "qty": "100",
      "price": "150.50",
      "ordStatus": "FILLED",
      "cumQty": "100",
      "leavesQty": "0",
      "avgPrice": "150.45",
      "currency": "USD",
      "exDestination": "MNGDFTE",
      "securityType": "EQUITY",
      "category": "EQUITY",
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-15T10:30:05Z"
    }
  }
}

ordStatus Values

The order status field is ordStatus. These are the full set of states an order can be in over its lifetime:
StatusWhat it meansWhat to show the user
PENDING_NEWThe order is on its way to the exchange but hasn’t been accepted yet.”Submitting…”
NEWThe exchange has accepted the order and it is live in the book (working but not yet executed).”Working” / “Open”
PARTIALLY_FILLEDSome of the order’s quantity has executed; the rest is still working. Watch cumQty and leavesQty.”Partially filled”
FILLEDThe entire order quantity has executed. The order is done.”Filled” / “Complete”
PENDING_CANCELYou sent a cancel request; the exchange has not confirmed it yet.”Cancelling…”
CANCELEDThe order was cancelled (by you, by the system, or by the exchange). It will not execute further.”Cancelled”
PENDING_REPLACEYou sent a modify/replace request; the exchange has not confirmed it yet.”Modifying…”
REJECTEDThe order was refused (bad parameters, insufficient buying power, halted symbol, etc.). It never made it onto the book.”Rejected” + error reason
EXPIREDThe order reached its time-in-force limit without filling (e.g. a DAY order that didn’t fill before market close).”Expired”

Order field enums

Order event payloads contain several enum fields. Here’s the full vocabulary you’ll see across stocks and options: side — direction of the trade:
ValueMeaning
BUYBuying — opening a long position or closing a short.
SELLSelling — closing a long position or opening a short.
SELL_SHORTSelling shares you do not own (short sale). Subject to short-sale regulations.
BUY_TO_COVERBuying back shares to close an existing short position.
type — order type, i.e. how the order is priced:
ValueMeaning
MARKETExecute immediately at the best available price. No price guarantee.
LIMITExecute only at the specified price or better. Price guarantee, no execution guarantee.
STOPSits inactive until the stop price is touched, then becomes a market order.
STOP_LIMITSits inactive until the stop price is touched, then becomes a limit order at the limit price.
TRAILING_STOPA stop that follows the market by a fixed dollar or percentage offset.
timeInForce — how long the order stays alive:
ValueMeaning
DAYActive until the end of today’s regular trading session, then cancelled if not filled.
GTCGood ‘Til Cancelled — stays open until you cancel it (broker may cap at 60–90 days).
IOCImmediate Or Cancel — fill whatever you can immediately, cancel the rest.
FOKFill Or Kill — fill the entire order immediately, or cancel it entirely.
GTDGood ‘Til Date — stays open until a specific date you provide.
OPGAt the market open.
CLOAt the market close.
securityType / instrument — what asset class:
ValueMeaning
EQUITYStock or ETF.
OPTIONSingle option contract.
MULTI_LEGMulti-leg option order (spread, condor, etc.) — see legs array.
putCall (options only): CALL or PUT. positionEffect (options only): OPEN (creates/increases a position) or CLOSE (reduces/closes one).

Position Updates

Receive notifications when positions change.

Long Stock Position

{
  "type": "event",
  "timestamp": "2024-01-15T14:30:00Z",
  "payload": {
    "topic": "account",
    "name": "account.position",
    "target": "account:ACC123456",
    "data": {
      "accountId": "ACC123456",
      "symbol": "AAPL",
      "securityType": "EQUITY",
      "qty": "100",
      "avgPrice": "150.45",
      "avgCost": "150.45",
      "unRealizedPL": "155.00",
      "todayRealizedPnL": "0",
      "realizedPL": "0",
      "todayPL": "155.00",
      "instrument": "EQUITY",
      "createdAt": "2024-01-15T10:30:05Z",
      "updatedAt": "2024-01-15T14:30:00Z"
    }
  }
}
Position updates emit primary fields avgPrice, todayRealizedPnL, and securityType. The backend also emits backward-compatible aliases avgCost, realizedPL, and instrument.

Balance Updates

{
  "type": "event",
  "timestamp": "2024-01-15T14:30:00Z",
  "payload": {
    "topic": "account",
    "name": "account.balance",
    "target": "account:ACC123456",
    "data": {
      "accountId": "ACC123456",
      "sodPositionsMarketValue": "48000.00",
      "netBuyingPower": "25155.00",
      "stockBuyingPower": "50310.00",
      "dayTradeBuyingPower": "100620.00",
      "optionBuyingPower": "25155.00",
      "dayTradeOvernightRegTBuyingPower": "50310.00",
      "totalEquity": "50155.00",
      "settledFunds": "35000.00",
      "unsettledFunds": "0",
      "heldBackFunds": "0",
      "grossMargin": "15045.00",
      "pendingOrdersMarginRequirements": "0",
      "maintReq": "7646.50",
      "creditMultiplier": "2",
      "pendingOrdersCount": 0,
      "credit": "50000.00",
      "creditRemaining": "25155.00",
      "realizedPL": "0",
      "unRealizedPL": "167.00",
      "SMA": "25155.00",
      "smaCreditRemaining": "25155.00",
      "PDT": "0",
      "pdtCreditRemaining": "100620.00",
      "startOfDayCash": "35000.00",
      "valueBought": "15293.00",
      "valueSold": "0"
    }
  }
}
Balance field reference — decimal values arrive as JSON strings to preserve precision:
FieldWhat it means
accountIdThe account this balance update belongs to.
sodPositionsMarketValueStart-of-day market value of all open positions (i.e. what your holdings were worth when the trading day opened).
netBuyingPowerTotal purchasing power available right now across all instruments. The most common number to display as “buying power” in a UI.
stockBuyingPowerHow much you can use specifically to buy stock (typically up to 2× cash on margin).
dayTradeBuyingPowerHow much you can use for same-day round-trip trades (typically up to 4× equity for pattern day traders). Resets at end of day.
optionBuyingPowerHow much you can use to buy options. Options usually require cash, so this is typically lower than stock buying power.
dayTradeOvernightRegTBuyingPowerDay-trade buying power that can also be held overnight under Reg T rules.
totalEquityCash + market value of positions − margin debit. Your account’s net worth.
settledFundsCash that has fully settled and is freely available (T+1/T+2 has passed).
unsettledFundsCash from recent sales that hasn’t settled yet — usable for most trades, but cash accounts have restrictions.
heldBackFundsCash temporarily reserved for pending orders or compliance holds. Not usable.
grossMarginTotal amount you have borrowed from the broker on margin.
pendingOrdersMarginRequirementsMargin already earmarked for orders that are working but not yet filled.
maintReqMaintenance requirement — the minimum equity you must hold to support your current positions. Drop below this and you may get a margin call.
creditMultiplierHow many times your equity you can borrow on standard margin (typically 2).
pendingOrdersCountNumber of orders currently working.
creditTotal margin credit line extended to the account.
creditRemainingHow much of that credit line is still available.
realizedPLCumulative profit/loss from positions that have been closed.
unRealizedPLProfit/loss on positions you currently hold open — i.e. paper gains/losses based on current market value.
SMASpecial Memorandum Account — a margin-account balance that effectively stores up “extra” buying power from gains. Reg T concept.
smaCreditRemainingSMA buying power still available.
PDTPattern Day Trader flag balance — relates to the four-day-trade rule and the $25,000 minimum equity requirement under FINRA Rule 4210.
pdtCreditRemainingRemaining day-trade buying power for a flagged PDT account.
startOfDayCashCash balance at the start of today’s session. Useful for calculating daily change.
valueBoughtDollar value of purchases executed today.
valueSoldDollar value of sales executed today.

Account-level enums

The account-info and account snapshot messages include a few enum fields. Here are the full sets of values you may see: accountType — how the account is funded and settled:
ValueMeaning
CASHCash account — trades must be paid for with settled funds; no margin borrowing.
MARGINStandard margin account — can borrow against equity (subject to Reg T).
IRAIndividual Retirement Account — tax-advantaged, no margin borrowing.
ROTH_IRARoth IRA — after-tax retirement account.
RETIREMENTGeneric retirement account (401k, SEP, etc.).
accountClass — who owns the account:
ValueMeaning
INDIVIDUALSingle-person account.
JOINTJoint ownership (two or more individuals).
CORPORATEOwned by a corporation.
TRUSTOwned by a trust.
LLCOwned by an LLC.
optionsLevel — what option strategies the account is approved for. Higher levels unlock more complex (and risky) strategies:
ValueWhat you can trade
LEVEL_0Not approved for options.
LEVEL_1Covered calls and cash-secured puts only.
LEVEL_2Adds long calls and long puts (buying options).
LEVEL_3Adds spreads (e.g. vertical spreads, iron condors) — defined-risk multi-leg strategies.
LEVEL_4Adds naked option selling — undefined-risk strategies. Requires the highest equity threshold.

Account Info Updates

{
  "type": "event",
  "timestamp": "2024-01-15T14:30:00Z",
  "payload": {
    "topic": "account",
    "name": "account.info",
    "target": "account:ACC123456",
    "data": {
      "id": "ACC123456",
      "sterlingAccountId": "STERLING-123",
      "apexAccountId": "",
      "fdid": "FDID-123456",
      "description": "John Doe Trading Account",
      "accountType": "MARGIN",
      "accountClass": "INDIVIDUAL",
      "optionsLevel": "LEVEL_3",
      "maintenanceExcess": "17508.50",
      "cashAvailable": "25155.00",
      "exchangeSurplus": "0",
      "accruedCash": "0",
      "netLiquidity": "50155.00",
      "marginEquity": "50155.00",
      "sma": "25155.00",
      "maintReq": "7646.50",
      "email": "john.doe@example.com",
      "cell": "+1234567890",
      "groupId": "TRADING"
    }
  }
}

P&L Candle Updates

{
  "type": "event",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "topic": "pnl",
    "data": {
      "accountId": "ACC123456",
      "interval": "1m",
      "t": [1703001000],
      "c": [50155]
    }
  }
}

Watchlist Updates

{
  "type": "event",
  "timestamp": "2024-01-15T14:30:00Z",
  "payload": {
    "topic": "watchlist",
    "data": {
      "id": "WL-001",
      "symbol": "TSLA",
      "name": "Tesla Inc",
      "lastPrice": "242.50",
      "change": "+2.35",
      "changePercent": "+0.98"
    }
  }
}

News Updates

{
  "type": "event",
  "timestamp": "2024-01-15T14:30:00Z",
  "payload": {
    "topic": "news",
    "data": {
      "msgType": "add",
      "items": [
        {
          "id": "12345",
          "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 topics.

Unsubscribe from Account Updates

{
  "type": "unsubscribe",
  "id": "req-007",
  "payload": {
    "topic": "account",
    "params": {
      "accountId": "ACC123456"
    }
  }
}

Response

{
  "type": "response",
  "id": "req-007",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 200,
    "data": {
      "unsubscribed": true,
      "topic": "account",
      "accountId": "ACC123456"
    }
  }
}

Connection Management

Ping/Pong Keepalive

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

Session Expiration

Refresh Warning (5 minutes before expiration):
{
  "type": "event",
  "payload": {
    "action": "refreshAuth",
    "data": {
      "expiresIn": 300000,
      "expiresAt": 1703001534567
    },
    "id": "system",
    "timestamp": 1703001234567
  }
}
Session Expired:
{
  "type": "event",
  "payload": {
    "action": "authExpired",
    "data": {
      "error": "session expired"
    },
    "id": "system",
    "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:
{
  "type": "response",
  "id": "req-002",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 400,
    "error": "accountId is required",
    "code": "MISSING_ACCOUNT_ID"
  }
}

Common Error Scenarios

Authentication Timeout

{
  "type": "event",
  "payload": {
    "action": "authTimeout",
    "data": {
      "error": "authentication timeout"
    },
    "id": "system",
    "timestamp": 1703001234567
  }
}
Cause: Did not authenticate within 5 seconds of connection.Resolution: Send authentication request immediately after connecting.

Invalid Token

{
  "type": "response",
  "id": "auth-001",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 401,
    "error": "token is invalid or expired",
    "code": "INVALID_TOKEN"
  }
}
Cause: JWT token is invalid or expired.Resolution: Generate a new token and re-authenticate.

Missing Account ID

{
  "type": "response",
  "id": "req-002",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 400,
    "error": "accountId is required",
    "code": "MISSING_ACCOUNT_ID"
  }
}
Cause: accountId not provided in params for account or pnl subscription.Resolution: Include accountId in payload.params.

Unknown Topic

{
  "type": "response",
  "id": "req-003",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "status": 400,
    "error": "unknown subscription topic: badtopic",
    "code": "UNKNOWN_TOPIC"
  }
}
Cause: Invalid topic specified.Resolution: Use valid topics: account, pnl, watchlist, news.

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 msg = JSON.parse(event.data);
  const payload = msg.payload;

  if (msg.type === 'event' && payload?.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 (msg.type === 'event' && payload?.action === 'authExpired') {
    console.log('Session expired, reconnecting...');
    reconnect();
  }
};

Efficient Subscription Management

Subscribe once to account updates for all order, position, balance, and account changes:
// Subscribe to all account events
ws.send(JSON.stringify({
  type: 'subscribe',
  id: 'req-002',
  payload: {
    topic: 'account',
    params: { accountId: 'ACC123456' }
  }
}));

Store State Locally

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

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

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

  ws.send(JSON.stringify({
    type: 'subscribe',
    id: `sub-${Date.now()}`,
    payload: { topic, params }
  }));

  subscriptions.add(key);
}

ws.onclose = () => {
  // Clear subscriptions on disconnect
  subscriptions.clear();
};
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

Error response

Authentication Success
type:object

Authentication succeeded

Authentication Timeout
type:object

Authentication timed out

Subscribed
type:object

Subscription confirmed with snapshot

Unsubscription Confirmed
type:object

Server confirms unsubscription

Pong
type:object

Keep-alive pong response