# Managing API Keys

> Create, rotate, scope, and rate-limit AnyRouter API keys from the dashboard. Track usage per key and revoke compromised keys instantly.


# Managing API Keys

A single shared secret is a liability: you can't tell which app spent what, a leak forces you to break every client at once, and there's no ceiling on the damage a runaway loop can do. AnyRouter API keys fix that — each key is an independent `sk-ar-…` credential with its own name, usage history, expiration, rate limit, and spending cap, so you can scope, monitor, and revoke access one application at a time.

## Overview

The **API Keys** page (`https://anyrouter.dev/dashboard/keys`) is where you create, configure, monitor, and revoke the credentials your applications use to call the AnyRouter API. You can hold as many keys as you need — there is no per-account limit — and every key carries its own configuration and analytics.

- For request authentication mechanics, see [Authentication](/getting-started/authentication).
- For the underlying REST endpoints, see the [Keys API reference](/api-reference/keys).

:::warning
AnyRouter never persists the plaintext form of a key — only a one-way hash used to verify requests. The full secret is shown **once**, at creation. If you lose it there is no recovery path: create a new key and revoke the old one.
:::

## How it works

### Where to find your keys

Open **Keys** in the dashboard sidebar. The page lists every key on your account, including disabled ones, with a card-and-table toggle in the top right. Each key card shows:

- The friendly name you gave the key
- Last-14-day request count and estimated spend
- The "last used" timestamp
- Quick links to that key's logs and usage charts
- An overflow menu (`⋯`) for edit, rename, and delete

Click any card to open the **single-key detail page** at `/dashboard/key/<id>`, which shows the full configuration, recent spend breakdown, and per-model activity.

### The "shown once" rule

Because AnyRouter stores only a hash, treat every secret as unrecoverable the moment you close the reveal dialog:

