API Reference
All endpoints require a Bearer token. See Authentication.
See Rate Limits for request quotas per tier.
Create Key
Keys can be created globally (under your account’s default project) or scoped to a specific project.
Global:
POST /v1/keys
Project-scoped:
POST /v1/projects/:id/keys
Both endpoints accept the same request body. Project-scoped keys can only access resources within that project. The project_id is included in verify responses so you can gate access by project.
| Field | Type | Required | Description |
|---|---|---|---|
| prefix | string | Yes | Key prefix, 1-32 chars, lowercase alphanumeric + underscore |
| name | string | Yes | Human-readable name, 1-255 chars |
| scopes | string[] | Yes | Scope strings to grant |
| environment | string | No | Environment tag (e.g. “production”, “staging”) |
| metadata | object | No | Custom key-value pairs |
| expires_at | string | No | ISO 8601 expiration timestamp |
Response (201):
{
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"secret": "myapp_live_A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0_12ab34cd",
"prefix": "myapp_live",
"name": "Production Key",
"scopes": ["orders:read", "orders:write"],
"environment": "production",
"metadata": { "team": "api" },
"created_at": "2026-02-05T12:00:00Z",
"expires_at": null
}
The secret is only returned at creation time. Store it securely.
List Keys
GET /v1/keys?limit=20&cursor=<created_at>
| Param | Type | Default | Description |
|---|---|---|---|
| limit | number | 20 | Results per page (1-100) |
| cursor | string | — | ISO 8601 timestamp from last item’s created_at |
Response (200):
{
"keys": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"masked_secret": "myapp_live_...",
"prefix": "myapp_live",
"name": "Production Key",
"scopes": ["orders:read", "orders:write"],
"environment": "production",
"metadata": { "team": "api" },
"created_at": "2026-02-05T12:00:00Z",
"expires_at": null,
"revoked_at": null,
"last_used_at": "2026-02-05T14:30:00Z"
}
],
"has_more": false,
"next_cursor": null
}
Secrets are masked as <prefix>_.... Use the id field for other operations.
Get Key
GET /v1/keys/:id
Response (200):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"prefix": "myapp_live",
"name": "Production Key",
"scopes": ["orders:read", "orders:write"],
"environment": "production",
"metadata": { "team": "api" },
"created_at": "2026-02-05T12:00:00Z",
"expires_at": null,
"revoked_at": null,
"last_used_at": "2026-02-05T14:30:00Z",
"last_used_ip": "203.0.113.42",
"last_used_ua": "MyApp/1.0"
}
The secret is never returned after creation. Use /v1/keys/verify to validate keys.
Rotate Key
Generate a new secret. Old key remains valid during the grace period.
POST /v1/keys/:id/rotate
| Field | Type | Default | Description |
|---|---|---|---|
| grace_hours | number | 24 | Hours old key remains valid (1-720) |
Response (200):
{
"new_key_id": "660f9511-f3ac-52e5-b827-557766551111",
"new_secret": "myapp_live_Z9Y8X7W6V5U4T3S2R1Q0P9O8N7M6L5K4J3I2H1_56ef78gh",
"old_key_id": "550e8400-e29b-41d4-a716-446655440000",
"old_expires_at": "2026-02-06T12:00:00Z",
"grace_hours": 24
}
The new key inherits name, scopes, environment, and metadata. Both keys verify successfully until old_expires_at.
Revoke Key
Immediately invalidate a key. Clears cache and sets revoked_at.
DELETE /v1/keys/:id
Response (200):
{
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"revoked_at": "2026-02-05T14:30:00Z",
"status": "revoked"
}
Soft-deleted with 30-day retention for recovery.
RPC Interface
For service-to-service verification via Cloudflare Workers service bindings.
interface KeyEntrypoint {
ping(): Promise<'pong'>
verify(
secret: string,
meta?: { ip?: string; userAgent?: string }
): Promise<VerifyResult>
}
interface VerifyResult {
valid: boolean
key_id?: string
project_id?: string
scopes?: string[]
error?: 'invalid_key' | 'expired' | 'revoked' | 'deleted'
}
Usage:
const result = await env.KEY.verify(apiKey, {
ip: request.headers.get('CF-Connecting-IP'),
userAgent: request.headers.get('User-Agent')
})
Metadata is optional. When provided, last_used_ip and last_used_ua are updated on the key record.
Metering
| Operation | Cost |
|---|---|
| Create key | Free |
| List keys | Free |
| Get key | Free |
| Rotate key | Free |
| Revoke key | Free |
| Verify key (RPC) | 1 credit |
Every /v1/keys request costs 1 credit — create, list, get, rotate, revoke and verify alike. The gateway meters the whole prefix; only /v1/latch/ and /v1/meter/ are exempt.
Next steps
- Errors — error codes and resolutions
- Troubleshooting — common issues and solutions