Guide

Errors

CostAPI's error envelope format and every error code you may see in the wild.

Error envelope

Every non-2xx response uses the same JSON shape:

{
  "error": {
    "code": "UPPER_SNAKE_CODE",
    "message": "Human-readable message.",
    "status": 422,
    "request_id": "c0a8012e-7b2c-4e1a-9b8f-2f4f7d3c1a55",
    "suggestion": "What to do about it.",
    "doc_url": "https://docs.aethar.dev/errors/<slug>"
  }
}

Always check error.code, not the message string — messages may change between versions, codes are stable. Include request_id in any support ticket — we log every request and can trace it end-to-end.

Validation errors (422) additionally include an errors array with per-field details.

Auth and rate-limit codes

MISSING_API_KEY — 401, add the X-API-Key (or X-RapidAPI-Key) header.

INVALID_API_KEY — 401, key value not recognised.

SCOPE_DENIED — 403, your plan doesn't cover this endpoint. Most common on /v1/intelligence/* called from Free-tier keys.

RATE_LIMIT_EXCEEDED — 429, daily quota exhausted. See the Rate Limits guide.

Request-shape codes

VALIDATION_ERROR — 422, request failed Pydantic validation. Check the errors array for field-level details (e.g. too_short, missing, value_error).

CITY_NOT_FOUND — 404, the fuzzy matcher couldn't resolve the city name. Try the canonical spelling (e.g. Munich not München) or include an ISO country code to disambiguate.

COUNTRY_NOT_FOUND — 404, the country parameter didn't resolve to an ISO 3166-1 alpha-2 code or a known country name.

METRO_NOT_FOUND — 404, the US metro string didn't map to a BEA MSA. Use the canonical MSA name (e.g. New York-Newark-Jersey City, NY-NJ-PA).

NO_DATA_AVAILABLE — 404, a known city/country exists but no upstream source publishes the requested index for the requested period. Try a neighbouring city or a coarser aggregation.

SERIES_OUT_OF_RANGE — 422, requested HICP/CPI period predates the earliest vintage we ship. Broaden the date window.

Server codes

UPSTREAM_DATA_ERROR — 502, Eurostat, BEA, OECD, or another source file is unavailable or malformed. We surface this rather than serving stale data. Retry after a few minutes.

INTERNAL_ERROR — 500, unexpected server error with a request_id. Retry once; if it persists, check https://status.aethar.dev or email [email protected] with the request_id.

Retry policy

4xx errors other than 429 should NOT be retried — they're client bugs, retrying won't fix them.

429, 502, and 500 errors should be retried with exponential backoff (1s, 2s, 4s, 8s, 16s). Give up after 5 attempts and surface the request_id to the caller.