API keys
Create keys, limit what each one can spend and call, and rotate or revoke them without downtime.
API keys authenticate your requests and draw on your account balance. You can create as many as you like and give each one its own limits. All keys share the same balance.
Create a key#
Open API keys
Go to API keys in the dashboard and click New key.
Name the key and pick a channel group
Name the key after where it will run, such as
checkout-prodoreval-runner. Leave Channel group on Auto — best available unless you need every request from this key to run in one specific group. See Channel groups.Set limits (optional)
Open Limits & restrictions to cap spend, rate, concurrency, models or lifetime. Every option is described below, and you can change all of them later.
Copy the key
Click Create. The full key appears once, in a banner at the top of the page. Copy it, or click Use in tools… to set up Claude Code, Codex CLI and other clients with it. After you click Done, only the first characters of the key are shown, for example
lr-a1b2c3….
Keys are shown once
Lovely Router stores only a hash of each key. If you lose a key, revoke it and create a new one.
Key options#
| Option | Default | What it does |
|---|---|---|
| Name | — | Label shown in the key list and in Logs. Up to 60 characters. |
| Channel group | Auto | Runs every request from this key in one channel group. Auto picks the best available group per request. Set at creation only. |
| Spend limit (USD) | No limit | Most the key may ever spend, in whole dollars, across model requests, tool runs and browser runs. It is a lifetime cap, not a monthly budget. |
| Expires on | Never | The key stops working after the end of this day, in your browser's time zone. |
| Requests per minute | Unlimited | How many model requests the key may start per minute. |
| Max concurrent requests | Unlimited | How many model requests the key may have in progress at once. A long stream counts until it ends. |
| Only allow specific models | All models | Allow-list of models the key may call. Aliases such as claude-sonnet-5-5 count as the model they resolve to. |
The key list shows each key's group, limits, total Spent and Last used time.
What happens when a limit is hit#
A refused request is not billed and does not appear in Logs. The body uses the format of the API you called.
| Situation | Status | Anthropic type | OpenAI type | Message |
|---|---|---|---|---|
| Key expired | 401 | authentication_error | authentication_error | This API key has expired |
| Key revoked | 401 | authentication_error | authentication_error | Invalid or revoked API key |
| Model not on the allow-list | 403 | permission_error | permission_denied | This API key is not allowed to use 'gpt-6.1-sol'. |
| Spend limit reached | 402 | billing_error | insufficient_quota | This API key has reached its spend limit. |
| Requests per minute or concurrency reached | 429 | rate_limit_error | rate_limit_exceeded | This API key has reached its rate or concurrency limit. |
Gemini-format requests get the same status codes in Gemini's error format. A 429 from a key limit carries a Retry-After header with the seconds to wait. Here is the spend-limit error in both formats. Every other body and the retry advice are in Errors.
{
"type": "error",
"error": {
"type": "billing_error",
"message": "This API key has reached its spend limit."
}
}Which limits apply to tools and browser runs#
| Limit | Model requests | Data tools and browser agent |
|---|---|---|
| Expiry and revocation | Yes | Yes |
| Spend limit | Yes | Yes |
| Requests per minute | Yes | No |
| Max concurrent requests | Yes | No |
| Model allow-list | Yes | No |
The spend limit is checked before each request starts. A model request already in progress always finishes, so the key's total can end slightly above the limit. A tool or browser run reserves its maximum cost up front, so it is refused with 402 if that maximum would take the key past its limit.
Edit a key#
Click Edit on a key to change its name, spend limit, expiry date, rate and concurrency limits, or model allow-list. Changes apply to the next request. Clearing a field removes that limit.
To move a key to a different channel group, create a new key in that group and rotate to it.
Revoke a key#
Click Revoke, then Confirm revoke. The key stops working on the next request, and revoking can't be undone. A revoked key stays in the list, greyed out, with its spend history, and its requests stay in Logs.
Rotate a key#
Replace a key without downtime:
- Create a new key with the same group and limits.
- Deploy the new key to your app or secrets manager.
- Wait until the old key's Last used time stops changing.
- Revoke the old key.
Rotate on a schedule, after someone with access leaves, and immediately if a key may have leaked.
Use a key in your tools#
Click Use in tools on any key for ready-made setups for Claude Code, Codex CLI, Gemini CLI, Cherry Studio, DeepChat and AionUI, with one-click import where the app supports it. See Use with your tools.
Best practices#
- One key per app and environment. Separate keys for production, staging, CI and your laptop keep spend visible per key, and let you revoke one without touching the others.
- Cap keys that run unattended. Agents, batch jobs and CI pipelines can loop. A spend limit bounds the damage, and a requests-per-minute limit slows a runaway loop.
- Allow only the models a key needs. A key for a summarisation job doesn't need the most expensive model.
- Expire temporary keys. Give demos, contractors and evaluations a key with an expiry date instead of remembering to revoke it.
- Keep keys server-side. Never ship a key in front-end or mobile code. See Keep keys safe.