Skip to content

Errors

Every Public API error uses the same envelope:

{
  "error": {
    "code": "bad_request",
    "message": "Invalid pub_date_from. Use YYYY-MM-DD.",
    "details": null
  },
  "request_id": "req_01J..."
}

error.code is a stable, machine-readable identifier. error.message is for people. error.details is null for simple errors and contains structured context when available. request_id matches the X-Request-ID response header.

Status codes

Status Meaning
400 Malformed request or invalid parameter (e.g. bad date format)
401 Missing or invalid API key
403 API key lacks access to the requested project
404 Project, article, or canonical not found — or outside caller scope
409 Request conflicts with existing state, including an idempotency-key conflict
422 Path, query, header, or JSON body validation failed
429 A per-key or project rate limit was exceeded
503 Requested capability is temporarily unavailable

Not found responses

For privacy and security, 404 can mean either "does not exist" or "not accessible with this API key."

Treat it as "not found in this project for this key."

Validation examples

Invalid date on article search:

{
  "error": {
    "code": "bad_request",
    "message": "Invalid pub_date_from. Use YYYY-MM-DD.",
    "details": null
  },
  "request_id": "req_01J..."
}

Request validation (422)

Validation failures retain the shared envelope. The individual validation issues appear in error.details:

{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed.",
    "details": [
      {
        "type": "missing",
        "loc": ["body", "query"],
        "msg": "Field required",
        "input": {}
      }
    ]
  },
  "request_id": "req_01J..."
}

Each item identifies the invalid input location and validation message. Clients can parse one envelope for both application errors and request validation.

Error codes

Code Typical status
bad_request 400
unauthorized 401
forbidden 403
not_found 404
conflict 409
validation_error 422
rate_limit_exceeded 429
service_unavailable 503

See Rate limits for retry headers on 429 responses.