Errors
All errors return JSON with an error field. Some errors include additional fields like required_tier.
The request succeeded. Response body is JSON with the requested data.
Your request had invalid parameters — a missing required field, an out-of-range value, or an unknown query param. Fix the request and retry.
{ "error": "invalid parameter: 'days' must be a positive integer" }The X-Api-Key header was missing or the key is invalid (revoked, malformed, or doesn't exist). Check that you're sending the header correctly and the key is still active.
{ "error": "Missing or invalid API key.", "docs": "https://loris.tools/docs/authentication" }Your key is valid but your tier doesn't have access to this endpoint, symbol, or historical depth. The response includes a required_tier field so you know what to upgrade to.
{ "error": "Your API key does not have access to this endpoint.", "required_tier": "dev", "docs": "https://loris.tools/docs/pricing" }You've exceeded your per-minute rate limit. The response includes X-RateLimit-Limit, X-RateLimit-Remaining: 0, and Retry-After: 1 headers. Back off and retry. See Rate limits for per-tier quotas and a backoff example. Rate limits
{ "error": "Rate limit exceeded", "message": "Too many requests. Please slow down.", "retry_after": 1 }Something went wrong on our end. The response body is intentionally terse — no internal details are surfaced. If this persists, reach out.
{ "error": "internal error" }An upstream data source is temporarily unavailable. This is rare and usually resolves within seconds. Retry with backoff.
{ "error": "upstream unavailable" }A note on 403 vs 404
The API uses 403 when a resource exists but your tier can't access it. It uses 404 when the resource genuinely doesn't exist — unknown symbol, missing data row, malformed path. If you're seeing 403 on a symbol you expect to exist, check your tier and the required_tier field in the response.