Authentication
Bearer keys, the two scopes, and what a 401 does and does not tell you.
Every request carries an API key as a bearer token:
Authorization: Bearer atl_live_7k2m9qr4vx8thn3p_wj6b2yd0fs1gzr4mcqvn8ka3hpx91tThis is the only accepted carrier — it is what an OpenAI SDK sends after only
its base URL and key are changed. There is no query-string key, no api-key
header, and no organization header: your organization is determined by the key.
Two scopes
| Prefix | Scope | Reaches |
|---|---|---|
atl_live_ | inference | /v1/chat/completions, /v1/models |
atl_read_ | read | /v1/usage, /v1/usage/export |
A key is admitted on one surface and refused on the other. Presenting a read key
to the inference endpoint returns 401, exactly as an unknown key would.
Scope is enforced against the stored scope, never the prefix presented. A
caller who rewrites atl_live_ to atl_read_ on a key they hold gets a
401, not a scope change.
See API keys for the format, creation, and revocation.
Failures
{
"error": {
"message": "...",
"type": "authentication_error",
"param": null,
"code": null,
"request_id": "req_01k4v9m2..."
}
}Status 401 for every credential problem, with an identical body: a missing
key, a malformed key, an unknown key, a revoked key, an expired key, and
a wrong-scope key are indistinguishable in the response.
This is deliberate. Telling a caller apart "no such key" from "revoked" turns the endpoint into an oracle for which stolen keys are still worth trying.
When debugging a 401, check the key in the console — its prefix,
revoked_at, and last_used_at — rather than reading anything into the
response body.
A malformed key is rejected on shape alone, before any database read: the key format carries a checksum, so a truncated paste costs no lookup.
Revocation takes effect immediately
There is no cache and no propagation delay. Verification is a single indexed read of the row that revocation just wrote, so the next request presenting a revoked key is rejected.
Rotate by overlap — create, deploy, confirm the old key's last_used_at has
stopped advancing, then revoke. Revoking first means an outage.
Handling keys
- One key per deployed service, labelled with the service name.
- Keep keys in a secret store, never in source. The
atl_live_prefix exists so automated secret scanners can recognise a leaked key. - Use the non-secret prefix as the key's identifier in your own logs.
- A key is shown in full exactly once, at creation. There is no recovery path.