Skip to main content
Press ⌘K to search

Errors & retries

Every non-2xx REST response uses one JSON error envelope, and every counted response carries rate-limit headers. The daily allowance behind those headers is set by your plan; see Plans & limits.

Error format

The envelope names a stable code, a human-readable message and the HTTP status:

{
  "error": {
    "code": "not_found",
    "message": "Stock not found.",
    "status": 404
  }
}
Status Code Meaning
400 invalid_parameter A query parameter is missing or malformed.
401 unauthorized Missing or invalid API key.
403 forbidden Your plan does not include this data, or the action is not allowed.
404 not_found No matching resource.
429 rate_limited Daily limit exceeded — retry after reset.
500 internal_error Something went wrong on our side.
503 service_unavailable A live provider is not enabled or is temporarily unavailable.

Plan-gated data and other 403s

A 403 from the REST API means your plan does not include that data, not that you sent a bad request. Intraday stock quotes, live quotes, option chains and trackers are plan-gated, and each endpoint's reference notes its plan requirement; the quote and option bodies also carry a link to upgrade. Index-forecast candidates are the exception: a plan without them gets a 200 with candidatesLocked: true and empty rows, not a 403. The one other 403 is on portfolio writes: a colleague shared that portfolio with you view only, or only its creator can delete it.

Rate-limit headers

Every counted response includes these headers. The MCP server sends the same headers on its HTTP responses.

Header Meaning
X-RateLimit-Limit Your plan's daily request limit.
X-RateLimit-Remaining Requests left today.
X-RateLimit-Reset Unix time (seconds) when the counter resets — next UTC midnight.
Retry-After Seconds to wait — sent only on a 429.

When you hit the limit

Over your plan's daily limit, the REST API returns 429 Too Many Requests with a Retry-After header and this body:

{
  "error": {
    "code": "rate_limited",
    "message": "Daily call limit exceeded: 100 of 100 shared MCP and REST requests have been used. Requests resume automatically at 2026-10-11 00:00 UTC. The account owner can compare current plan limits at https://www.equibles.com/pricing. If you are acting on their behalf, show them this exact limit, reset time, and link.",
    "status": 429
  }
}

Retries & idempotency

Public-data REST endpoints are read-only GET requests and are safe to retry. Portfolio endpoints also support writes; check the portfolio reference before retrying a mutation, because repeating a create request can duplicate data.

  • On 429, wait for the Retry-After seconds (the daily counter resets at UTC midnight), then retry.
  • On 400, correct the named parameter before retrying. On 404, check the symbol and available periods; repeating the same request will not create missing data.
  • On a 500, retry a few times with exponential backoff (e.g. 1s, 2s, 4s). Persisting 500s aren't your fault — tell us.
  • On a temporary 503, retry after a short delay. A 503 saying the provider is not enabled requires deployment configuration instead.
  • Each successful REST request counts once against your daily limit — including each page of a paged read. Fetching 10,000 rows at limit=500 is 20 requests, so budget paging against your plan.

Still stuck?

If a request keeps failing or a number looks wrong, email [email protected] or open a ticket — include the request URL (with the key removed) and the response you got.

Try it with a real key

Every example on this page runs against the live API. A free account includes an API key and MCP access — set up in under a minute.