Errors
HTTP status codes and error payload shapes returned by the Public API.
The API returns plain JSON error bodies. There's no envelope beyond the fields shown below — check the HTTP status code first, then read error (and required, where present) to decide how to react.
401 — unauthorized
Returned when the Authorization header is missing, malformed, or the bearer token doesn't verify (unknown/revoked/expired API key, or an OAuth token that fails signature, issuer, or audience checks). The response also carries a WWW-Authenticate: Bearer header.
{
"error": "unauthorized",
"reason": "API key is unknown, revoked, or expired."
}Other reason values you may see: "Missing Authorization header.", "Authorization header must be a Bearer token.", "Invalid bearer token: <verification detail>", "Token audience is missing or does not match this API.".
403 — insufficient scope
Your token is valid, but doesn't carry the scope the endpoint requires.
{
"error": "insufficient_scope",
"required": "accounting:write"
}required is always a single scope name from the scope catalog — request it (or a key/token with it already granted) and retry.
404 — not found
Returned for any path/method combination that isn't a real endpoint on this gateway — including internal platform procedures that exist but were deliberately not exposed here. There is no partial or fuzzy matching: check the API Reference for the exact path and HTTP method.
HTTP/1.1 404 Not Found
Not found502 — bad gateway
Returned only by the hmrc.* group, when the request reaches us correctly (authenticated, correctly scoped) but the upstream HMRC filing service we forward it to is unreachable.
{
"error": "bad_gateway",
"message": "HMRC service unreachable: <reason>"
}This reflects an outage or connectivity issue on our side reaching HMRC, not a problem with your request — retry with backoff. See HMRC compliance for the current status of that group.
429 — not yet enforced
The API does not currently rate-limit requests. 429 Too Many Requests is reserved for future use — don't rely on its absence today as a guarantee it won't appear later; a client that could reasonably hit high request volumes should still back off on repeated failures and space out retries.
Server errors
Unhandled server-side failures are logged and surface as a plain non-JSON 500 response. If you see one consistently for a request that looks correct per this documentation, it's a bug on our side — the shapes above are the only errors you should need to handle in normal operation.