Skip to content

Why was my API key rejected?

The API returns 401 invalid_api_key or 401 authentication_required, or a 403 insufficient_scope after the key authenticated. The 401 message is the same opaque string on both paths by design — the server never discloses whether a key exists, only whether the request as-presented is authorized.

API keys are bound to the region they were issued in. The key prefix encodes the region:

  • ah_sk_us_… only works against api-dev.us.autohost-dev.uk.
  • ah_sk_eu_… only works against api-dev.eu.autohost-dev.uk.

A wrong-region request returns 401 invalid_api_key. Pick the host that matches the prefix:

Terminal window
# Correct
curl https://api-dev.us.autohost-dev.uk/v1/me \
-H "Authorization: Bearer ah_sk_us_test_..."

For the region rules, see Where is my data hosted?.

Keys are also bound to a mode (test or live). The two modes are isolated databases. A test key cannot read or write live-mode resources, and vice versa.

If you mix modes by accident (storing a test key as your production secret), you see “vanishing data”: verifications created against one mode return 404 not_found to the other mode’s key.

Each key carries a list of scopes (applicants:read, sessions:write, etc.) that gate which routes it can call. A request to a route the key does not have the scope for returns 403 insufficient_scope, and the error body’s details.required_scope field names the missing one.

Revoked keys are rejected immediately on every request with no grace window. Expired keys are rejected after their expiresAt timestamp passes. Keys created without an expiry never expire.

  1. Read the key prefix — confirm region and mode match the endpoint.
  2. Open Developers -> API keys in the matching console region and confirm the key’s status is active with the scopes you need.
  3. If revoked, generate a fresh one and rotate it through your secrets manager. If the scopes are wrong, generate a new key — scopes are not editable. See Rotate an API key for the zero-downtime swap.

Confirm the header is Authorization: Bearer <key> with a single space. Missing whitespace returns 401 authentication_required. If the key looks right and the rejection looks wrong, include the X-Request-Id from the response in your support ticket.