Skip to content

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:

  1. Authenticate the connection with authorization.
  2. 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.