API Docs/Errors

Errors

Every non-2xx response from the Keeper Health API follows the same JSON envelope. Branch your client code on error.type, not on error.message — the type is a stable machine-readable slug, while messages may be reworded for clarity over time. See Code Examples for end-to-end clients that handle these errors.

Error envelope

JSON
{
  "error": {
    "type": "validation_error",
    "message": "One or more fields in the request body are invalid.",
    "details": [
      {
        "loc": ["body", "npis"],
        "msg": "npis exceeds the per-request limit of 1000",
        "type": "value_error"
      }
    ]
  }
}
FieldTypeDescription
error.typestringStable machine-readable slug, e.g. validation_error. Branch on this.
error.messagestringShort human-readable summary. Safe to log and surface.
error.detailsarrayOptional. Structured field-level information. Present on validation errors; omitted otherwise.

Error types

error.typeHTTPMeaning
validation_error400A request field failed validation. details lists each failing field. See Create Search and Rate Limits for the hard per-request limits.
invalid_request400The request body is missing, not valid JSON, or the Idempotency-Key header is malformed. See Create Search → Idempotency.
unauthorized401The API key is missing, malformed, or invalid. See Authentication.
forbidden403The API key has been revoked or the organization is inactive. See Authentication → Help.
not_found404The job_id does not exist, or belongs to a different organization. See Get Search Status.
rate_limited429You've exceeded the rate limit. A Retry-After header is set. See Rate Limits.
enqueue_failed503The job could not be enqueued. Transient — safe to retry. Retry-After is set.
service_unavailable503A backend dependency is temporarily unavailable. Safe to retry. Retry-After is set.
internal_error500Something broke on our end. Log the response and contact support.

The Retry-After header

429 and 503 responses include a Retry-After header with the number of seconds to wait before retrying. Honor it rather than inventing your own backoff schedule. See Rate Limits for details.

Retry-safe vs. not retry-safe

Safe to retry (ideally with an Idempotency-Key so you don't create duplicate jobs — see Code Examples for language-specific retry loops):

  • 503 service_unavailable / 503 enqueue_failed — honor Retry-After
  • 429 rate_limited — honor Retry-After
  • Network errors, connection drops, timeouts

Not retry-safe — fix the request first:

  • 400 validation_error / 400 invalid_request — the request is malformed. Retrying unchanged produces the same 400.
  • 401 unauthorized — your key is wrong. Do not retry until fixed.
  • 403 forbidden — your key is revoked or your organization is inactive.

A note on job failures

A job that ends in a terminal failure state (status: "failed" in the body of a GET /v1/searches/{job_id} response) still returns HTTP 200 — the status check itself succeeded; the job is just done and didn't succeed. Read the status field in the JSON body, not the HTTP status code, to detect terminal job failure. See Get Search Status for details.

See also

Keeper Health API v1 · Questions? company@keeperhealth.com