Errors
Use HTTP status codes, JSON bodies on REST 429/503, and WebSocket error frames to branch retries, backoff, and user messaging.
REST errors
| Status | Meaning |
|---|---|
400 | Invalid path or query parameters; the message lists the valid values. |
401 | Missing or invalid key. |
403 | Inactive key, a key not entitled for REST, or a plan that leaves out the data. On stocks, ETFs, indices, commodities and bonds the plan case carries "error": "NOT_IN_PLAN" and product, plus market on a stock; other products name themselves in message. |
404 | The route exists but the symbol or resource does not: { "statusCode": 404, "message": "…" }, with an optional error field. |
429 | The per-second limit or the monthly quota; the error field says which, and a quota answer gives resetsAt, when the allowance renews (UTC). |
503 | Usage metering is unavailable, so the request fails closed. |
{
"statusCode": 429,
"message": "rate limit exceeded",
"error": "REST_RATE_LIMIT_EXCEEDED",
"limitRps": 10,
"retryAfterMs": 250
}The per-second 429 also sends Retry-After, and every REST response carries X-RateLimit-Limit and X-RateLimit-Remaining: see Rate limit headers.
WebSocket upgrade errors
Invalid keys and connection caps are refused before any frame is exchanged. Every upgrade status is listed on Connection.
Account connection limit (429)
{
"error": "WS_CONNECTION_LIMIT_EXCEEDED",
"message": "rate limit exceeded"
}WebSocket frame errors
After connect, a failed subscribe returns a type: "error" frame with a machine-readable code. Every code is listed on Errors & troubleshooting.
Symbol limit exceeded
{
"type": "error",
"event": "subscribe_failed",
"code": "SYMBOL_LIMIT_EXCEEDED",
"message": "rate limit exceeded"
}