Docs
WebSocket

WebSocket

Real-time signal stream over WebSocket. Connect once and receive signals as they are generated without polling.

Overview

The WebSocket endpoint delivers signals in real time as they are generated. Use this instead of polling /signals/latest when you need minimal latency.

Endpoint: wss://api.agentsona.com/v1/ws/signals

Connecting

The WebSocket endpoint does not require authentication. Connect directly:

const ws = new WebSocket('wss://api.agentsona.com/v1/ws/signals')
 
ws.onmessage = (event) => {
  const signal = JSON.parse(event.data)
  console.log(signal.signal_type)
}
import asyncio
import json
import websockets
 
async def listen():
    uri = "wss://api.agentsona.com/v1/ws/signals"
    async with websockets.connect(uri) as ws:
        async for message in ws:
            signal = json.loads(message)
            print(signal["signal_type"])
 
asyncio.run(listen())

Message Format

Each message is a JSON object matching the engine-specific signal shape:

{
  "signal_id": "...",
  "signal_type": "SMART_MONEY_FLOW",
  "timestamp": "2026-04-01T09:03:11Z",
  "signal_expiry": "2026-04-01T15:03:11Z",
  "market": { ... },
  "signal": { ... },
  "analysis": { ... }
}

See Engine A for full field descriptions.

Keepalive

Send "ping" to the server at any time. The server responds with "pong". Use this to keep the connection alive and detect disconnects.

// Send ping every 30 seconds
setInterval(() => ws.send('ping'), 30000)
 
ws.onmessage = (event) => {
  if (event.data === 'pong') return
  const signal = JSON.parse(event.data)
  // handle signal
}

Reconnection

The WebSocket connection does not auto-reconnect. Implement reconnection logic in your client:

function connect() {
  const ws = new WebSocket('wss://api.agentsona.com/v1/ws/signals')
  ws.onclose = () => setTimeout(connect, 3000)
  ws.onmessage = (event) => {
    if (event.data === 'pong') return
    const signal = JSON.parse(event.data)
    /* handle signal */
  }
}
connect()