Authentication
Every request authenticates with a LunaRoute API key (lr_…). Prefer a header:
| Header | Notes |
|---|---|
LUNAROUTE-API-KEY: lr_… |
Recommended. Used by the CLI and supported harnesses. |
Authorization: Bearer lr_… |
Accepted when the value is lr_-prefixed. |
x-api-key: lr_… |
Accepted when the value is lr_-prefixed. |
Precedence is LUNAROUTE-API-KEY, then Authorization: Bearer, then
x-api-key. A standard header that carried an lr_ key is stripped before the
request is forwarded upstream, so your LunaRoute key is never sent to a model
provider.
Only lr_-prefixed values in Authorization / x-api-key are treated as
LunaRoute auth. Any other value (for example sk-…) is left intact and passed
through as a bring-your-own-key (BYOK) upstream credential.
Project scoping
Section titled “Project scoping”To attribute usage to a project, add:
LUNAROUTE-PROJECT-ID: my-projectProject IDs are free-form strings up to 128 characters. See Projects & organizations.
Errors
Section titled “Errors”| Status | error.code |
Meaning |
|---|---|---|
| 401 | MISSING_LUNAROUTE_HEADER |
No key on the request. |
| 401 | INVALID_API_KEY |
Key is unknown or revoked. |
| 403 | ORGANIZATION_SUSPENDED |
The key is valid but the org is suspended. |
| 503 | SERVICE_UNAVAILABLE |
Auth backend temporarily unavailable — retry. |
| 400 | PROJECT_ID_TOO_LONG |
Project ID exceeds 128 characters. |
A backend outage returns 503 SERVICE_UNAVAILABLE, not 401 — a healthy key is
never reported as invalid because of an internal failure.