WebSocket Protocol
ada-api exposes a WebSocket endpoint for real-time run events. Connection requires a one-time ticket obtained via REST.
Two-step connection
# Step 1: get a ticket (valid 30s, single-use)
curl -X GET http://localhost:3001/api/ws/ticket \
-H "Authorization: Bearer <jwt>"
# → { "ticket": "550e8400-...", "expiresAt": "2026-06-01T10:00:30Z" }
# Step 2: connect WebSocket
ws://localhost:3001/ws?ticket=<uuid>Message Envelope
// All messages follow this envelope
{
"type": "<event_type>",
"id": "<uuid>",
"ts": 1748686800000,
"payload": { }
}Client → Server Commands
join_room { workspaceId } // join workspace room
subscribe_run { runId } // subscribe to run events
unsubscribe_run { runId }
cancel_run { runId } // SIGTERM on ada-core process
ping {} // latency testServer → Client Events
run:started { runId, profile, conversationId }
run:phase:started { runId, phase, agent, tier, model }
run:phase:progress { runId, phase, log, tokens }
run:phase:completed { runId, phase, cost, tokens, durationMs }
run:phase:failed { runId, phase, error }
run:completed { runId, totalCost, totalTokens, durationMs }
run:failed { runId, error }
run:cancelled { runId }
message:created { conversationId, message }
conversation:updated { conversationId }
core:status { connected: boolean }
heartbeat { ts } // every 30sClosure Codes
| Code | Meaning | Action |
|---|---|---|
1000 | Normal Closure | Don't reconnect |
1006 | Abnormal Closure | Reconnect with backoff |
4001 | Ticket Invalid | Get new ticket, reconnect |
4002 | Token Expired | Refresh JWT, get new ticket |
4003 | Rate Limited | Wait 60s |
4004 | Session Revoked | Redirect to login |
Reconnection (exponential backoff)
// Backoff: 0ms, 1s, 2s, 4s, 8s, 16s, max 30s
class AdaWebSocket {
connect() {
const ws = new WebSocket(`ws://localhost:3001/ws?ticket=${ticket}`)
ws.onclose = (e) => {
if (e.code === 1000 || e.code === 4004) return // don't retry
const delay = Math.min(1000 * 2 ** this.retries++, 30000)
setTimeout(() => this.refreshTicket().then(() => this.connect()), delay)
}
}
}