WebSocket
wss://ws.mfxhub.com/v1/stream. The upgrade is signed like a request, with the same four headers. One connection carries every channel you subscribe to.
> {"op": "subscribe", "ch": "events"}
< {"op": "ack", "ch": "events"}
< {"op": "msg", "ch": "events", "seq": 184222, "type": "position.closed", "data": {"schema_version": 1, ...}}
> {"op": "resume", "ch": "events", "after_seq": 184222}
Client messages are subscribe, unsubscribe and resume; each names a channel in ch. Server messages are ack, msg, resync and error. Every event carries schema_version inside data.
Channels
Channels are keyed by id, never by a display name, because brokers rename servers and symbols.
| Channel | Carries | Scope |
|---|---|---|
events |
Every event of yours: terminals, commands, positions, account profile, webhooks, expert advisors | exec:read or acct:read (or the families ea:read and md:read allow) |
results:{terminal_id} |
Command outcomes and fills for one terminal | exec:read |
account:{terminal_id} |
One terminal’s account: account.snapshot, then account.marks between snapshots |
acct:read |
md:{server_id}:{symbol} |
Ticks for one symbol on one server | md:read |
candles:{server_id}:{symbol}:{tf} |
Closed candles, tf one of M1, M5, M15, M30, H1, H4, D1, W1, MN1 |
md:read |
book:{server_id}:{symbol} |
Market depth, the whole book on each change | md:read |
ea:{terminal_id} |
What your expert advisor on that terminal writes | ea:read |
Resuming
seq increases per channel. After a reconnect, send resume with the last seq you processed: events and results are replayed from up to 15 minutes back. Ticks and candles are not replayed; a stale tick is worse than none. When the position you name is older than the replay window you get resync: read the current state over REST. On an account: channel, resume answers the current snapshot.
Closing codes
4001 re-authenticate (the key expired, was rotated or revoked), 4008 you fell too far behind and were dropped, 4009 the 24-hour lifetime was reached: reconnect and resume.