Provisioning API keys
Programmatically mint, scope and revoke API keys — one per end-customer — with per-key spend caps, rate limits, model access scoping and a kill switch. Built for resellers and multi-tenant apps.
Authentication
These endpoints are authenticated with your account's PRIMARY API key — it is the management credential. Secondary (provisioned) keys are explicitly rejected, so a leaked customer key can never mint or disable keys. All responses carry Cache-Control: no-store.
Authorization: Bearer sk-air-YOUR_PRIMARY_KEY
# x-api-key: sk-air-YOUR_PRIMARY_KEY also acceptedPOST /v1/keys
Create a secondary key. This is the only response that ever contains the full key — store it now, it cannot be retrieved again. Up to 100 keys per account.
https://api.airforce/v1/keysRequest body
| Parameter | Type | Required | Description |
|---|---|---|---|
| label | string | Optional | Human-readable name for the key, e.g. the end-customer it belongs to. |
| rpm_limit | integer | Optional | Per-key requests-per-minute cap. Omit for the account default. |
| credit_allowance | number | Optional | Spend cap for this key within each limit_reset window. Consumption is reported back as credits_used in the same unit, so you can calibrate against it. Omit for no per-key cap. |
| limit_reset | string | Optional | "daily", "weekly" or "monthly" — the window after which credits_used resets to zero. Omit for a non-resetting lifetime cap. |
| tier | string | Optional | "default" (your account settings), "premium" (plan credits only, no pay-as-you-go), or "paygo" (pay-as-you-go only). |
| allowed_models | string[] | Optional | Allow-list of model IDs. When set, the key may ONLY call these models. |
| blocked_models | string[] | Optional | Deny-list of model IDs the key may never call. |
| allowed_makers / blocked_makers | string[] | Optional | Scope by model maker/vendor (e.g. "anthropic", "openai", "google") instead of listing individual IDs. |
| allowed_classes / blocked_classes | string[] | Optional | Scope by model class (e.g. chat, image, audio, video, embedding). |
| allowed_ips | string[] | Optional | IP allow-list. When set, requests with this key are only accepted from these addresses. |
All fields are optional — an empty body mints an unrestricted key under your account defaults.
Example
curl https://api.airforce/v1/keys \
-H "Authorization: Bearer sk-air-YOUR_PRIMARY_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "customer-acme",
"rpm_limit": 60,
"credit_allowance": 1000,
"limit_reset": "monthly",
"allowed_classes": ["chat", "embedding"]
}'{
"key": "sk-air-xxxxxxxxxxxxxxxxxxxxxxxx",
"label": "customer-acme",
"disabled": false,
"tier": "default",
"rpm_limit": 60,
"credit_allowance": 1000,
"credits_used": 0,
"limit_reset": "monthly",
"allowed_classes": ["chat", "embedding"]
}GET /v1/keys
List your secondary keys. Key material is masked (prefix + last 4); use the create response if you need the full key.
https://api.airforce/v1/keys{
"keys": [
{
"key": "sk-air-…f3a9",
"label": "customer-acme",
"disabled": false,
"tier": "default",
"rpm_limit": 60,
"credit_allowance": 1000,
"credits_used": 134,
"limit_reset": "monthly"
}
],
"total": 1
}PATCH /v1/keys/{key}
Update any field on an existing key. Send only the fields you want to change; for a scope (allowed_models, etc.) the value you send REPLACES the whole list for that dimension. Set "disabled": true to instantly cut a customer off, false to restore them.
https://api.airforce/v1/keys/{key}curl -X PATCH https://api.airforce/v1/keys/sk-air-xxxxxxxx \
-H "Authorization: Bearer sk-air-YOUR_PRIMARY_KEY" \
-H "Content-Type: application/json" \
-d '{ "disabled": true }'DELETE /v1/keys/{key}
Permanently delete a secondary key. Deletion is irreversible; for a temporary cut-off prefer PATCH with disabled: true.
https://api.airforce/v1/keys/{key}Key fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| key | string | Optional | The API key. Returned in FULL exactly once — by POST /v1/keys. List/get/update responses mask it as sk-air-…abcd. |
| label | string | Optional | The label you set. |
| disabled | boolean | Optional | Kill switch — true means the key is rejected on every request until re-enabled. |
| tier / rpm_limit / credit_allowance / limit_reset | mixed | Optional | Echo of the limits configured on the key. |
| credits_used | number | Optional | Spend in the current window — the figure the credit_allowance check actually compares against. |
| allowed_models / blocked_models / allowed_makers / … | string[] | Optional | The access scopes configured on the key. |
The disabled kill switch and the credit_allowance / limit_reset window are enforced on every request centrally, so a change takes effect immediately across all your keys. Model, maker, class and IP scoping are enforced post-routing on each call.