Skip to content

API Keys

POST https://api.bve.me/admin/api-keys
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY
Content-Type: application/json
{
"name": "my-client",
"rpm_limit": 60,
"rpd_limit": 10000,
"monthly_limit": null,
"monthly_token_limit": null,
"allowed_models": null
}
FieldTypeRequiredDefaultDescription
namestringYesHuman-readable label (1–255 chars)
rpm_limitintegerNo60Max requests per minute
rpd_limitintegerNo10000Max requests per day
monthly_limitinteger | nullNonullMax requests per month (null = unlimited)
monthly_token_limitinteger | nullNonullMax tokens per month (null = unlimited)
allowed_modelsstring[] | nullNonullRestrict to specific exact live Fuelix model IDs. New admin writes reject wildcard prefixes. null or [] removes the per-key restriction, so the key inherits the gateway’s global policy and live model availability. Older keys may still return legacy wildcard prefixes until normalized.
expires_atISO 8601 datetime | nullNonullKey expiry date/time. After this timestamp, all requests with the key return 401 api_key_expired. Set to null for no expiry.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-client",
"key": "sk-bve-a1b2c3d4...",
"status": "active",
"rpm_limit": 60,
"rpd_limit": 10000,
"monthly_limit": null,
"monthly_token_limit": null,
"allowed_models": null,
"expires_at": null,
"is_expired": false,
"created_at": "2026-05-21T12:00:00.000Z",
"updated_at": "2026-05-21T12:00:00.000Z",
"revoked_at": null,
"last_used_at": null
}
Terminal window
curl -X POST https://api.bve.me/admin/api-keys \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-client",
"rpm_limit": 60,
"rpd_limit": 10000
}'
Terminal window
curl -X POST https://api.bve.me/admin/api-keys \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "trial-key",
"rpm_limit": 10,
"rpd_limit": 100,
"monthly_limit": 500
}'
Terminal window
curl -X POST https://api.bve.me/admin/api-keys \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "embeddings-only",
"allowed_models": ["text-embedding-3-small", "text-embedding-3-large"]
}'
Terminal window
curl -X POST https://api.bve.me/admin/api-keys \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "trial-30-days",
"expires_at": "2026-06-25T00:00:00.000Z"
}'

After the expires_at timestamp, all requests using this key return 401 api_key_expired. To remove the expiry, PATCH the key with "expires_at": null.


GET https://api.bve.me/admin/api-keys/:id
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns a single API key by its UUID.

ParameterDescription
idUUID of the API key
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-client",
"status": "active",
"rpm_limit": 60,
"rpd_limit": 10000,
"monthly_limit": null,
"monthly_token_limit": null,
"allowed_models": null,
"expires_at": null,
"is_expired": false,
"created_at": "2026-05-21T12:00:00.000Z",
"updated_at": "2026-05-21T12:00:00.000Z",
"revoked_at": null,
"last_used_at": "2026-05-21T14:37:00.000Z"
}
FieldTypeDescription
idstringUUID of the API key
namestringHuman-readable label
statusstringactive, suspended, or revoked
rpm_limitintegerMax requests per minute
rpd_limitintegerMax requests per day
monthly_limitinteger | nullMonthly request cap; null = unlimited
monthly_token_limitinteger | nullMonthly token cap; null = unlimited
allowed_modelsstring[] | nullStored model allowlist; null or [] = no per-key restriction (global policy and live availability still apply). Older keys may still return legacy wildcard prefixes until normalized, but new admin writes reject them and require exact live Fuelix IDs.
expires_atstring | nullISO 8601 expiry timestamp; null = no expiry
is_expiredbooleantrue when expires_at is set and in the past; false otherwise. Lets clients detect expired-but-status=active keys without comparing date strings.
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 timestamp of last update
revoked_atstring | nullISO 8601 revocation timestamp; null if not revoked
last_used_atstring | nullISO 8601 timestamp of the last accepted request; null if never used
{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"code": "not_found"
}
}
Terminal window
curl https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

