Skip to content

WebSocket Skill

The xbtfx-websocket skill provides AI agents with read-only access to real-time streaming market quotes and account events over WebSocket.

  • Skill name: xbtfx-websocket
  • Type: Read-only
  • Required env var: XBTFX_API_KEY
  • Endpoint: wss://ws.xbtfx.com/v1/ws
  • Stream real-time bid/ask quotes for one or more symbols
  • Monitor position, order, and deal events on the account
  • Access order book depth data
  • Build live dashboards or price alerts

Connect to the WebSocket endpoint and authenticate within 10 seconds by sending an auth message:

{"action": "auth", "token": "your-api-key"}

The server responds with:

{"action": "auth_ok", "login": 12345678, "tier": "standard"}

If authentication fails:

{"action": "auth_error", "message": "Invalid API key"}
Terminal window
websocat wss://ws.xbtfx.com/v1/ws
> {"action":"auth","token":"your-api-key"}
< {"action":"auth_ok","login":12345678,"tier":"standard"}
> {"action":"subscribe","channel":"quotes","symbols":["BTCUSD"]}
< {"channel":"quote","symbol":"BTCUSD","bid":65000.00,"ask":65000.50,"spread":50,"time":"2025-01-15T10:30:00.123Z"}
import asyncio
import json
import websockets
async def stream_quotes():
uri = "wss://ws.xbtfx.com/v1/ws"
async with websockets.connect(uri) as ws:
# Authenticate
await ws.send(json.dumps({
"action": "auth",
"token": "your-api-key"
}))
auth_response = await ws.recv()
print(auth_response)
# Subscribe to quotes
await ws.send(json.dumps({
"action": "subscribe",
"channel": "quotes",
"symbols": ["BTCUSD"]
}))
# Receive messages
async for message in ws:
data = json.loads(message)
print(data)
asyncio.run(stream_quotes())

Subscribe to real-time bid/ask quotes for a symbol.

Subscribe:

{"action": "subscribe", "channel": "quotes", "symbols": ["BTCUSD"]}

With depth (order book):

{"action": "subscribe", "channel": "quotes", "symbols": ["BTCUSD"], "depth": true}

Unsubscribe:

{"action": "unsubscribe", "channel": "quotes", "symbols": ["BTCUSD"]}

Quote message:

{
"channel": "quote",
"symbol": "BTCUSD",
"bid": 65000.00,
"ask": 65000.50,
"spread": 50,
"time": "2025-01-15T10:30:00.123Z"
}

Quote message with depth (when depth is enabled):

When depth is enabled, the order book data is nested within the quote message:

{
"channel": "quote",
"symbol": "BTCUSD",
"bid": 65000.00,
"ask": 65000.50,
"spread": 50,
"depth": {
"bids": [[65000.00, 1.5], [64999.50, 2.0]],
"asks": [[65000.50, 1.2], [65001.00, 3.0]]
},
"time": "2025-01-15T10:30:00.123Z"
}

Subscribe to real-time account events including position, order, and deal updates.

Subscribe:

{"action": "subscribe", "channel": "account"}

Position event:

{
"type": "position",
"event": "open",
"ticket": 12345678,
"symbol": "BTCUSD",
"side": "buy",
"volume": 0.01,
"price": 65000.00
}

Order event:

{
"type": "order",
"event": "placed",
"ticket": 12345679,
"symbol": "BTCUSD",
"order_type": "buy_limit",
"volume": 0.01,
"price": 64000.00
}

Deal event:

{
"type": "deal",
"event": "filled",
"ticket": 12345680,
"symbol": "BTCUSD",
"side": "buy",
"volume": 0.01,
"price": 65000.00,
"profit": 0.00
}

The server may send system messages for connection state changes:

{"channel": "system", "event": "connected"}
{"channel": "system", "event": "reconnect_required"}
  • Send {"action": "ping"} every 30 seconds to keep the connection alive
  • The server responds with {"action": "pong"}
  • The server closes idle connections after 90 seconds without any messages
LimitValue
Max connections per API key10
Max symbol subscriptions per connection1,000
Quote throttle rate5 updates/sec per symbol
CodeDescription
auth_errorAuthentication failed — invalid or expired token
subscription_limitSubscription limit reached (max 1,000 symbols per connection)
connection_limitMaximum connection count exceeded
rate_limitedMessage rate limit exceeded

Error messages are sent as JSON:

{"type": "error", "code": "subscription_limit", "message": "Maximum subscriptions reached (1000 per connection)"}

Agents using this skill must follow these behavioral rules:

  1. This is a read-only skill. WebSocket connections cannot execute trades or modify account state.
  2. Authenticate immediately. Send the auth message within 10 seconds of connecting.
  3. Implement keepalive. Send {"action": "ping"} every 30 seconds to prevent idle disconnection.
  4. Unsubscribe when done. Remove subscriptions that are no longer needed to stay within limits.
  5. Handle reconnection gracefully. If the connection drops, reconnect and re-authenticate. Resubscribe to all previously active channels.
  6. Always mask API keys in output. Never display the full API key or auth token to the user.
  7. Respect subscription limits. Do not subscribe to more than 1,000 symbols per connection.
  8. Process messages asynchronously. Quote updates arrive at up to 5 per second per symbol. Ensure the agent processes or buffers messages without blocking the connection.