WebSocket Stream¶
Overview¶
The platform WebSocket stream is used for real-time client updates.
It delivers:
- quotes
- balance updates
- trade updates
- price alert triggers
The client does not need symbol subscriptions for account-specific events such as balance, trade, or price alerts. Those events are pushed automatically to WebSocket sessions with a selected active account.
Endpoint¶
wss://{broker_domain}:{ws_port}
Session Flow¶
The WebSocket session uses a two-step account context flow:
- Authenticate the connection with
authorization. - Select the current trading account with
account.switch.
This flow is the same for account sessions and customer sessions.
Authentication¶
After connection, the client must send a message with the JWT token:
{
"authorization": "<JWT_TOKEN>"
}
The token is decoded on the server side and linked to the current WebSocket session identity.
Authentication does not select an account for streaming. The client must call account.switch after successful authorization.
Authentication Response¶
Success:
{
"event": "authorization",
"success": true
}
Error:
{
"event": "authorization",
"success": false,
"error": "INVALID_TOKEN"
}
Possible errors:
| Error | Description |
|---|---|
INVALID_TOKEN |
Token is invalid or required payload fields are missing |
UNSUPPORTED_SESSION |
Session type is not supported by the WebSocket client flow |
Account Switch¶
After authentication, the client must select the account that should receive account-scoped events.
{
"event": "account.switch",
"active_login": 2000009
}
The server also accepts login as an alias:
{
"event": "account.switch",
"login": 2000009
}
For SESSION_USER account sessions, account.switch may be sent without
active_login; the server uses the account login from the JWT payload.
{
"event": "account.switch"
}
And object-form data:
{
"event": "account.switch",
"data": {
"active_login": 2000009
}
}
Validation Rules¶
| Session type | Rule |
|---|---|
SESSION_USER |
active_login is optional. If sent, it must match the account login from the JWT payload |
SESSION_CUSTOMER |
active_login must be linked to the authenticated customer |
Customer account ownership is validated on the server side. A customer can switch between linked accounts without reconnecting the WebSocket.
Workflow Trigger¶
Every successful account.switch is also emitted on the server as the back-office workflow trigger account.switch.
This includes switching to the same already active account. The client should therefore treat every successful response as account activation, not only as a changed-account event.
Workflow rules can use this trigger to create account-scoped notifications, including marketing popup notifications delivered later through the regular notification event marker "n".
Account Switch Response¶
Success:
{
"event": "account.switch",
"success": true,
"active_login": 2000009
}
Error:
{
"event": "account.switch",
"success": false,
"active_login": 2000009,
"error": "PERMISSION_DENIED"
}
Possible errors:
| Error | Description |
|---|---|
INVALID_LOGIN |
Missing or invalid account login. For SESSION_CUSTOMER, active_login / login is required |
UNAUTHORIZED |
Account switch was sent before authorization |
PERMISSION_DENIED |
Account is not allowed for the current session identity |
SESSION_CHANGED |
Session identity changed while switch was being processed |
Account Context¶
active_login defines the current account context for the WebSocket session.
Account-scoped events are delivered only when the event login matches the session active_login.
Affected events:
- balance updates
- trade updates
- price alert events
- account-level notifications
If the client is authenticated but has not selected an account with account.switch, it will not receive account-scoped events.
When account.switch is called again, the WebSocket starts receiving account-scoped events for the new active account and stops receiving them for the previous account.
Quote subscriptions are not account-scoped. They are controlled only by symbol channel subscriptions.
Channel Subscription¶
Market quote streams use channel subscription.
Subscribe¶
{
"event": "subscribe",
"data": ["eurusd", "btcusd"]
}
Unsubscribe¶
{
"event": "unsubscribe",
"data": ["eurusd"]
}
Quote channels are symbol-based. The exact symbol naming must match the server symbol name used by the client terminal.
Ping / Pong¶
The server accepts a plain text heartbeat:
ping
Response:
pong
Payload Format¶
Most outgoing events are sent as compact JSON arrays.
The first element is the event marker:
"t"— quote update"b"— balance update"o"— trade update"a"— price alert event"n"— notification
This compact format is used to reduce payload size and parsing overhead.
Event Delivery Model¶
Quotes¶
Quotes are broadcast to all sessions subscribed to the symbol channel.
Balance¶
Balance updates are sent directly to all active WebSocket sessions where active_login matches the balance login.
Trade¶
Trade updates are sent directly to all active WebSocket sessions where active_login matches the trade login.
Price Alert¶
Price alert trigger events are sent directly to all active WebSocket sessions where active_login matches the alert login.
Ordering Notes¶
Within a single session, the server preserves per-session send order.
However, different event types may arrive close together:
- quote update
- trade update
- balance update
- price alert trigger
Clients should treat WebSocket events as incremental real-time updates and reconcile with REST state if strict snapshot consistency is required.