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
When to Use
Section titled “When to Use”- 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
When NOT to Use
Section titled “When NOT to Use”- Executing trades or managing positions — use the Trading Skill
- Checking account balance or trade history — use the Account Skill
- One-off symbol lookups — use the Market Data Skill
Connection and Authentication
Section titled “Connection and Authentication”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"}Connection Example (websocat)
Section titled “Connection Example (websocat)”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"}Connection Example (Python)
Section titled “Connection Example (Python)”import asyncioimport jsonimport 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())Channels
Section titled “Channels”Quotes Channel
Section titled “Quotes Channel”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"}Account Channel
Section titled “Account Channel”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}System Messages
Section titled “System Messages”The server may send system messages for connection state changes:
{"channel": "system", "event": "connected"}{"channel": "system", "event": "reconnect_required"}Keepalive
Section titled “Keepalive”- 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
Connection Limits
Section titled “Connection Limits”| Limit | Value |
|---|---|
| Max connections per API key | 10 |
| Max symbol subscriptions per connection | 1,000 |
| Quote throttle rate | 5 updates/sec per symbol |
Error Codes
Section titled “Error Codes”| Code | Description |
|---|---|
auth_error | Authentication failed — invalid or expired token |
subscription_limit | Subscription limit reached (max 1,000 symbols per connection) |
connection_limit | Maximum connection count exceeded |
rate_limited | Message rate limit exceeded |
Error messages are sent as JSON:
{"type": "error", "code": "subscription_limit", "message": "Maximum subscriptions reached (1000 per connection)"}Agent Guidelines
Section titled “Agent Guidelines”Agents using this skill must follow these behavioral rules:
- This is a read-only skill. WebSocket connections cannot execute trades or modify account state.
- Authenticate immediately. Send the auth message within 10 seconds of connecting.
- Implement keepalive. Send
{"action": "ping"}every 30 seconds to prevent idle disconnection. - Unsubscribe when done. Remove subscriptions that are no longer needed to stay within limits.
- Handle reconnection gracefully. If the connection drops, reconnect and re-authenticate. Resubscribe to all previously active channels.
- Always mask API keys in output. Never display the full API key or auth token to the user.
- Respect subscription limits. Do not subscribe to more than 1,000 symbols per connection.
- 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.