Skip to main content
Errors are returned as JSON with a detail field. Status-code semantics follow HTTP conventions — retry 5xx, don’t retry 4xx (except 429).

Status codes

CodeNameWhenHow to respond
200OKSuccessful inferenceParse body
401UnauthorizedMissing, invalid, or revoked API keyCheck your Authorization header — don’t retry until fixed
422Unprocessable EntityRequest body failed validation (e.g. both resources and bundle empty)Fix payload — don’t retry
429Too Many RequestsRate limit or monthly cap exceededRespect Retry-After; back off
501Not Implementedformat: "us_core" or format: "bundle" requestedSwitch to format: "inferred_list" (default)
503Service UnavailableTransient infra failure (e.g. Clerk JWKS unreachable on /admin/*)Retry with backoff

Shape

{ "detail": "missing API key" }
{
  "detail": {
    "error": "rate_limit_exceeded",
    "limit_per_minute": 60,
    "plan": "starter"
  }
}
{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body"],
      "msg": "request must include `resources` and/or `bundle`",
      "input": {}
    }
  ]
}

Common scenarios

You sent a request without an Authorization: Bearer ... header, or the key has been revoked. Generate a new one from the portal.
You sent { "resources": [] } with nothing else. At least one of resources (non-empty array) or bundle (non-empty FHIR Bundle) must be present. See the Quickstart for a minimal working request.
You exceeded your plan’s per-minute limit. Back off for the number of seconds in the Retry-After header, then retry. If you’re hitting this often, consider upgrading to Starter or Pro.
Your org has used all of its monthly request allowance. The upgrade_url in the response points to your billing page. Usage resets on the 1st of next month (UTC).
format: "us_core" and format: "bundle" are reserved for future use. Use the default format: "inferred_list" (or omit the field entirely).

Retries

For retryable errors (5xx, 429), use exponential backoff. Starting point:
  • 429: respect Retry-After
  • 503: 1s, 2s, 4s, 8s, then give up
Don’t retry 4xx other than 429 — they indicate the request itself is malformed and won’t succeed on retry.

Getting a request ID

Every response includes an x-request-id response header. If you open a support ticket, include that ID — we can trace the exact request in our logs. The same ID also appears inside the response body as meta.request_id for successful /v1/* calls.