Authentication
Every request carries an API key in the Authorization header:
Keys are issued per organization from the dashboard.
Key format
A key is a prefix followed by 32 bytes of randomness encoded in base62 — 51 characters in total:
Every request made with a key is billed against the organization’s wallet.
Only the SHA-256 hash of a key is stored, so the plaintext is shown once at
creation and cannot be recovered afterwards. Lose it and you mint a new one.
The dashboard and the API only ever show the first 12 characters
(nl_live_YxQF), which is enough to tell your keys apart and useless on its
own.
A key carries its organization, its scopes, an optional expiry, its own rate limit, and a last-used timestamp.
Errors
Authentication failures return the standard error envelope with
type: "authentication_error" and HTTP 401.
No key at all:
A key that is unknown, malformed, revoked or expired. The key is echoed back redacted to its first 8 and last 4 characters, so you can tell which key failed without the error log becoming a place credentials leak:
All four causes return the same message. Distinguishing “unknown” from “revoked” would confirm to whoever holds a leaked key that it used to be real.
Scopes
A key can be narrowed to a subset of the API. The available scopes are:
A key created without scopes is unrestricted — that is the default. Narrowing is opt-in, and it is worth doing for any key that leaves your own infrastructure: a key that only transcribes cannot enumerate the catalogue, and a key that only reads the catalogue cannot spend money.
Calling an endpoint your key lacks the scope for returns HTTP 403:
Rate limits
Limits are per key and reset on a rolling one-minute window. The default is
600 requests per minute; a lower or higher limit can be set on each key in
the dashboard. Every /v1 response carries:
Counters are shared across every API instance, so a limit is a limit no matter which server answers.
Exceeding the limit returns HTTP 429:
A request that arrives with no usable key is limited by client IP instead,
at a deliberately low rate — it is on its way to a 401 regardless.