DocsErrors & troubleshooting

Errors & troubleshooting

Failures split into two phases: before the WebSocket opens (HTTP status on upgrade) and after connect (JSON error frames sent by the server).

Upgrade errors

These HTTP responses are sent before the WebSocket handshake completes. No WebSocket frames are exchanged.

  • 401 — invalid or missing apiKey.
  • 403 — key authenticated but not entitled for WebSocket / package access (JSON body with an error reason).
  • 429 — too many open WebSocket connections for your account (or global capacity). Body: { "error": "WS_CONNECTION_LIMIT_EXCEEDED", "message": "rate limit exceeded" }. Close an existing connection or upgrade your package. See Rate limits.
  • 503 — auth or entitlement check timed out / temporarily unavailable. Response includes Retry-After: 2; retry shortly. The same status with a JSON body carrying SERVICE_RESTARTING and Retry-After: 1 is returned for a few seconds while a release swaps the serving process: reconnect after the delay and resubscribe. Treat any handshake answer other than 101 as a retry, whatever the status.

In-stream error codes

After connect, failed client actions emit type: "error" frames. Subscribe failures also set event: "subscribe_failed" (or subscribe_partial_failed). Invalid symbols appear in rejected when present — there is no details object.

ParameterDescription
INVALID_PAYLOADMalformed JSON, non-object body, unknown action, bad channels array, missing channels, invalid symbols field type, or generic processing failure.
EMPTY_SYMBOLSsymbols field is present but empty after normalization.
TOO_MANY_SYMBOLSMore symbols in one subscribe action than the per-message cap (env API_PUBLIC_WS_MAX_SYMBOLS_PER_SUBSCRIBE, default 500). Message is usually "rate limit exceeded".
SYMBOL_LIMIT_EXCEEDEDAccount distinct-symbol cap or per-connection distinct symbol cap. Message is usually "rate limit exceeded".
UNSUPPORTED_CHANNELChannel string is not one of the 13 public channels.
INVALID_CHANNELChannel is known but not allowed for this API key (entitlement / package deny).
INVALID_SYMBOLOne or more symbols are not enabled for the requested channel. See rejected[] (and optional channel / symbol fields).
UNSUPPORTED_SYMBOL_FOR_CHANNELSymbol is known but not valid for the requested channel asset class.
UNAUTHORIZED_SYMBOLSymbol is not entitled for this account on that channel.
PARTIAL_SUBSCRIBE_FAILEDSome symbols subscribed successfully; rejected[] lists those that did not (event: subscribe_partial_failed).
MARKET_DATA_CAPACITYTemporary capacity / activation limit for demand-driven (smart-auto) symbols. Retry later.
PACKAGE_EXPIREDIn-stream entitlement revoke after connect (package ended). Connection may be closed.

The server also sends native WebSocket ping frames. If the client does not answer with pongs, the server emits a system { "event": "disconnect", "code": "HEARTBEAT_TIMEOUT" } and closes with code 4008.

When a release replaces the serving process, every open stream first receives { "event": "disconnect", "code": "SERVER_RESTART" } and is then closed with code 1012. Reconnect right away and resubscribe; the snapshot on subscribe closes the gap. A close that arrives with no system frame and no close code (1006) was not initiated by the server and usually points at a reset on the network path; reconnect the same way.

Common fixes

Start here when a connection fails or subscribe actions return errors:

  • Check the connect URL — use wss://stream.tickerlayer.com/?apiKey=..., not the REST base URL. URL-encode your key with encodeURIComponent. See Connection and Authentication.
  • Wait for the ready frame — send subscribe actions only after the server emits event: "ready".
  • Send valid JSON text frames — one JSON object per message; binary frames are not accepted from the client.
  • Verify symbols and channels — use symbols from the REST symbol list for that asset class (for example GET /stocks/symbols for Stocks). For equities, use market-qualified symbols such as US:AAPL. Subscribe only to channels included in your package.
  • Respect connection and symbol limits— close unused connections before opening new ones and stay within your plan's distinct-symbol allowance. The per-subscribe symbol count is a separate server cap (default 500). See Rate limits.

REST quota errors are documented separately on Errors and Rate limits.