Overview
When you create a sub-key:- It inherits your account’s credit pool — there is no separate balance to fund.
- You optionally cap how much of that pool any single sub-key can consume per billing period.
- You optionally restrict which models the sub-key can call.
- The sub-key’s usage feeds back into your account’s overall billing.
- Teams — give each team or project its own key with a monthly budget.
- Partners / customers — provide programmatic API access with hard credit limits so a single integration can never exhaust your entire balance.
- Services — isolate microservices with model allow-lists so they can only call the models they need.
Authentication
All sub-key management endpoints use your admin API key in thex-api-key header. Sub-keys themselves authenticate inference calls (chat completions, embeddings, etc.) using the same header — they are recognized automatically by the API.
Sub-keys cannot create further sub-keys. Only an admin key can manage the key hierarchy.
Creating a Sub-API Key
Store the returned key value securely
The response includes a
value field with the full key string (e.g. acme-v2-eyJhbGci...). This is shown only once. Copy it to a secret manager immediately — it cannot be retrieved again.Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
description | string | Yes | Human-readable label for the key. |
allowed_models | string[] | No | List of model IDs this key may call. Omit to allow all models. |
credit_limit | number | No | Maximum credits per refresh cycle. Omit for no per-key cap. |
credit_refresh_cycle | string | No | When the usage counter resets: "8h", "daily", "weekly", "monthly" (default). |
expires_at | datetime / "never" | No | Key expiry. Defaults to 180 days from creation. |
key_prefix | string | No | 2–8 char lowercase slug prepended to the key (e.g. "acme" → acme-v2-...). Defaults to the standard io-v2 prefix. |
Model Restrictions
Whenallowed_models is set, any request to a model not in the list is rejected with 403 Forbidden, even if the admin key has access to that model.
The GET /v1/models endpoint, when called with a sub-key, returns only the models in the sub-key’s allow-list — so integrations can discover their permitted set without any extra configuration.
To remove all restrictions on an existing sub-key, pass an empty array:
Credit Limits
How limits are enforced
Credit limits are evaluated once per billing cycle by the settlement pipeline (which runs every ~60 seconds). When a sub-key’s accumulated spend in the current period exceeds itscredit_limit, the key is automatically blocked and inference calls return 429 Too Many Requests.
The block clears automatically when the cycle resets (credit_refresh_cycle), or immediately when you raise the limit via PATCH.
Blocking and unblocking
A sub-key is returning 429 — how do I unblock it?
A sub-key is returning 429 — how do I unblock it?
The key has exceeded its Wait for the next cycle reset — the key unblocks automatically when
credit_limit for the current period. You have two options:Raise the limit immediately:credit_refresh_cycle rolls over.How do I check how much a sub-key has spent?
How do I check how much a sub-key has spent?
Use the admin endpoint to inspect a specific key:Or let the sub-key check itself:
What happens to my account balance when a sub-key is blocked?
What happens to my account balance when a sub-key is blocked?
The block applies only to that specific sub-key. Your admin key and all other sub-keys continue operating normally. The admin’s overall account balance is not affected by per-key limits.
Credit Refresh Cycles
Thecredit_refresh_cycle determines when a sub-key’s credit_used counter resets to zero, allowing spending up to credit_limit again.
| Cycle | Resets at |
|---|---|
8h | Every 8 hours aligned to midnight UTC (00:00, 08:00, 16:00). |
daily | Midnight UTC each day. |
weekly | Monday 00:00 UTC. |
monthly | The 1st of each month at 00:00 UTC. |
Custom Key Prefix
By default, sub-keys follow the standardio-v2- format. You can supply a custom key_prefix to make keys visually identifiable:
acme-v2-eyJhbGci...
Prefix rules:
- 2–8 characters, lowercase letters, digits, and internal hyphens only.
- Cannot start with
io(reserved for platform keys). - Cannot contain version markers like
-v2.
Managing Sub-Keys
Listing keys
credit_used for the active billing period.
Updating a key
All fields on a sub-key can be updated at any time. Only the fields you include in thePATCH body are changed:
Revoking a key
Viewing Usage
All sub-keys (admin)
Single sub-key (admin)
Self-service (sub-key holder)
FAQs
Do sub-keys have their own credit balance?
Do sub-keys have their own credit balance?
No. Sub-keys draw from the admin’s account balance. The
credit_limit is a spending cap per cycle, not a separate balance. All usage by sub-keys is deducted from the same pool as the admin’s own usage.Can a sub-key call any model endpoint?
Can a sub-key call any model endpoint?
Only the models listed in
allowed_models. If no list is configured, the sub-key can call any model available to the admin account. The /v1/models endpoint filters its response to only show the permitted models when called with a sub-key.What happens when the cycle resets?
What happens when the cycle resets?
The sub-key’s
credit_used counter is reset to zero at the start of each new period. If the key was blocked due to exceeding its limit, it is automatically unblocked.How quickly does blocking take effect after the limit is exceeded?
How quickly does blocking take effect after the limit is exceeded?
The billing settlement pipeline runs approximately every 60 seconds. Once a sub-key’s accumulated spend exceeds its
credit_limit, the block is applied within the next pipeline run.Can I have sub-keys without a credit limit?
Can I have sub-keys without a credit limit?
Yes. Omit
credit_limit (or set it to null) when creating or updating a sub-key. The key will only be limited by the admin’s overall account balance.Is the key prefix stored anywhere?
Is the key prefix stored anywhere?
No. The prefix is encoded in the key string itself. The display value (e.g.
acme-v2-eyJh...c0eQ) shows the prefix so you can identify it, but it is not stored separately in the database.