Issue and scope an API key
Mint a key with its own budget, rate limits and model allowlist.
An API key is what an application presents to the gateway’s /v1/* endpoints.
It carries its own budget, rate limits and model allowlist, and it is the level
at which spend is attributed.
Before you start: decide who the key belongs to. A key bound to a user, team or organization inherits that entity’s budget ceiling. A key bound to nothing is governed only by its own limits — which is occasionally what you want, and more often an oversight.
Steps
1. Open /api-keys.
The list shows every issued key with its owner, current spend, budget and status. The token column is masked — the full value is never displayed again after creation.

2. Click Create Key. You land on /api-keys/create.

3. Fill the form.
| Field | Notes |
|---|---|
| Key Name | Required. Shown throughout the console and in spend attribution. Use something that identifies the consuming application, not the person who created it. |
| Alias (optional) | A stable secondary identifier. Useful when you rotate a key and want reporting continuity. |
| Max Budget ($) | Hard ceiling for this key. Leave empty for no key-level cap — the key is then bounded only by the user/team/org levels above it. |
| Duration | Daily, Weekly or Monthly. Determines when the spend counter resets. Without a duration the budget is cumulative and never resets. |
| RPM Limit | Requests per minute. |
| TPM Limit | Tokens per minute. |
4. Click Create Key.
Copy the key now. The plaintext key is returned exactly once, at creation. It is stored hashed, so nobody — including an instance-tier administrator — can retrieve it later. If it is lost, delete the key and issue another.
After creation
- The key appears in
/api-keyswith statusactive. - Spend against it accrues in
/spend-logsand rolls up into/spend. - Rotating: use the rotate action in the key’s row. This mints a new secret while preserving the key’s identity, so budgets and reporting continue uninterrupted.
Rate limits are fleet-wide only with Redis
RPM and TPM are enforced per gateway instance unless REDIS_URL is configured.
With more than one replica and no Redis, each instance keeps its own counter and
the effective limit is your configured value multiplied by the replica count.
If Redis is configured but unreachable, the limiter degrades to in-process
counting rather than failing requests — it logs loudly and exports
aocore_provider_ratelimit_redis_errors_total. Watch that counter if you depend
on exact enforcement.
API equivalent
curl -X POST https://<gateway>/key/generate \
-H "X-Aoedge-Identity-Context: <attested context>" \
-H "Content-Type: application/json" \
-d '{
"key_name": "billing-service",
"user_id": "<uuid>",
"max_budget": 500,
"duration": "monthly",
"rpm_limit": 600,
"tpm_limit": 120000,
"models": ["gpt-4o", "claude-sonnet-4"]
}'
201 returns the plaintext key — the only time it is available. See
POST /key/generate for the full schema.