Docs / Takers
WebSocket and TCP price streams
Stream XiroLink prices to your own apps over WebSocket or TCP: sign in, choose symbols, keep the connection alive and read each price message.
Besides FIX and the MT5 datafeed, XiroLink streams prices as JSON over WebSocket or plain TCP. Both suit your own apps, web terminals and tools. WebSocket lets the client choose symbols; TCP sends every symbol mapped to the taker.
Create the taker in Takers: choose API → WebSocket, or TCP. Set a username and password, the client's Allowed IPs, map symbols on Symbols and assign a markup profile on Markups. The taker's connection guide has the exact address for your bridge.
WebSocket
Connect
wss://<your bridge address>/ws/pricesSign in
Within 10 seconds of connecting, send:
{"action": "auth", "username": "client_a", "password": "********"}| Reply | Meaning |
|---|---|
{"status": "authenticated", "taker": "WebSocket API"} |
Signed in. Prices for every mapped symbol start to arrive. |
{"status": "auth_failed"} |
Wrong username or password. The connection closes. |
{"status": "auth_failed", "reason": "auth message required"} |
No valid sign-in message within 10 seconds |
If the client's IP is not allowed, the connection closes with code 1008 and no message.
Choose symbols
You receive every symbol mapped to the taker until you choose. To narrow it down:
{"action": "subscribe", "symbols": ["EURUSD", "XAUUSD"]}{"action": "unsubscribe", "symbols": ["XAUUSD"]}An empty subscribe, or unsubscribing from everything, goes back to all symbols.
Prices
One message per price:
{
"symbol": "EURUSD",
"bid": 1.08542,
"ask": 1.08545,
"spread": 0.00003,
"timestamp": 1762162201.125,
"bid_volume": 1000000,
"ask_volume": 1000000
}| Field | Contents |
|---|---|
symbol |
The taker's name for the symbol |
bid, ask |
Prices with your markup applied |
spread |
Ask minus bid, as a price |
timestamp |
Time of the price, Unix seconds with milliseconds |
bid_volume, ask_volume |
Size at the price, where the source provides it |
depth_levels, bids, asks |
Only where depth is enabled: levels as [[price, units], ...] |
sentiment |
Only where enabled: {"buy": ..., "sell": ...} |
If the bridge restarts the taker, the connection closes with code 1012. Reconnect and sign in again.
TCP
Connect and sign in
Open a TCP connection to your bridge's address and the taker's port. Within 10 seconds, send one line of JSON ending in a newline:
{"username": "client_a", "password": "********"}The bridge answers with {"status": "authenticated"} or {"status": "auth_failed"}. A taker set to IP only still expects a first line, but does not check it.
Keep the connection alive
Send HEARTBEAT followed by a newline every 10 seconds. The bridge answers with the same line. Any data you send counts, and after about 30 seconds of silence the bridge closes the connection.
Prices
The bridge sends one JSON object per line, one symbol per object:
{"EURUSD": {"bid_price": "1.08542", "ask_price": "1.08545", "last_updated": 1762162201.125}}
{"XAUUSD": {"bid_price": "2934.51", "ask_price": "2935.12", "last_updated": 1762162201.234, "bid_volume": "5", "ask_volume": "5"}}| Field | Contents |
|---|---|
bid_price, ask_price |
Prices as strings, at the symbol's digits, with your markup applied |
last_updated |
Time of the price, Unix seconds with milliseconds |
bid_volume, ask_volume |
Only when the source gives a size |
A TCP taker always receives every symbol mapped to it. If the client reads slowly, it gets the newest price for each symbol rather than a growing queue.
Both
- Clients connect only from the taker's Allowed IPs. Repeated failed sign-ins from one address block it for an hour; unblock it under Security.
- Prices are prices only. Neither stream accepts orders.
Something unclear or out of date? Email [email protected].