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.

FieldTypeRequiredDescription
prefixstringYesKey prefix, 1-32 chars, lowercase alphanumeric + underscore
namestringYesHuman-readable name, 1-255 chars
scopesstring[]YesScope strings to grant
environmentstringNoEnvironment tag (e.g. “production”, “staging”)
metadataobjectNoCustom key-value pairs
expires_atstringNoISO 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>
ParamTypeDefaultDescription
limitnumber20Results per page (1-100)
cursorstringISO 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
FieldTypeDefaultDescription
grace_hoursnumber24Hours 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

OperationCost
Create keyFree
List keysFree
Get keyFree
Rotate keyFree
Revoke keyFree
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