- Copy the secret to your secret manager immediately after creation.
- Do not paste API keys into chat, email, or screenshots.
- Do not commit keys to source control, even on private branches.
- If you suspect a leak, treat it as confirmed and rotate immediately (see [Rotate without downtime](#rotate-without-downtime)).

The masked prefix on the keys page (e.g. `sk-ar-7d2f***`) is safe to share when coordinating with teammates or filing support tickets — it identifies the key without exposing the secret.

### Configuration fields

The create dialog (and the edit dialog) expose these controls.

| Field | What it does |
| --- | --- |
| **Name** | Internal-only label, never sent with requests. We recommend one name per `(app, environment)` — e.g. `web-app-prod`. |
| **Expiration** | `Never` (default), quick-picks (`7 days`, `30 days`, `90 days`), or an exact date-time. After expiry the key returns `401 Unauthorized` until replaced. |
| **Rate limit (RPM)** | Caps requests per minute at the AnyRouter edge. Requests over the cap return `429 Too Many Requests` with a `Retry-After` header. |
| **Credit limit** | Spend ceiling. Choose a dollar **Limit** and a **reset cadence** (`Daily`, `Weekly`, `Monthly`). The cap is measured over a rolling window, so a key left with no cadence is still measured over 30 days like `Monthly` — it is not a lifetime cap. Over the limit, requests return `402 Payment Required` until the window rolls. |
| **Include BYOK usage** | Off by default. On, BYOK-routed requests count toward this key's credit limit even though they don't consume AnyRouter credits — useful for team-wide spend budgeting. |

:::note
There is no token-per-minute (TPM) cap on individual keys — TPM is enforced upstream per model. If you need a TPM-style cap, set a tight RPM and pair it with a credit limit.
:::

### Per-key analytics

Opening a key's detail page (`/dashboard/key/<id>`) gives you a dedicated view:

- **Headline metrics** — total spend and request count for the last 24 hours, 7 days, and 30 days; the "last seen" timestamp with relative formatting (`2m ago`); created-at and expires-at.
- **Spend over time** — a bar chart of daily spend for the trailing 14 days. Hover a bar for the exact figure and request count.
- **Top models** — a leaderboard of the models this key called most, with per-model request counts and spend. Use it to spot unexpected model usage, confirm a migration is complete, or find repeated prompts worth [caching](/features/caching).
- **Recent errors** — the most recent failed requests with timestamps, model, status code, and message. The fastest way to debug a key that started rejecting requests (common causes: `402` credit-limit hits, `429` rate-limit hits, revoked downstream credentials).

The **Logs** link at the top jumps to the full [request log](/features/request-logs) filtered to this key.

### Restrictions

- **Allowed models.** Restrict a key to a subset of the catalog — useful for budget-approved model lists, compliance policies, or a "preview" key that can call experimental models without risking production. A request for a disallowed model returns `403 Forbidden` and is **not** charged.
- **Network restrictions.** IP allow-lists and `Referer` checks are not currently exposed on individual keys. If your security model depends on them, raise it with us. In the meantime, rely on per-key rotation and credit limits, and route outbound traffic through a fixed egress (NAT gateway, VPN) if you need source-IP attribution.

## Configure

### Create a key

1. Click **Create key** in the top right of the API Keys page.
2. Set the **Name**, and optionally an **Expiration**, **Rate limit**, **Credit limit**, and **Include BYOK usage** (see [Configuration fields](#configuration-fields)).
3. Click **Create key**. The dialog switches to a one-time reveal panel showing the full secret.
4. **Copy the secret now** — the single click-to-copy button puts it on your clipboard. Paste it into your secret manager or `.env` before closing.

After closing, the new key appears in the list with a masked `sk-ar-<prefix>***` label. The rest of the secret is gone from the dashboard forever.

### Edit a key

Open the overflow menu (`⋯`) and choose **Edit** to change expiration, credit limit, reset cadence, or the BYOK-in-limit toggle. **Rename** is a separate action because it's the most common edit and touches no limits. Changes apply within seconds — no application restart needed.

The one thing that cannot be changed on an existing key is the owner or workspace
the key belongs to. To move a key between those, issue a new one.

### Rotate a key in place

Use **Rotate** when a key's secret needs replacing but its identity should stay
put — a suspected leak, a key that ended up somewhere you don't control, or just
a routine swap. The key keeps its id, name, credit limit, restrictions, usage
history and every dashboard link; only the secret changes. Anything still holding
the old secret starts getting `401 Unauthorized` immediately, with no overlap
window.

The new secret is shown once, right after the rotate, with a copy button. After
that you can still fetch it on demand with **Reveal** (keys created after secure
storage landed), but it is never displayed again on its own.

### Rotate without downtime

In-place rotation is immediate by design — the right behavior for a suspected
leak, but it means any service still holding the old secret starts failing. When
you need a handoff with zero failed requests, run two keys side by side instead.

1. **Issue** a new key with the same configuration (name it `app-prod-v2`).
2. **Deploy** the new key alongside the old one. Most secret managers let two values coexist; if not, deploy the new key first and roll forward.
3. **Verify** the new key is serving production traffic — the card's "Last used" timestamp updates within seconds of the first request.
4. **Revoke** the old key once its traffic drops to zero. Wait at least one full request cycle (typically a few minutes) before deleting.

This sequence guarantees there is never a moment when neither key is valid, so in-flight requests never hit a `401`. The cost is that the old key stays live for the length of the handoff — exactly the window you do not want if you are rotating because of a leak.

:::warning
**Compromise rotation.** If you suspect a leak, skip the gradual handoff and revoke immediately. This fails in-flight requests on the leaked key, but every extra second it stays valid is more time for an attacker to drain your credits. Burnt requests are recoverable; drained credits are not.
:::

### Revoke and delete

Two ways to take a key out of service:

- **Disable** — flip the toggle in table view or use **Disable** in the overflow menu. The key is preserved but rejects all requests with `401 Unauthorized`, and can be re-enabled later. Good for temporary suspensions or incident response.
- **Delete** — choose **Delete**, confirm the prompt. The key is permanently removed. Historical usage is retained for billing and audit, but the secret can never be re-validated.

Both take effect within seconds at the edge. Already-streaming responses are allowed to complete — we do not tear down in-flight connections — but no new requests are accepted. For an instantaneous kill switch during an active incident, pair **Disable** with a credit-limit drop to `$0.01` so anything that slips through propagation is still caught.

## Best practices

- **One key per application per environment.** A separate key for each `(app, env)` pair gives per-application spend visibility, blast-radius isolation, and independent rotation. Three apps across two environments means six keys: `web-prod`, `web-staging`, `mobile-prod`, `mobile-staging`, `batch-prod`, `batch-staging`.
- **Never reuse keys across environments.** A shared key means a misconfigured staging deploy can drain production credits, and a leaked staging key compromises production. A second key costs nothing.
- **Set a credit limit on every key.** Pick a comfortable ceiling (e.g. 3× current peak) with a monthly reset. You won't notice it in normal operation, but you'll be glad it's there the day a bug spawns an infinite loop.
- **Monitor spend trends.** The per-key spend chart shows 14 days. A step-change that doesn't match a deploy is worth investigating before the bill arrives. For automated alerting, poll the [Keys API](/api-reference/keys) daily.
- **Alert on sudden spend.** Combine a hard credit limit (`$200/mo`) with a tighter soft alert (`$150`) — the limit catches catastrophic runaway, the alert catches gradual drift.
- **Keep management keys separate.** A small number of accounts have **Management** keys (labelled with a **Management** badge) that call administrative endpoints. Treat them like root credentials: one per administrator, never shared, short rotation cadence, never used by an application, and stored in a separate vault.
- **Off-board promptly.** When a teammate leaves, revoke their management key the same day and rotate or transfer any application keys they created.

## Frequently asked questions

:::details{summary="Why is my last-used timestamp not updating?"}
Verify the application sends the `Authorization: Bearer sk-ar-…` header on every request, and that the prefix matches the dashboard. A mismatched prefix means the request is hitting a different key — check for typos and stray whitespace.
:::

:::details{summary="Why am I getting 401 after a successful create?"}
The key was likely disabled, expired, or deleted — check its status. Also confirm you copied the full secret; truncated secrets fail validation silently.
:::

:::details{summary="Why am I getting 402 mid-month?"}
The key hit its credit limit. Raise the limit in **Edit**, lower the reset cadence, or wait for the reset.
:::

:::details{summary="Why am I getting 429 at modest volumes?"}
Check the key's per-minute rate limit in **Edit**. AnyRouter also enforces account-wide and per-model rate limits — the key cap is one of several gates.
:::

:::details{summary="Can I share a key across two workspaces?"}
No. Keys are owned by exactly one workspace. Create one key per workspace.
:::


## Related

- [Authentication](/docs/getting-started/authentication.md)
- [Bring Your Own Key (BYOK)](/docs/features/byok.md)
