ReferenceErrors & rate limits

Errors & rate limits

How the API reports failures and throttling, and what to do about each.

Audience: developers handling error responses. What you will accomplish: parse error bodies and implement correct backoff.

The error shape (problem+json)

All errors share one shape — application/problem+json (RFC 9457):

{
  "type": "https://errors.chat-bot/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "Question cannot be empty",
  "correlation_id": "…",
  "errors": [{ "field": "q", "message": "..." }]
}

errors[] is present on validation failures and names the offending field. 5xx bodies never include internal details — quote the correlation_id instead.

Status codes

StatusMeaningWhat to do
400Bad request (e.g. invalid X-User-Id, blocked input)Fix the input.
401Missing/invalid X-API-Key (ingest)Provide a valid key.
404Unknown doc_idCheck the id.
422Validation errorSee errors[] for the offending field.
429Rate limitedBack off (see below).
500Server errorRetry later; quote correlation_id. 5xx bodies never include internal details.

Rate limits

The default limit is 60 requests/minute per client IP. Every response includes:

HeaderMeaning
X-RateLimit-LimitTotal requests allowed in the window.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetWindow reset time (epoch seconds).

On a 429, you also get a Retry-After header (seconds).

Backoff pseudocode

on response:
  if status == 429:
    wait(seconds = Retry-After)
    retry
  else if X-RateLimit-Remaining is low:
    slow down upcoming requests

Verify your result

  • Verify: Your client reads status and, on 422, the errors[] array.
  • Verify: On 429 you wait exactly Retry-After seconds before retrying.
  • Verify: On 5xx you log and quote the correlation_id rather than expecting detail in the body.

Common mistakes and fixes

  • Retrying a 429 immediately → respect Retry-After; a tight retry loop stays throttled.
  • Expecting detail in a 5xx body → there is none by design; use the correlation_id.
  • Behind a proxy and getting throttled globally → the operator must configure TRUSTED_PROXIES so your real client IP is used, not the proxy’s.