PATCH https://api.bve.me/admin/api-keys/:id
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY
Content-Type: application/json

Partially update key metadata or limits. All fields are optional — only provided fields are changed.

{
"name": "new-name",
"rpm_limit": 120,
"rpd_limit": 20000,
"monthly_limit": 5000,
"monthly_token_limit": null,
"allowed_models": ["gpt-4o", "gpt-4o-mini"]
}
FieldTypeDescription
namestringNew display name (1–255 chars)
rpm_limitintegerNew requests-per-minute limit
rpd_limitintegerNew requests-per-day limit
monthly_limitinteger | nullMonthly request cap (null = unlimited)
monthly_token_limitinteger | nullMonthly token cap (null = unlimited)
allowed_modelsstring[] | nullStored model allowlist (null or [] = no per-key restriction; global policy and live availability still apply). Older keys may still return legacy wildcard prefixes until normalized, but new admin writes reject them and require exact live Fuelix IDs.
expires_atISO 8601 datetime | nullExpiry date/time; null removes the expiry

Returns the full updated key object (same shape as Get API key, without the raw key value).

{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"code": "not_found"
}
}

Rename and raise rate limit:

Terminal window
curl -X PATCH https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "production-client", "rpm_limit": 120 }'

Restrict to specific models:

Terminal window
curl -X PATCH https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "allowed_models": ["gpt-4o", "gpt-4o-mini"] }'

Remove the monthly limit:

Terminal window
curl -X PATCH https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "monthly_limit": null }'

GET https://api.bve.me/admin/api-keys
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns all API keys by default. Use ?status= to filter by lifecycle state, ?name= to search by display name or UUID, ?since= / ?until= to filter by creation date, ?sort_by= / ?sort_dir= to control order, and ?limit= / ?offset= for pagination.

ParameterTypeRequiredDefaultDescription
statusstringNoFilter by key status: active, suspended, or revoked. Omit to return all statuses. Mutually exclusive with ?expired=true.
namestringNoCase-insensitive substring match on the key’s display name or UUID. Operators can paste a partial UUID from a request log to find the associated key. Combinable with all other parameters.
expiredbooleanNotrue to return only keys whose expires_at date has passed. Mutually exclusive with ?status=.
sincestringNoISO 8601 timestamp. Return only keys created at or after this time. Invalid timestamps return 400 validation_error.
untilstringNoISO 8601 timestamp. Return only keys created at or before this time. since must not be after until.
sort_bystringNocreated_atColumn to sort by. One of: name, created_at, updated_at, last_used_at. Any other value returns 400 validation_error.
sort_dirstringNodescSort direction: asc or desc. Any other value returns 400 validation_error.
limitintegerNo100Maximum number of keys to return (1–500).
offsetintegerNo0Number of keys to skip. Use with ?limit= for cursor-free pagination.

All parameters may be combined: ?status=active&name=prod&since=2026-05-01T00:00:00Z&sort_by=last_used_at&limit=10 returns up to 10 active keys whose name contains "prod", created on or after 2026-05-01, sorted by most recently used.

{
"total": 1,
"has_more": false,
"keys": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-client",
"status": "active",
"rpm_limit": 60,
"rpd_limit": 10000,
"monthly_limit": null,
"monthly_token_limit": null,
"allowed_models": null,
"expires_at": null,
"is_expired": false,
"created_at": "2026-05-21T12:00:00.000Z",
"updated_at": "2026-05-21T12:00:00.000Z",
"revoked_at": null,
"last_used_at": "2026-05-21T14:37:00.000Z"
}
]
}
FieldTypeDescription
totalintegerTotal number of keys matching the current filters (ignores limit/offset). Use for pagination UI.
has_morebooleantrue when additional pages exist (offset + len(keys) < total). Shorthand for detecting additional pages without computing pagination math.
keysarrayArray of key objects. Each key has the same fields as Get API key, without the raw key value.

