MT5 — Real-time (subscriptions & WebSocket)
Real-time data is a two-step model:
- Tell the terminal what to stream with the REST subscription endpoints below
(keyed by instance
id(UUID), not the MT5 login). - Receive the stream by connecting a WebSocket client to
/ws/serviceand subscribing to the relevant channels.
Subscribe to ticks
POST /api/external/instances/{instanceId}/subscribe-tick — body { "symbol": "EURUSD" }.
{instanceId} is the instance id (UUID).
curl -s -X POST "$ATLAS_BASE_URL/api/external/instances/$INSTANCE_ID/subscribe-tick" \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "symbol": "EURUSD" }'
Unsubscribe from ticks
POST /api/external/instances/{instanceId}/unsubscribe-tick — { "symbol": "EURUSD" }, or an
empty body to unsubscribe from all.
List tick subscriptions
GET /api/external/instances/{instanceId}/tick-subscriptions
Subscribe to candles
POST /api/external/instances/{instanceId}/subscribe-candle — { "symbol": "EURUSD", "timeframe": "M15" }.
Unsubscribe from candles
POST /api/external/instances/{instanceId}/unsubscribe-candle — { "symbol", "timeframe" }, or
empty body for all.
List candle subscriptions
GET /api/external/instances/{instanceId}/candle-subscriptions
WebSocket stream — /ws/service
Connect, authenticate with your service key, then subscribe to channels. The server pings
periodically; reply with {"type":"pong"} to stay connected.
const ws = new WebSocket("wss://api.atlaas.dev/ws/service")
ws.onopen = () => {
// 1. Authenticate
ws.send(JSON.stringify({ type: "service_auth", apiKey: process.env.ATLAS_API_KEY, clientName: "my-bot" }))
}
ws.onmessage = (e) => {
const msg = JSON.parse(e.data)
switch (msg.type) {
case "hello_from_atlas": break // greeting; authRequired: true
case "service_auth_success": // { accountId, accountName, ts }
// 2. Subscribe to channels (optionally filter by accountIds / symbols)
ws.send(JSON.stringify({
type: "subscribe",
channels: ["ticks", "candles", "positions", "trades", "orders"],
accountIds: ["5012345"],
symbols: ["EURUSD"]
}))
break
case "service_auth_failed": break // { reason }
case "subscribed": break // echo of your subscription
case "ping": ws.send(JSON.stringify({ type: "pong" })); break
case "mt5_tick": break // { accountId, symbol, bid, ask, ts }
case "mt5_candle": break // { accountId, symbol, timeframe, open, high, low, close, volume, isNew, ts }
case "mt5_position_update": break // { accountId, balance, equity, margin, freeMargin, positions: [...] }
case "mt5_trade_event": break // { accountId, symbol, orderType, orderState, volume, price, ... }
}
}
Subscribe message
{
"type": "subscribe",
"channels": ["ticks", "candles", "positions", "trades", "orders"],
"accountIds": ["5012345"],
"symbols": ["EURUSD"]
}
channels— any ofticks,candles,positions,trades,orders.accountIds/symbols— optional MT5 filters (empty = everything you own).
You only ever receive events from terminals and broker connections your account owns. If
accountIds, brokerConnectionIds or brokerOrderConnectionIds names one you don't own, it is
left out of the filter and listed in the subscribed reply under refusedAccountIds,
refusedBrokerConnectionIds or refusedBrokerOrderConnectionIds.
Unsubscribe with { "type": "unsubscribe", "channels": [...] }.