Skip to main content

Broker WebSocket

The same realtime channel the Trader WebSocket uses, but from the back-office side. With an admin or manager (dealer) session you connect once and stream live account events for the clients in your book — balances, margin, money movements, status changes, and session activity — so your CRM or risk desk stays in sync without polling.

What you get​

  • Live account summaries (balance / equity / margin) for your clients.
  • account_update when an account's fields change (leverage, status, prop/config you pushed).
  • money_change on every deposit / withdrawal / adjustment / credit.
  • liquidation events when a client hits a margin call or stop-out.
  • session events (a client logged in / was disconnected).

Your reach mirrors your REST scope: an admin sees every account; a manager sees only the accounts inside the group(s) they manage.

Endpoint​

wss://api.onlytradeplatform.com/ws/v1/?session_id=<session_id>
Authorization: Bearer <access_token>

The handshake needs both the session_id (query parameter) and the access token — as an Authorization: Bearer header, or as an access_token query parameter if your WebSocket client can't set headers.

Connect & authenticate​

  1. Log in over REST with your admin / manager credentials (see Broker → Authentication) and keep the access_token and session_id from the response.
  2. Open the socket with the bearer token and the session_id query parameter. A missing or expired token fails the upgrade with HTTP 401; an invalid session gets an unauthorized frame and the socket closes.
  3. Send subscribe frames to start receiving events.

Frame format​

Every frame, both directions, is a JSON object with a type and a payload:

{ "type": "account_subscribe", "payload": { "account_id": 26100003 } }
  • You send actions (subscribe to an account).
  • You receive events (a balance changed, a client hit a margin call).

What you send​

Subscribe per client account you want to watch (call it for each account in your book, e.g. as your CRM loads them):

{ "type": "account_subscribe", "payload": { "account_id": 26100003 } }

What you receive​

EventWhen
account_SummaryBalance / equity / margin / margin-level tick (note the capital S; at most one every 200 ms per account).
account_updateAccount fields changed — leverage, status, or a prop/config update you pushed.
money_changeDeposit / withdrawal / adjustment / credit.
balance_correctionA balance correction was applied.
event_liqudation_statusThe client reached a margin call / stop-out.
session_client_logoutA client session was killed (login-limit, admin disconnect, or trial expiry).
{ "type": "account_Summary", "session_id": "f6a1c2d3-…", "payload": { "ts": 1781251200000, "account_id": 26100003, "balance": 1000547.09, "credit": 0, "equity": 1010647.99, "used_margin": 9.0, "free_margin": 1010638.99, "margin_level": 11229422.11, "floating_profit": 0.90, "positions": [{ "id": 260610016, "profit": 0.90 }] } }
{ "type": "money_change", "session_id": "f6a1c2d3-…", "payload": { "account_id": 26100003, "amount": 5000.00, "balance": 1005547.09, "credit": 0, "desc": "Deposit", "origin": 0, "type": 0 } }

Error frames arrive as events too — branch on type: bad_request, internal_server_error, not_found, forbidden, unauthorized. The payload.message carries the reason.

Watching the whole book (self-hosters)​

Internally the server fans events out over NATS. A back-office consumer can read every account's stream from one subject instead of subscribing per account:

websocket.accounts.* all accounts (admin)
websocket.accounts.{account_id}.* all events for one account
websocket.accounts.{account_id}.summary account summary ticks only
websocket.accounts.{account_id}.deals deals only

You don't need NATS when using the WebSocket directly — it's documented for broker operators running their own bus.