Error codes
Every error response has the same shape: a machine-readable error code and a human-readable message. The code is stable — build your retry and alerting logic against it, not the message text.
Response shape
{
"error": "snake_case_code",
"message": "Human readable string"
}Codes
| Code | Status | Meaning | Retry |
|---|---|---|---|
company_not_found | 404 | No company exists for the supplied company number. The number is validated before lookup, so this means the company genuinely does not exist at Companies House. | Do not retry — check the company number. |
officer_not_found | 404 | Companies House confirms the supplied officer id does not exist. Returned by the officer-appointments endpoint. | Do not retry — check the officer id. |
invalid_query | 422 | The search request was malformed. The q parameter is required and must be at least 2 characters. | Do not retry without fixing the query. |
invalid_officer_id | 422 | The officer id is empty, over 64 characters, or contains a character outside the set [A-Za-z0-9_-]. | Do not retry without fixing the id — it must be 1–64 characters from [A-Za-z0-9_-]. |
rate_limit_exceeded | 429 | Your API key has used its monthly tier quota. This is about your usage, not the upstream registries. Quota is per user, so regenerating your key does not reset it. | Retry after the monthly reset — the Retry-After header gives the seconds remaining. Or upgrade your tier. |
upstream_capacity | 429 | The shared Companies House budget is exhausted, so the request was shed — either proactively by the outbound budget limiter or by a reactive upstream 429. Returned by the entity, risk, and officer-appointments endpoints alike. Distinct from rate_limit_exceeded — this reflects the shared registry being saturated, not your usage. Lower tiers are shed first under sustained pressure. | Retry after the short interval in the Retry-After header (seconds, while the budget refills). |
risk_tier_required | 403 | The /risk endpoint (and embedded risk_signals on the entity endpoint) requires a Growth or Enterprise key. | Do not retry on a Free key — upgrade your tier first. |
appointments_tier_required | 403 | The officer-appointments endpoint requires a Growth or Enterprise key. Free keys are not entitled. | Do not retry on a Free key — upgrade your tier first. |
upstream_unavailable | 503 | The search endpoint could not be served because the Companies House upstream is unavailable. | Retry after the interval given in the Retry-After response header. |
Partial responses are not errors
An unavailable upstream source never fails an entity request. You receive a 200 with the failure recorded in sources_failed, and — for risk signals — with affected flags listed under indeterminate and score_is_floor set to true. See the risk-signals page for how to interpret that.
upstream_capacity vs rate_limit_exceeded
Both return 429, but they mean different things. rate_limit_exceeded is your key's monthly quota — only you are affected, and the fix is to wait for the reset or upgrade. upstream_capacity is the shared Companies House budget being exhausted — everyone is affected, and the fix is to retry after the short Retry-After interval (seconds, not the monthly reset).