Skip to content

Errors

Every error has the same shape and an HTTP status that matches it:

{
"error": {
"code": "invalid_request",
"message": "\"limit\" number must be less than or equal to 500.",
"details": { "param": "limit" }
}
}
  • code is stable. Branch on it, not on message.
  • message is for people and may change wording.
  • details is optional. For parameter errors it names the offending param.
Status code When What to do
400 invalid_request A parameter is unknown, malformed, out of range, or a cursor was not issued by the API. Fix the parameter named in details.param.
401 authentication_required No bearer token was sent. Send Authorization: Bearer <token>.
401 invalid_token The token is invalid, expired or revoked. Create a new token at tapetide.com/settings.
404 not_found The symbol, index or document does not exist. Look the symbol up with GET /v1/stocks?q=.
404 route_not_found No such path. Check the path against the reference.
405 method_not_allowed A method other than GET (or OPTIONS). The API is read-only.
429 rate_limited Per-minute burst cap reached. Wait Retry-After seconds.
429 quota_exhausted Your plan’s daily or monthly quota is used. Wait until X-RateLimit-Reset, or upgrade.
500 tool_error The request reached a dataset that could not answer it. Retry once; report it if it persists.
500 internal_error An unexpected failure. Retry with backoff.
502 upstream_unavailable A data dependency was briefly unavailable. Retry with backoff.
503 service_unavailable Tapetide is briefly unavailable. Wait Retry-After seconds.

Only a 200 costs a request unit. Every error above is free, including 429.

Retry 429, 500, 502 and 503. Do not retry 400, 401, 404 or 405 without changing the request.

import time, requests
def get(session, url, attempts=4):
for i in range(attempts):
r = session.get(url, timeout=30)
if r.status_code not in (429, 500, 502, 503):
return r
wait = int(r.headers.get("Retry-After", 2 ** i))
if r.status_code == 429 and r.json()["error"]["code"] == "quota_exhausted":
return r # waiting will not help within this run
time.sleep(min(wait, 60))
return r