Errors, Limits & Timeouts

Error format, HTTP status codes, rate limits, and recommended client timeouts

Error response format

All error responses share one body shape:

{
  "error": "BadRequest",
  "message": "Included or excluded answers must be provided"
}

Always log message — it is the actionable part.

HTTP status codes

StatusMeaningTypical causes / handling
200Success
204No contente.g. logout
400Bad requestValidation failures: missing partner_id/secret; age outside 18–125; initial_query outside 3–500 chars; answer type doesn't match the current question; neither included nor excluded provided; choice ids not in the current question; report requested before report_possible; disallowed X-Language; analytics value too large. Fix the request — do not retry as-is.
401UnauthorizedBad partner credentials at login, or an expired/invalid token elsewhere. Mid-conversation this means the session is gone: re-login, re-accept terms, start a new assessment.
403ForbiddenInvalid/revoked API key, domain validation failure, or calling a medical endpoint with the non-upgraded token. Check credentials and the two-token flow.
404Not foundGET /chat before any conversation exists; unknown article id.
429Too many requestsPartner rate limit exceeded (see below). Back off and retry.
5xxServer errorRetry with backoff; if persistent, contact support.

Rate limits (per partner)

Enforced at the gateway per API key:

LimitDefault
Sustained rate2 requests/second
Burst10 requests/second
Daily quota~10,000 requests/day

Notes:

  • These are partner-wide, shared across all of your users — another reason the API must sit behind your own backend, where you can queue/throttle. Actual values are per your contract; treat the above as defaults.
  • The chattiest endpoint is /symptom-search (per keystroke) — debounce it client-side (e.g. 300 ms) and require 2–3 characters before querying.
  • On 429, apply exponential backoff. Do not tight-loop retries.

Recommended client timeouts

Server-side processing budgets per endpoint — set your client timeouts a little above these:

EndpointServer budget
POST /login30 s
POST /initial, POST /chat, POST /step-back, GET /chat30 s
GET /report30 s
GET /symptom-search3 s
GET /articles, GET /article/{id}10 s
GET /terms, POST /terms5 s
POST /analytics, POST /analytics/feedback30 s

Typical latencies are far lower; the chat budget is generous because a single turn can involve NLU and diagnostic-engine calls.

Retry semantics — the important nuance

POST /chat is not idempotent: it advances the conversation. If a chat call times out or the connection drops, do not blindly resend it — the answer may already have been applied, and a resend would be validated against the next question (usually yielding a 400, but don't rely on that).

Safe recovery procedure:

  1. Call GET /chat (read-only) to fetch the authoritative current question.
  2. Compare with what you last rendered:
    • Same question → your answer was not applied; resend it.
    • Different question → your answer was applied; render the new question and continue.

GET endpoints and POST /analytics are safe to retry. POST /step-back has the same non-idempotent caveat as /chat (each call steps back one question).

Operational guidance

  • Token expiry: track expires_in from login and warn users on long pauses; an expired session cannot be resumed.
  • Sequential calls only per conversation: never issue concurrent POST /chat calls on one token.
  • Don't parse debug_messages or build logic on scenario values — both are diagnostic aids, not contract.
  • Monitor your quota: a full consultation is typically 10–25 requests (login, terms ×2, initial, 5–15 chat turns, report, plus searches/articles). Size your expected daily volume against the quota and request an increase if needed.