api-keys
Scoped server credential issuance, rotation, revocation, and audit.
| Method | Path | Operation ID |
|---|---|---|
| GET | /v1/api-keys |
listApiKeys |
| POST | /v1/api-keys |
createApiKey |
| GET | /v1/api-keys/scopes |
listApiKeyScopes |
| GET | /v1/api-keys/{api_key_id} |
getApiKey |
| DELETE | /v1/api-keys/{api_key_id} |
revokeApiKey |
| GET | /v1/api-keys/{api_key_id}/restrictions |
getApiKeyRestrictions |
| PUT | /v1/api-keys/{api_key_id}/restrictions |
setApiKeyRestrictions |
| GET | /v1/api-keys/{api_key_id}/retention |
getApiKeyRetention |
| PUT | /v1/api-keys/{api_key_id}/retention |
setApiKeyRetention |
| POST | /v1/api-keys/{api_key_id}/rotate |
rotateApiKey |
| POST | /v1/api-keys/{api_key_id}/rotation/cancel |
cancelApiKeyRotation |
| POST | /v1/api-keys/{api_key_id}/rotation/complete |
completeApiKeyRotation |
| GET | /v1/api-keys/{api_key_id}/signing-profile |
getApiKeySigningProfile |
| PUT | /v1/api-keys/{api_key_id}/signing-profile |
setApiKeySigningProfile |
| GET | /v1/api-request-logs |
listApiRequestLogs |
| GET | /v1/api-request-logs/summary |
summarizeApiRequestLogs |
GET /v1/api-keys
Section titled “GET /v1/api-keys”Operation ID: listApiKeys
List tenant-owned API-key metadata without credential secrets.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyListResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | A verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
data |
array of ApiKeyMetadataResponse | yes |
POST /v1/api-keys
Section titled “POST /v1/api-keys”Operation ID: createApiKey
Issue a scoped API key and display its secret exactly once.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string | yes | Pattern: ^[!-~]+$. Max length 200. |
Request body
Section titled “Request body”application/json: ApiKeyCreateRequest (required)
| Field | Type | Required | Description |
|---|---|---|---|
expires_at |
string or null | no | |
name |
string or null | no | |
restrictions |
ApiKeyRestrictionsRequest or null | no | |
retention_mode |
enum or null | no | |
scopes |
array of string | yes | |
signing_profile |
ApiKeySigningProfileDocument or null | no |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 201 | Successful Response | application/json IssuedApiKeyResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The API key does not grant the scope required by this operation, the requested grants exceed the calling API key’s own authority, the requested restrictions are looser than the calling API key’s own, or the operation is not classified by the route/scope policy and is denied by default. A caller may never mint a credential broader than the one it presented. | application/json HttpErrorResponse or ErrorResponse |
| 409 | The calling API key changed after authentication; the idempotency key was reused for a different request; the one-time secret of a completed request cannot be replayed; just-in-time provisioning found the verified email on another account; or an IP allowlist was requested on a deployment that cannot enforce one (API_KEY_IP_ALLOWLIST_UNAVAILABLE). This operation may also return its reason-coded domain envelope with this status. |
application/json HttpErrorResponse or ErrorResponse |
| 422 | The request is malformed, the requested scopes are not in the current scope vocabulary, the expiry is not in the future, or a verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | API-key issuance is unavailable because no pepper keyring is enrolled, or bounded memory-hard hashing is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
201 response fields
Section titled “201 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
secret |
string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
GET /v1/api-keys/scopes
Section titled “GET /v1/api-keys/scopes”Operation ID: listApiKeyScopes
Discover the exact versioned scope vocabulary an API key may be granted.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyScopeCatalogResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | A verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
catalog_version |
string | yes | |
groups |
array of ApiKeyScopeGroupResponse | yes | |
scopes |
array of ApiKeyScopeDescriptorResponse | yes | |
wildcard_supported |
const false | no | Default false. |
GET /v1/api-keys/{api_key_id}
Section titled “GET /v1/api-keys/{api_key_id}”Operation ID: getApiKey
Read one tenant-owned API key’s metadata without credential secrets.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyMetadataResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | Not Found | application/json HttpErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | A verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
DELETE /v1/api-keys/{api_key_id}
Section titled “DELETE /v1/api-keys/{api_key_id}”Operation ID: revokeApiKey
Immediately revoke one tenant-owned API key.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Idempotency-Key |
header | string | yes | Pattern: ^[!-~]+$. Max length 200. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyMetadataResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | Not Found | application/json HttpErrorResponse |
| 409 | A concurrent revoke of the same key is still in progress; the calling API key or target changed after authentication; the idempotency key was reused for a different request; or the verified email belongs to another account. | application/json HttpErrorResponse |
| 422 | The request is malformed, or a verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable or temporarily overloaded. Revocation itself performs no memory-hard work. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
GET /v1/api-keys/{api_key_id}/restrictions
Section titled “GET /v1/api-keys/{api_key_id}/restrictions”Operation ID: getApiKeyRestrictions
Read the key’s versioned IP allowlist and rate limit.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyRestrictionsResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | The key does not exist in the authenticated tenant. | application/json HttpErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | The API-key identifier is invalid, or account provisioning lacks a verified email. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
allowed_ip_cidrs |
array of string or null | yes | |
api_key_id |
string | yes | |
ip_allowlist_available |
boolean | yes | |
rate_limit_per_minute |
integer or null | yes | |
version |
integer | yes |
PUT /v1/api-keys/{api_key_id}/restrictions
Section titled “PUT /v1/api-keys/{api_key_id}/restrictions”Operation ID: setApiKeyRestrictions
Replace the key’s IP allowlist and rate limit, effective from its next request.
Replace a key’s restrictions. They apply from the key’s next request.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Request body
Section titled “Request body”application/json: ApiKeyRestrictionsUpdateRequest (required)
| Field | Type | Required | Description |
|---|---|---|---|
allowed_ip_cidrs |
array of string or null | yes | |
expected_version |
integer | yes | Minimum 0. |
rate_limit_per_minute |
integer or null | yes |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyRestrictionsResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The identity was deleted or the account is deactivated; the API key lacks the governance:write scope, an unclassified operation is denied by default, or the requested restrictions are looser than the calling API key’s own. | application/json HttpErrorResponse or ErrorResponse |
| 404 | The key is unavailable to this caller. | application/json HttpErrorResponse |
| 409 | The key is inactive, its authority changed, expected_version is stale, identity provisioning conflicted, or a new IP allowlist was requested on a deployment that cannot enforce one (API_KEY_IP_ALLOWLIST_UNAVAILABLE). This operation may also return its reason-coded domain envelope with this status. |
application/json HttpErrorResponse or ErrorResponse |
| 422 | Invalid API-key identifier, network, rate limit, version, request body, or verified account identity. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
allowed_ip_cidrs |
array of string or null | yes | |
api_key_id |
string | yes | |
ip_allowlist_available |
boolean | yes | |
rate_limit_per_minute |
integer or null | yes | |
version |
integer | yes |
GET /v1/api-keys/{api_key_id}/retention
Section titled “GET /v1/api-keys/{api_key_id}/retention”Operation ID: getApiKeyRetention
Read the key’s versioned retention policy without changing historical jobs.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyRetentionResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | The key does not exist in the authenticated tenant. | application/json HttpErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | The API-key identifier is invalid, or account provisioning lacks a verified email. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
api_key_id |
string | yes | |
clock_starts_at |
const “validated_publication” | yes | |
effective_for |
const “future_job_admissions” | yes | |
retention_mode |
enum | yes | One of: legacy, 1h, 24h, 72h, retain. |
version |
integer | yes |
PUT /v1/api-keys/{api_key_id}/retention
Section titled “PUT /v1/api-keys/{api_key_id}/retention”Operation ID: setApiKeyRetention
Set retention for future admissions within tenant and delegated-key ceilings.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Request body
Section titled “Request body”application/json: ApiKeyRetentionRequest (required)
| Field | Type | Required | Description |
|---|---|---|---|
expected_version |
integer | yes | Minimum 0. |
retention_mode |
enum | yes | One of: 1h, 24h, 72h, retain. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyRetentionResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The identity was deleted or the account is deactivated; the API key lacks the governance:write scope, an unclassified operation is denied by default, or retention exceeds the tenant/delegated ceiling. | application/json HttpErrorResponse or ErrorResponse |
| 404 | The key is unavailable to this caller. | application/json HttpErrorResponse |
| 409 | The key is inactive, its authority changed, expected_version is stale, or identity provisioning conflicted. | application/json HttpErrorResponse |
| 422 | Invalid API-key identifier, retention mode, version, request body, or verified account identity. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
api_key_id |
string | yes | |
clock_starts_at |
const “validated_publication” | yes | |
effective_for |
const “future_job_admissions” | yes | |
retention_mode |
enum | yes | One of: legacy, 1h, 24h, 72h, retain. |
version |
integer | yes |
POST /v1/api-keys/{api_key_id}/rotate
Section titled “POST /v1/api-keys/{api_key_id}/rotate”Operation ID: rotateApiKey
Begin a bounded API-key rollover and display the successor secret once.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Idempotency-Key |
header | string | yes | Pattern: ^[!-~]+$. Max length 200. |
Request body
Section titled “Request body”application/json: ApiKeyRotateRequest (required)
| Field | Type | Required | Description |
|---|---|---|---|
expires_at |
string or null | no | |
overlap_seconds |
integer | no | Minimum 300. Maximum 604800. Default 86400. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 201 | Successful Response | application/json IssuedApiKeyResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The API key does not grant the scope required to invoke rotation, or the operation is not classified by the route/scope policy and is denied by default. The target identifier is not evaluated on this path. | application/json HttpErrorResponse or ErrorResponse |
| 404 | The rotation target is unavailable to this caller. Missing, foreign-tenant, over-broad targets return the same status and body to a delegated API-key caller, so the response does not disclose whether a target exists. | application/json HttpErrorResponse |
| 409 | The key is not active, expired or was rotated concurrently; the target or the calling key’s authority changed while the replacement was being prepared; the idempotency key was reused for a different request; the one-time secret of a completed request cannot be replayed; or the verified email belongs to another account. | application/json HttpErrorResponse |
| 422 | The request is malformed, the requested scopes are not in the current scope vocabulary, the expiry is not in the future, or a verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | API-key issuance is unavailable because no pepper keyring is enrolled, or bounded memory-hard hashing is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
201 response fields
Section titled “201 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
secret |
string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
POST /v1/api-keys/{api_key_id}/rotation/cancel
Section titled “POST /v1/api-keys/{api_key_id}/rotation/cancel”Operation ID: cancelApiKeyRotation
Cancel a pending rollover and revoke its undeployed successor.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Idempotency-Key |
header | string | yes | Pattern: ^[!-~]+$. Max length 200. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyMetadataResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | Not Found | application/json HttpErrorResponse |
| 409 | The rollover is absent, has changed concurrently, or can no longer be changed; the calling API key changed after authentication; the idempotency key was reused for another request; or the verified email belongs to another account. | application/json HttpErrorResponse |
| 422 | The request is malformed, or a verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable or temporarily overloaded. The lifecycle transition itself performs no memory-hard work. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
POST /v1/api-keys/{api_key_id}/rotation/complete
Section titled “POST /v1/api-keys/{api_key_id}/rotation/complete”Operation ID: completeApiKeyRotation
Retire an outgoing API key after its successor has been deployed.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Idempotency-Key |
header | string | yes | Pattern: ^[!-~]+$. Max length 200. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeyMetadataResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | Not Found | application/json HttpErrorResponse |
| 409 | The rollover is absent, has changed concurrently, or can no longer be changed; the calling API key changed after authentication; the idempotency key was reused for another request; or the verified email belongs to another account. | application/json HttpErrorResponse |
| 422 | The request is malformed, or a verified email is unavailable for account provisioning. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable or temporarily overloaded. The lifecycle transition itself performs no memory-hard work. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
created_at |
string | yes | |
display_hint |
string | yes | |
expires_at |
string or null | yes | |
id |
string | yes | |
last_used_at |
string or null | yes | |
name |
string or null | yes | |
restrictions |
ApiKeyRestrictionsView or null | no | |
revoked_at |
string or null | yes | |
rotated_from_id |
string or null | yes | |
rotation |
ApiKeyRotationResponse or null | no | |
scopes |
array of string | yes | |
status |
ApiKeyStatus | yes | One of: active, expired, revoked, rotated. |
GET /v1/api-keys/{api_key_id}/signing-profile
Section titled “GET /v1/api-keys/{api_key_id}/signing-profile”Operation ID: getApiKeySigningProfile
Read the key’s versioned signing defaults and allowed sets.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeySigningProfileResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 404 | The key does not exist in the authenticated tenant. | application/json HttpErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | The API-key identifier is invalid, or account provisioning lacks a verified email. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
api_key_id |
string | yes | |
profile |
ApiKeySigningProfileDocument | yes | Defaults and allowed sets for POST /v1/sign made with this key. Every field is optional. A default fills a POST /v1/sign field the request omits; a field the request names always wins. An allowed set refuses, with API_KEY_PROFILE_FORBIDS, a request whose recipe, media type, watermark, strength or fingerprints would fall outside it – judged on what the job would actually run, so an omitted field cannot pass by falling through to a system default. Omit a field (or send null) for no default or no restriction. Names come from GET /v1/recipes and GET /v1/capabilities. |
version |
integer | yes |
PUT /v1/api-keys/{api_key_id}/signing-profile
Section titled “PUT /v1/api-keys/{api_key_id}/signing-profile”Operation ID: setApiKeySigningProfile
Replace the key’s signing defaults and allowed sets, effective from its next Sign.
Replace a key’s signing profile. It applies from the key’s next POST /v1/sign.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
path | string | yes | Pattern: ^ak_[a-z2-7]{16}$. |
Request body
Section titled “Request body”application/json: ApiKeySigningProfileUpdateRequest (required)
| Field | Type | Required | Description |
|---|---|---|---|
expected_version |
integer | yes | Minimum 0. |
profile |
ApiKeySigningProfileDocument | yes | Defaults and allowed sets for POST /v1/sign made with this key. Every field is optional. A default fills a POST /v1/sign field the request omits; a field the request names always wins. An allowed set refuses, with API_KEY_PROFILE_FORBIDS, a request whose recipe, media type, watermark, strength or fingerprints would fall outside it – judged on what the job would actually run, so an omitted field cannot pass by falling through to a system default. Omit a field (or send null) for no default or no restriction. Names come from GET /v1/recipes and GET /v1/capabilities. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiKeySigningProfileResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The identity was deleted or the account is deactivated; the API key lacks the governance:write scope, an unclassified operation is denied by default, or the requested profile allows more than the calling API key’s own. | application/json HttpErrorResponse or ErrorResponse |
| 404 | The key is unavailable to this caller. | application/json HttpErrorResponse |
| 409 | The key is inactive, its authority changed, expected_version is stale, or identity provisioning conflicted. | application/json HttpErrorResponse |
| 422 | Invalid API-key identifier, profile entry, version, request body, or verified account identity. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
api_key_id |
string | yes | |
profile |
ApiKeySigningProfileDocument | yes | Defaults and allowed sets for POST /v1/sign made with this key. Every field is optional. A default fills a POST /v1/sign field the request omits; a field the request names always wins. An allowed set refuses, with API_KEY_PROFILE_FORBIDS, a request whose recipe, media type, watermark, strength or fingerprints would fall outside it – judged on what the job would actually run, so an omitted field cannot pass by falling through to a system default. Omit a field (or send null) for no default or no restriction. Names come from GET /v1/recipes and GET /v1/capabilities. |
version |
integer | yes |
GET /v1/api-request-logs
Section titled “GET /v1/api-request-logs”Operation ID: listApiRequestLogs
List the tenant’s recent API-key requests (metadata only, best effort).
The tenant’s recent API-key requests, newest first. Best effort, not evidence: rows are written in the background and can be dropped under load. Kept for 30 days.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key_id |
query | string or null | no | |
status_class |
query | StatusClass or null | no | |
route |
query | string or null | no | |
cursor |
query | string or null | no | |
limit |
query | integer | no | Minimum 1. Maximum 200. Default 50. |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiRequestLogPageResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | A filter, cursor or limit is malformed, or account provisioning lacks a verified email. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
best_effort |
const true | no | Default true. |
data |
array of ApiRequestLogItem | yes | |
next_cursor |
string or null | yes |
GET /v1/api-request-logs/summary
Section titled “GET /v1/api-request-logs/summary”Operation ID: summarizeApiRequestLogs
Summarize the tenant’s recent API-key requests by status and latency.
Counts and latency percentiles over a recent window. Best effort, not evidence: rows are written in the background and can be dropped under load. Kept for 30 days.
Authentication: Authorization: Bearer <API key or console session> (Authentication).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
window |
query | SummaryWindow | no | Default "24h". |
Responses
Section titled “Responses”| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | application/json ApiRequestLogSummaryResponse |
| 401 | The bearer credential is missing, malformed, expired, revoked, or otherwise invalid. Clerk sessions and scoped API keys fail identically and the body never reveals which credential was presented or whether it exists. | application/json HttpErrorResponse |
| 403 | The provider deleted this identity, or the account is deactivated. A valid session cannot authorize a tombstoned identity back into use; an API key must also grant the scope required by the operation, and an operation is not classified by the route/scope policy and is denied by default. An API key restricted to client networks is refused from any other network with the API_KEY_IP_NOT_ALLOWED envelope. |
application/json HttpErrorResponse or ErrorResponse |
| 409 | Just-in-time provisioning conflicted: the verified email belongs to another provisioned account. | application/json HttpErrorResponse |
| 422 | A filter, cursor or limit is malformed, or account provisioning lacks a verified email. | application/json HttpErrorResponse |
| 429 | The API key’s own request rate limit was exceeded (API_KEY_RATE_LIMITED). Only keys configured with a rate limit can receive this. Retryable after Retry-After seconds; the refused request consumed no capacity. |
application/json ErrorResponse |
| 503 | Credential verification is unavailable: Clerk session verification is not configured, no API-key pepper is enrolled, or bounded API-key verification is temporarily overloaded. Retryable. | application/json HttpErrorResponse |
200 response fields
Section titled “200 response fields”| Field | Type | Required | Description |
|---|---|---|---|
best_effort |
const true | no | Default true. |
p50_duration_ms |
integer or null | yes | |
p95_duration_ms |
integer or null | yes | |
refused |
integer | yes | |
since |
string | yes | |
status_classes |
ApiRequestLogStatusClasses | yes | |
total |
integer | yes | |
window |
SummaryWindow | yes | One of: 1h, 24h, 7d. |
