Skip to content

Authentication

BVE Gateway uses two separate authentication schemes — one for public API access and one for admin operations.

Public API keys authenticate requests to /v1/* endpoints.

Format: sk-bve- followed by 64 lowercase hex characters.

Example: sk-bve-a1b2c3d4e5f6... (71 characters total)

Keys are provisioned by an admin via POST /admin/api-keys and are only shown once at creation time. They are never stored in plain text — only sha256(key + pepper) is stored in D1.

Use the Authorization header with the Bearer scheme:

Authorization: Bearer sk-bve-YOUR_KEY
CodeStatusMeaning
missing_api_key401No Authorization header
invalid_api_key401Header is not Bearer, key lacks sk-bve- prefix, or key not found in DB
api_key_expired401Key exists but its expires_at date is in the past
api_key_suspended403Key exists but is suspended
api_key_revoked403Key has been revoked

All error responses use the OpenAI error format.

StatusCan make requests
activeYes (unless expires_at is in the past — see below)
suspendedNo (403 api_key_suspended)
revokedNo (403 api_key_revoked)
expiredNo (401 api_key_expired) — status stays active; expiry is determined by expires_at

Keys with expires_at in the past return 401 api_key_expired even though their status field is still active. Reactivate by PATCHing expires_at to a future date or null via PATCH /admin/api-keys/:id.

Admin routes (/admin/*) require the ADMIN_API_KEY secret set in the Worker environment.

Format: Any string — set by the operator.

Convention: Use a long random string (not the sk-bve- format).

Example placeholder: admin_bve_YOUR_ADMIN_KEY

Pass it the same way as a public key:

Authorization: Bearer admin_bve_YOUR_ADMIN_KEY

The admin auth middleware also accepts the token without the Bearer prefix, but using the full Bearer scheme is recommended.

BVE Gateway allows cross-origin requests from any origin (*).

Allowed request headers:

HeaderPurpose
AuthorizationAPI key (Bearer sk-bve-…)
Content-TypeRequest body type
X-Request-IdClient-provided request ID
OpenAI-BetaOpenAI beta feature flags (e.g. assistants=v2)
Anthropic-VersionAnthropic API version (e.g. 2023-06-01)
Anthropic-BetaAnthropic beta feature flags (e.g. interleaved-thinking-2025-05-14)
x-api-keyAlternative API key header accepted by the Anthropic SDK in browser contexts — the gateway maps this to Authorization: Bearer and strips it before forwarding to Fuelix

Exposed response headers (readable by browser JS):

HeaderDescription
X-Request-IdGateway request UUID
X-BVE-LatencyTotal gateway latency in ms
X-BVE-ModelModel ID resolved for the request (from response JSON when buffered, from request body for streaming)
X-BVE-Key-NameOperator-assigned display name of the API key that authenticated the request (e.g. "ci-bot", "production-app"). Absent on 401/403 error responses — only emitted after successful authentication
X-BVE-CacheModel list cache status: HIT, STALE, or MISS (only on GET /v1/models) — see Models — Model list caching
X-Quota-Allowed, X-Quota-Available, X-Quota-ResetFuelix quota headers (forwarded when present)
X-RateLimit-Limit-Requests, X-RateLimit-Remaining-Requests, X-RateLimit-Reset-RequestsPer-key RPM limit, remaining capacity, and reset time
X-RateLimit-Limit-Day, X-RateLimit-Remaining-Day, X-RateLimit-Reset-DayPer-key RPD limit, remaining capacity, and reset time
X-RateLimit-Limit-Month, X-RateLimit-Remaining-Month, X-RateLimit-Reset-MonthMonthly request limit, remaining requests, and reset time (only when monthly_limit is set)
X-RateLimit-Limit-Tokens, X-RateLimit-Remaining-Tokens, X-RateLimit-Reset-TokensMonthly token limit, remaining tokens, and reset time (only when monthly_token_limit is set)
Retry-AfterSeconds until the rate-limit window resets (present on 429/503)
Anthropic-RateLimit-Requests-Limit, Anthropic-RateLimit-Requests-Remaining, Anthropic-RateLimit-Requests-ResetAnthropic Messages API request-count rate limits
Anthropic-RateLimit-Tokens-Limit, Anthropic-RateLimit-Tokens-Remaining, Anthropic-RateLimit-Tokens-ResetAnthropic Messages API combined token rate limits
Anthropic-RateLimit-Input-Tokens-Limit, Anthropic-RateLimit-Input-Tokens-Remaining, Anthropic-RateLimit-Input-Tokens-ResetAnthropic Messages API input-token rate limits (allows distinguishing prompt vs. output budget exhaustion)
Anthropic-RateLimit-Output-Tokens-Limit, Anthropic-RateLimit-Output-Tokens-Remaining, Anthropic-RateLimit-Output-Tokens-ResetAnthropic Messages API output-token rate limits
X-Groq-Request-IdGroq request ID for log correlation
OpenAI-Processing-MsOpenAI server-side processing time
X-OpenRouter-ModelActual model selected by OpenRouter after provider routing (e.g. openai/gpt-4o)
X-Or-Cache-StatusOpenRouter semantic cache result: HIT or MISS
X-Or-Remaining-TokensToken budget remaining in the OpenRouter rate-limit window

Preflight responses are cached for 24 hours (Access-Control-Max-Age: 86400).