Connect & authenticate
Open a WebSocket to the gateway, present your token, and keep the connection healthy.
The endpoint
wss://<your-base-url>/v1/wsSame host as your REST base URL — the one shown next to your API token in
the app, or the one your SDK resolved after following the platform's
region redirect. If your REST calls go to https://eu.api.predict.ai/v1,
connect to wss://eu.api.predict.ai/v1/ws.
Authenticate
The gateway accepts the same credential as REST — an API token
(pa_live_…, see Authentication).
The token is validated once, at connect time. Present it one of two
ways:
Authorization: Bearer header — for any client that can set WebSocket
headers (servers, CLIs, bots):
wscat -c "wss://api.predict.ai/v1/ws" -H "Authorization: Bearer $TOKEN"?access_token= query parameter — for browsers, which cannot set
WebSocket headers:
wscat -c "wss://api.predict.ai/v1/ws?access_token=$TOKEN"When both are present, the header wins.
Close code 4401 — unauthorized
A missing, invalid, or expired token closes the socket with application
close code 4401. The handshake itself succeeds — the gateway accepts
the connection first so it can deliver a meaningful close code, then
closes immediately.
Treat 4401 differently from a network drop: don't reconnect in a
loop with the same token — it will keep failing. Refresh or replace the
token first, then reconnect.
Keepalive
Send an app-level ping every ~25 seconds so proxies and load balancers don't idle the connection out:
{ "action": "ping", "id": "c42" }The gateway answers with a pong frame. See the
wire protocol for the exact shapes.
Reconnect strategy
Connections drop — deploys, network blips, idle timeouts. A robust client:
- Backs off exponentially — start around 1 second, double per attempt, cap around 30 seconds.
- Resubscribes to every channel after each reconnect — subscriptions are per-connection state and do not survive a disconnect.
- Reconciles via REST after resubscribing — events that fired while you were offline are not replayed.
- Stops on
4401— replace the token, then reconnect. Also reconnect proactively with the new token after regenerating one, so a long-lived socket doesn't outlive its credentials.
A client that falls too far behind reading events is disconnected with
close code 1011 rather than buffered indefinitely. Handle it like any
other drop: reconnect, resubscribe, reconcile via REST.