The raw key (sk-bve-...) is not included in list responses.

List all keys:

Terminal window
curl https://api.bve.me/admin/api-keys \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

List only active keys:

Terminal window
curl "https://api.bve.me/admin/api-keys?status=active" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

List only suspended keys:

Terminal window
curl "https://api.bve.me/admin/api-keys?status=suspended" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Search by name (substring match):

Terminal window
curl "https://api.bve.me/admin/api-keys?name=production" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Find a key by UUID prefix (paste from a request log):

Terminal window
curl "https://api.bve.me/admin/api-keys?name=550e8400" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Combine name/UUID search with status filter:

Terminal window
curl "https://api.bve.me/admin/api-keys?status=active&name=prod" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Paginate through all keys (100 at a time):

Terminal window
# Page 1
curl "https://api.bve.me/admin/api-keys?limit=100&offset=0" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Page 2
curl "https://api.bve.me/admin/api-keys?limit=100&offset=100" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Filter by creation date range:

Terminal window
# Keys created in May 2026
curl "https://api.bve.me/admin/api-keys?since=2026-05-01T00:00:00Z&until=2026-05-31T23:59:59Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

List only expired keys:

Terminal window
# Keys whose expires_at has passed (cannot be combined with ?status=)
curl "https://api.bve.me/admin/api-keys?expired=true" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Sort by most recently used (stale keys first with asc):

Terminal window
curl "https://api.bve.me/admin/api-keys?sort_by=last_used_at&sort_dir=asc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Most recently updated keys:

Terminal window
curl "https://api.bve.me/admin/api-keys?sort_by=updated_at&sort_dir=desc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Active keys sorted alphabetically by name:

Terminal window
curl "https://api.bve.me/admin/api-keys?status=active&sort_by=name&sort_dir=asc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

POST https://api.bve.me/admin/api-keys/:id/suspend
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Suspends an active key. Suspended keys are immediately rejected with 403 api_key_suspended on any request. Unlike revocation, suspension is reversible.

Only active keys can be suspended. Calling this on an already-suspended or revoked key returns 404.

ParameterDescription
idUUID of the active API key to suspend
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "suspended",
"updated_at": "2026-05-21T12:30:00.000Z"
}
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/suspend \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

POST https://api.bve.me/admin/api-keys/:id/unsuspend
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Restores a suspended key to active status. The key can make requests again immediately.

Only suspended keys can be unsuspended. Calling this on an active or revoked key returns 404.

ParameterDescription
idUUID of the suspended API key to reactivate
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"updated_at": "2026-05-21T12:45:00.000Z"
}
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/unsuspend \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

POST https://api.bve.me/admin/api-keys/:id/rotate
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Generates a new raw key value and immediately invalidates the old one. The key’s ID, status, rate limits, and model allowlist are preserved. Use this when a key has been exposed or as part of a routine rotation policy.

Only active and suspended keys can be rotated. Attempting to rotate a revoked key returns 404.

