Errors take two forms depending on transport — a JSON body on REST and a typed frame on WebSocket — but share the same stable error code strings. Key your retry logic off code / error; treat message as opaque since its wording may change.
The connection remains open after most WS errors. The exception is auth_failed / auth_error, which the server may follow with a close frame — reconnect after refreshing credentials.
WebSocket error codes
code
Trigger
Recovery
rate_limited
Subscribe rate exceeded (30 actions per 10-second window)
Wait retryAfter seconds, then retry the subscribe.
symbol_limit_reached
Per-session tier symbol cap hit (free = 3, paid = 100)
Unsubscribe an existing symbol, or upgrade tier.
free_tier_cap_reached
Free-tier per-IP / per-userId cap (3) exceeded across all sessions
Unsubscribe in another session, or authenticate with an API key.
subscription_required
Subscribed to a role-gated venue (e.g. arbflag without super_admin)
Cannot upgrade by retrying; do not retry.
auth_error / auth_failed
Bad API key on {action:"auth"}, or expired JWT on subscribe
Refresh credentials; reconnect.
invalid_symbol / unknown_symbol
Symbol unknown to that venue
Fix the symbol string; consult GET /v1/symbols/{venue}/live for the canonical list.