Skip to navigation

Authentication

Bearer API keys, scoped to an organization.

Every request carries an API key in the Authorization header:

Authorization: Bearer nl_live_...

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:

nl_live_YxQFoF6p2xKvStMzWhYhwPMNSlEnWTwzYL83OJCbyTo
└──────┘└─────────────────────────────────────────┘
prefix 43 base62 characters (32 random bytes)

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:

{
"error": {
"message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer nl_live_...). You can find your API key at https://platform.nyra-labs.com/api-keys.",
"type": "authentication_error",
"param": null,
"code": "missing_api_key"
}
}

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:

{
"error": {
"message": "Incorrect API key provided: nl_live_…byTo. You can find your API key at https://platform.nyra-labs.com/api-keys.",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}

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:

ScopeGrants
transcriptions:writePOST /v1/audio/transcriptions
models:readGET /v1/models, GET /v1/models/{model}

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:

{
"error": {
"message": "You have insufficient permissions for this operation. Your API key is missing the 'transcriptions:write' scope. Grant it at https://platform.nyra-labs.com/api-keys, or use a key with no scope restrictions.",
"type": "permission_error",
"param": null,
"code": "insufficient_scope"
}
}

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:

HeaderMeaning
x-ratelimit-limit-requestsRequests allowed in the window
x-ratelimit-remaining-requestsRequests left in the current window
x-ratelimit-reset-requestsTime until the window resets, e.g. 43s
retry-afterSeconds to wait. Sent on 429 only

Counters are shared across every API instance, so a limit is a limit no matter which server answers.

Exceeding the limit returns HTTP 429:

{
"error": {
"message": "Rate limit reached for requests. Please slow down or contact support to raise your limit.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
}
}

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.