ParameterDescription
idUUID of the API key to rotate
{
"key": "sk-bve-a1b2c3d4...",
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"updated_at": "2026-05-22T16:00:00.000Z"
}
{
"error": {
"message": "API key not found or revoked",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/rotate \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

POST https://api.bve.me/admin/api-keys/:id/revoke
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Revocation is permanent and immediate. The key cannot be restored.

ParameterDescription
idUUID of the API key to revoke
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "revoked",
"revoked_at": "2026-05-21T13:00:00.000Z"
}

Returned when the key does not exist or is already revoked. Calling this endpoint twice on the same key returns 404 on the second call to prevent revoked_at from being overwritten.

{
"error": {
"message": "API key not found or already revoked",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/revoke \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

POST https://api.bve.me/admin/api-keys/bulk-revoke
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY
Content-Type: application/json

Revokes multiple API keys in a single request. Useful for emergency lockdowns, offboarding, or cleaning up a set of compromised keys. Revocation is immediate — affected keys are evicted from the auth cache so subsequent requests fail instantly.

Idempotent: already-revoked keys in the ids list are silently skipped. revoked_count reflects only keys that were actually transitioned to revoked.

FieldTypeRequiredDescription
idsstring[]YesArray of API key UUIDs to revoke. Minimum 1, maximum 100 per request.
{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}
{
"revoked_count": 2,
"revoked_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"total": 2
}
FieldTypeDescription
revoked_countintegerNumber of keys actually transitioned to revoked (skips already-revoked keys)
revoked_idsstring[]UUIDs of the keys that were newly revoked
totalintegerTotal number of IDs submitted (including any that were already revoked)

Returned when the request body is missing, malformed, or violates the 1–100 ID constraint.

{
"error": {
"message": "ids must contain at most 100 items",
"type": "invalid_request_error",
"param": "ids",
"code": "validation_error"
}
}

Returned when the Authorization header is missing or the token is invalid.

Terminal window
curl -X POST https://api.bve.me/admin/api-keys/bulk-revoke \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'

Revoke all active keys for an emergency lockdown (using key:list script):

Terminal window
# Get all active key IDs as JSON array
bun run key:list -- --status active --json | \
jq '{ ids: [.[].id] }' | \
curl -X POST https://api.bve.me/admin/api-keys/bulk-revoke \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d @-

POST https://api.bve.me/admin/api-keys/bulk-suspend
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY
Content-Type: application/json

Temporarily disables multiple active API keys in a single request. Useful for maintenance windows, security holds, or pausing a team’s credentials without permanent revocation. Suspension is immediate — affected keys are evicted from the auth cache so subsequent requests fail with 403 api_key_suspended instantly.

Unlike bulk revoke, suspended keys can be reactivated at any time via POST /admin/api-keys/bulk-unsuspend (or the single-key unsuspend endpoint).

Idempotent: already-suspended or revoked keys in the ids list are silently skipped. suspended_count reflects only keys that actually transitioned from activesuspended.

FieldTypeRequiredDescription
idsstring[]YesArray of API key UUIDs to suspend. Minimum 1, maximum 100 per request.
{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}
{
"suspended_count": 2,
"suspended_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"total": 2
}
FieldTypeDescription
suspended_countintegerNumber of keys actually transitioned to suspended (skips already-suspended or revoked keys)
suspended_idsstring[]UUIDs of the keys that were newly suspended
totalintegerTotal number of IDs submitted
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/bulk-suspend \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'

POST https://api.bve.me/admin/api-keys/bulk-unsuspend
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY
Content-Type: application/json

Reactivates multiple suspended API keys in a single request. Suspended keys are immediately restored to active status — affected keys are evicted from the auth cache so the updated status is read from D1 on the next request.

Idempotent: already-active or revoked keys in the ids list are silently skipped. unsuspended_count reflects only keys that actually transitioned from suspendedactive.

FieldTypeRequiredDescription
idsstring[]YesArray of API key UUIDs to unsuspend. Minimum 1, maximum 100 per request.
{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}
{
"unsuspended_count": 2,
"unsuspended_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"total": 2
}
FieldTypeDescription
unsuspended_countintegerNumber of keys actually transitioned to active (skips already-active or revoked keys)
unsuspended_idsstring[]UUIDs of the keys that were reactivated
totalintegerTotal number of IDs submitted
Terminal window
curl -X POST https://api.bve.me/admin/api-keys/bulk-unsuspend \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'

GET https://api.bve.me/admin/api-keys/:id/quota
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns the real-time quota consumption and configured limits for an API key. Minute and day counts come from the Durable Object (in-memory, reset at the window boundary). Monthly request and token totals come from D1. Use this to monitor remaining capacity without waiting for a 429.

ParameterDescription
idUUID of the API key
{
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"limits": {
"rpm": 60,
"rpd": 10000,
"monthly_requests": null,
"monthly_tokens": 500000
},
"current": {
"minute": {
"count": 3,
"remaining": 57,
"reset_at": "2026-05-22T12:01:00.000Z",
"reset_in_seconds": 42
},
"day": {
"count": 142,
"remaining": 9858,
"reset_at": "2026-05-23T00:00:00.000Z",
"reset_in_seconds": 42847
},
"month": {
"request_count": 2871,
"request_remaining": null,
"token_count": 187432,
"token_remaining": 312568,
"reset_at": "2026-06-01T00:00:00.000Z"
}
},
"checked_at": "2026-05-22T12:00:18.000Z"
}
FieldDescription
limits.monthly_requestsnull if no monthly request cap is set
limits.monthly_tokensnull if no monthly token cap is set
current.minute.remainingRequests available in the current minute window
current.day.remainingRequests available in the current day window
current.month.request_remainingnull if no monthly request cap
current.month.token_remainingnull if no monthly token cap
checked_atISO 8601 timestamp when this response was generated
{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}
Terminal window
curl https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/quota \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

GET https://api.bve.me/admin/api-keys/:id/stats
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns aggregate performance statistics for a single API key from the 1%-sampled request log: total request count, latency percentiles (avg/p50/p95/max), total tokens, error counts split by 4xx vs 5xx, and error rate.

ParameterDescription
idUUID of the API key
ParameterTypeRequiredDescription
sincestringNoInclude only log entries at or after this ISO 8601 timestamp. Invalid timestamps return 400 validation_error.
untilstringNoInclude only log entries at or before this ISO 8601 timestamp.

Both parameters are optional. Omit them to get all-time stats for this key.

{
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"total_requests": 142,
"stats": {
"avg_latency_ms": 1240,
"max_latency_ms": 8340,
"p50_latency_ms": 980,
"p95_latency_ms": 6200,
"total_tokens": 246860,
"error_count": 3,
"client_error_count": 2,
"server_error_count": 1,
"error_rate": 2.11
}
}
FieldTypeDescription
key_idstringUUID of the API key
total_requestsintegerNumber of sampled log entries for this key (~1% of actual requests)
stats.avg_latency_msnumber | nullAverage end-to-end latency in milliseconds. null if no entries.
stats.max_latency_msnumber | nullMaximum end-to-end latency seen in the sample window
stats.p50_latency_msnumber | nullMedian (50th percentile) latency — more representative than average for skewed distributions
stats.p95_latency_msnumber | null95th percentile latency — useful for tail-latency SLO alerting
stats.total_tokensintegerSum of prompt + completion tokens across all sampled entries
stats.error_countintegerSampled requests with HTTP status ≥ 400
stats.client_error_countintegerSampled requests with HTTP 4xx status (bad request, quota exceeded, auth failure)
stats.server_error_countintegerSampled requests with HTTP 5xx status (gateway or upstream failures)
stats.error_ratenumber(error_count / total_requests) × 100, rounded to 2 decimal places. 0 when total_requests is 0.

Returned when the key UUID does not exist.

{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}

All-time stats for a key:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/stats" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Stats for the last 7 days:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/stats?since=2026-05-18T00:00:00Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Alert on high error rate:

const res = await fetch(
`https://api.bve.me/admin/api-keys/${keyId}/stats`,
{ headers: { Authorization: `Bearer ${adminKey}` } },
);
const { stats } = await res.json();
if (stats.error_rate > 5) {
console.warn(`Key ${keyId} error rate: ${stats.error_rate.toFixed(2)}%`);
}

GET https://api.bve.me/admin/api-keys/:id/audit
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns the lifecycle history for a single API key: every create, update, suspend, unsuspend, revoke, rotate, and quota reset event that targeted this key. Entries are returned in descending chronological order (most recent first).

This is a scoped view of the global Audit Logs filtered to one key. The key difference: this endpoint returns 404 when the key does not exist, whereas GET /admin/audit-logs?target_id= silently returns an empty list.

ParameterDescription
idUUID of the API key
ParameterTypeRequiredDefaultDescription
actionstringNoExact action string to filter by (e.g. api_key.rotated, api_key.created). Returns only entries with this exact action.
action_categorystringNoFilter by action category: keys, auth, models, or admins. keys matches all api_key.* events. Invalid values return 400 validation_error.
searchstringNoSubstring match across action, target_id, and actor_type. Case-insensitive LIKE filter. Truncated to 200 characters.
sincestringNoISO 8601 timestamp. Return only entries at or after this time. Invalid values return 400 validation_error.
untilstringNoISO 8601 timestamp. Return only entries at or before this time.
limitintegerNo100Max entries per page (1–500).
offsetintegerNo0Number of entries to skip. Use with limit for cursor-free pagination.
{
"total": 4,
"has_more": false,
"logs": [
{
"id": "880e8400-e29b-41d4-a716-446655440003",
"action": "api_key.rotated",
"actor_type": "admin",
"target_type": "api_key",
"target_id": "550e8400-e29b-41d4-a716-446655440000",
"metadata": { "source": "legacy_admin_api" },
"created_at": "2026-05-22T09:00:00.000Z"
},
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"action": "api_key.updated",
"actor_type": "admin",
"target_type": "api_key",
"target_id": "550e8400-e29b-41d4-a716-446655440000",
"metadata": {
"changes": ["rpm_limit"],
"before": { "rpm_limit": 60 },
"after": { "rpm_limit": 120 },
"source": "legacy_admin_api"
},
"created_at": "2026-05-21T14:00:00.000Z"
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"action": "api_key.created",
"actor_type": "admin",
"target_type": "api_key",
"target_id": "550e8400-e29b-41d4-a716-446655440000",
"metadata": { "name": "my-client", "source": "legacy_admin_api" },
"created_at": "2026-05-21T12:00:00.000Z"
}
]
}
FieldTypeDescription
totalintegerTotal number of audit entries for this key matching the current filters (before limit/offset). Use for pagination.
has_morebooleantrue when offset + len(logs) < total. Shorthand for detecting additional pages without computing pagination math.
logsarrayArray of audit log entries (see below).
FieldTypeDescription
idstringUUID of the audit log entry
actionstringAction type (see Audit Logs — Action types)
actor_typestring"admin" for Admin API operations; "admin_user" for dashboard actions
target_typestringAlways "api_key" for this endpoint
target_idstringUUID of the API key (same as the :id path parameter)
metadataobject | nullAction-specific JSON details. For api_key.updated: includes changes (array of changed field names), before, and after objects. For api_key.quota_reset: includes window. Most entries include source: "legacy_admin_api" when triggered via the Admin API.
created_atstringISO 8601 timestamp of the event
{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}

Full audit history for a key:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Audit events since a date:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?since=2026-05-01T00:00:00Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Audit events in a date range:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?since=2026-05-01T00:00:00Z&until=2026-05-31T23:59:59Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Only rotation events:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?action=api_key.rotated" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

All key lifecycle events (create/update/rotate/suspend/unsuspend/revoke):

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?action_category=keys" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Paginate (page 2, 50 entries per page):

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?limit=50&offset=50" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Substring search across action/target (e.g. all “rotated” events):

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/audit?search=rotated" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Most recent 5 events (using bun run key:audit):

Terminal window
bun run key:audit -- --id 550e8400-e29b-41d4-a716-446655440000 --limit 5

Search by keyword (using bun run key:audit):

Terminal window
bun run key:audit -- --id 550e8400-e29b-41d4-a716-446655440000 --search rotated
StatusCodeCause
400validation_errorsince or until is not a parseable ISO 8601 timestamp, or action_category is not one of auth, keys, models, admins
401missing_api_keyNo Authorization header
401invalid_api_keyAdmin key does not match the configured ADMIN_API_KEY secret
404not_foundNo API key with the given UUID exists

GET https://api.bve.me/admin/api-keys/:id/usage
Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

Returns daily and monthly usage rows scoped to a single API key. This is a convenience wrapper around GET /admin/usage?key_id= with one key difference: it returns 404 when the key UUID does not exist, whereas the generic usage endpoint silently returns empty arrays.

ParameterDescription
idUUID of the API key
ParameterTypeRequiredDefaultDescription
fromstringNoEarliest date to include, in YYYY-MM-DD format. Filters daily rows by date and monthly rows by year-month prefix.
tostringNoLatest date to include, in YYYY-MM-DD format.
daily_limitintegerNo30Max daily rows to return (1–500).
monthly_limitintegerNo12Max monthly rows to return (1–500).

from and to can be combined to select a specific window. Invalid date strings (not-a-date, 2026-13-01) return 400 validation_error. from must not be after to.

{
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"daily": [
{
"id": "aa0e8400-e29b-41d4-a716-446655440001",
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"date": "2026-05-30",
"request_count": 47,
"prompt_tokens": 12840,
"completion_tokens": 3210,
"total_tokens": 16050,
"updated_at": "2026-05-30T23:00:00.000Z"
},
{
"id": "bb0e8400-e29b-41d4-a716-446655440002",
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"date": "2026-05-29",
"request_count": 63,
"prompt_tokens": 18200,
"completion_tokens": 4900,
"total_tokens": 23100,
"updated_at": "2026-05-29T23:00:00.000Z"
}
],
"monthly": [
{
"id": "cc0e8400-e29b-41d4-a716-446655440003",
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"year_month": "2026-05",
"request_count": 1420,
"prompt_tokens": 412800,
"completion_tokens": 108600,
"total_tokens": 521400,
"updated_at": "2026-05-30T23:00:00.000Z"
}
]
}

daily[] row:

FieldTypeDescription
idstringRow UUID (internal)
key_idstringUUID of the API key this row belongs to
datestringCalendar date in YYYY-MM-DD format
request_countintegerRequests recorded on this date
prompt_tokensintegerPrompt token total for this date
completion_tokensintegerCompletion token total for this date
total_tokensintegerSum of prompt + completion tokens
updated_atstringISO 8601 timestamp of last write

monthly[] row:

FieldTypeDescription
idstringRow UUID (internal)
key_idstringUUID of the API key this row belongs to
year_monthstringMonth in YYYY-MM format
request_countintegerRequests recorded this month
prompt_tokensintegerPrompt token total for this month
completion_tokensintegerCompletion token total for this month
total_tokensintegerSum of prompt + completion tokens
updated_atstringISO 8601 timestamp of last write

Rows are ordered newest-first. The key_id field at the top level confirms which key was queried.

{
"error": {
"message": "API key not found",
"type": "invalid_request_error",
"param": null,
"code": "not_found"
}
}

Full usage history (last 30 daily + 12 monthly rows):

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/usage" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Last 7 days only:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/usage?from=2026-05-23&to=2026-05-30" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

90 days of daily data for a billing report:

Terminal window
curl "https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/usage?daily_limit=90" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

TypeScript — compute total tokens for May 2026:

const res = await fetch(
'https://api.bve.me/admin/api-keys/550e8400-e29b-41d4-a716-446655440000/usage?from=2026-05-01&to=2026-05-31&daily_limit=31',
{ headers: { Authorization: 'Bearer admin_bve_YOUR_ADMIN_KEY' } },
);
const { daily } = await res.json() as { daily: Array<{ total_tokens: number }> };
const monthTotal = daily.reduce((sum, d) => sum + d.total_tokens, 0);
console.log('May 2026 tokens:', monthTotal);
StatusCodeCause
400validation_errorfrom or to is not YYYY-MM-DD; from is after to
401missing_api_keyNo Authorization header
401invalid_api_keyAdmin key does not match the configured ADMIN_API_KEY secret
404not_foundNo API key with the given UUID exists