Skip to content

Request Logs

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

Returns a sampled log of recent API requests. The gateway records approximately 1% of all requests (streaming and non-streaming) to this table, providing a representative sample without the storage cost of logging every call.

ParameterTypeRequiredDefaultDescription
key_idstringNoFilter by API key UUID (exact match)
modelstringNoFilter by model ID, e.g. gpt-4o (exact match)
endpointstringNoFilter by gateway endpoint path, e.g. /v1/chat/completions (exact match)
request_idstringNoExact lookup by BVE request UUID — the same UUID returned in the X-Request-Id response header. Returns the single sampled log entry for that request, or an empty result if not in the 1% sample.
error_codestringNoFilter to only requests that were rejected with this error code (exact match). Common values: rate_limit_exceeded, model_not_allowed, invalid_request_error, authentication_error. Returns only sampled gateway-rejection rows; rows with no error code (successful requests) are excluded.
status_rangestringNoHTTP status class filter. Accepted values: 2xx (successful), 4xx (client errors), 5xx (server errors). Returns 400 validation_error for any other value.
searchstringNoFree-text substring filter applied across endpoint, model, and key_name columns (case-insensitive LIKE match, truncated to 200 chars).
sincestringNoReturn only entries at or after this ISO 8601 timestamp (e.g., 2026-05-01T00:00:00Z). Passing an invalid timestamp returns 400 validation_error.
untilstringNoReturn only entries at or before this ISO 8601 timestamp. Combine with since for a bounded time window. Passing an invalid timestamp returns 400 validation_error.
min_latency_msintegerNoReturn only entries where latency_ms is at or above this value (non-negative integer). Use to isolate slow requests.
max_latency_msintegerNoReturn only entries where latency_ms is at or below this value (non-negative integer). Combine with min_latency_ms for a range filter. Returns 400 validation_error if min > max.
min_upstream_latency_msintegerNoReturn only entries where upstream_latency_ms is at or above this value. Useful for isolating requests where Fuelix itself was slow (as distinct from gateway overhead).
max_upstream_latency_msintegerNoReturn only entries where upstream_latency_ms is at or below this value. Returns 400 validation_error if min > max.
sort_bystringNocreated_atSort field. Accepted values: created_at, latency_ms, upstream_latency_ms, status. Returns 400 validation_error for any other value.
sort_dirstringNodescSort direction. Accepted values: asc, desc. Returns 400 validation_error for any other value.
limitintegerNo100Max entries to return (1–500)
offsetintegerNo0Number of entries to skip. Use with ?limit= for cursor-free pagination.

All parameters are optional and combinable. For example, ?key_id=<uuid>&status_range=4xx&since=2026-05-01T00:00:00Z returns only client-error requests for a specific key since May 1.

{
"total": 412,
"stats": {
"avg_latency_ms": 843,
"max_latency_ms": 4210,
"p50_latency_ms": 720,
"p95_latency_ms": 3100,
"total_tokens": 128450,
"error_count": 15,
"client_error_count": 12,
"server_error_count": 3,
"error_rate": 0.036
},
"logs": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"key_id": "550e8400-e29b-41d4-a716-446655440000",
"key_name": "production-app",
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "gpt-4o",
"endpoint": "/v1/chat/completions",
"status": 200,
"prompt_tokens": 128,
"completion_tokens": 64,
"latency_ms": 1234,
"upstream_latency_ms": 1180,
"error_code": null,
"created_at": "2026-05-21T12:00:00.000Z"
}
]
}
FieldTypeDescription
totalintegerTotal number of sampled log entries matching the current filters (ignores limit/offset). Use for pagination UI.
statsobjectAggregate statistics computed across all matching rows (not limited by limit/offset). See Stats object fields.
logsarrayArray of log entry objects (see below).
FieldTypeDescription
avg_latency_msnumber | nullMean gateway-to-upstream latency across matching rows. null if no rows.
max_latency_msnumber | nullMaximum latency among matching rows. null if no rows.
p50_latency_msnumber | nullMedian (50th percentile) latency. null if no rows.
p95_latency_msnumber | null95th percentile latency — use this for tail-latency alerting. null if no rows.
total_tokensintegerSum of prompt_tokens + completion_tokens across all matching rows.
error_countintegerNumber of rows where the HTTP status is 4xx or 5xx.
client_error_countintegerNumber of rows where the HTTP status is 4xx (bad API key, quota exceeded, model blocked, validation error).
server_error_countintegerNumber of rows where the HTTP status is 5xx (upstream failures, gateway errors).
error_ratenumbererror_count / total — fraction of sampled requests that resulted in an error. 0 if no rows.

The stats object covers all rows matching the current filter set, regardless of limit/offset. It is computed in a parallel query alongside the logs page fetch, adding no extra latency.

FieldTypeDescription
idstringUUID of the log entry
key_idstringUUID of the API key that made the request
key_namestring | nullHuman-readable name of the API key (null if the key has no name set)
request_idstring | nullThe X-Request-Id UUID assigned to the request and forwarded to Fuelix. Use this to correlate a sampled log row with Fuelix-side traces or with the X-Request-Id response header your client received. Null for requests logged before migration 0005.
modelstring | nullModel ID from the upstream response body
endpointstringGateway path (e.g. /v1/chat/completions)
statusintegerHTTP status code returned to the client
prompt_tokensintegerPrompt token count from the upstream response
completion_tokensintegerCompletion token count from the upstream response
latency_msintegerTotal gateway round-trip latency in ms (request received → upstream response body received).
upstream_latency_msinteger | nullTime Fuelix spent generating the response in ms — i.e. total latency minus gateway overhead. null for requests that were rejected by the gateway before reaching Fuelix (auth errors, quota, model filter).
error_codestring | nullGateway-level rejection code when the request was blocked before reaching Fuelix. Common values: rate_limit_exceeded (429 quota hit), model_not_allowed (403 key/global block), invalid_request_error (400 validation failure), authentication_error (401 bad key). null for successfully proxied requests.
created_atstringISO 8601 timestamp
Terminal window
curl "https://api.bve.me/admin/request-logs" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
Terminal window
curl "https://api.bve.me/admin/request-logs?key_id=550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
Terminal window
curl "https://api.bve.me/admin/request-logs?since=2026-05-01T00:00:00Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Combine since and until to query a bounded time window:

Terminal window
curl "https://api.bve.me/admin/request-logs?since=2026-05-01T00:00:00Z&until=2026-05-31T23:59:59Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
Terminal window
curl "https://api.bve.me/admin/request-logs?limit=10" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
Terminal window
curl "https://api.bve.me/admin/request-logs?model=gpt-4o" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?error_code= to find all sampled gateway-rejection logs of a specific type:

Terminal window
# All sampled rate-limit rejections (RPM/RPD/monthly quotas)
curl "https://api.bve.me/admin/request-logs?error_code=rate_limit_exceeded" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# All sampled model-not-allowed rejections for a specific key
curl "https://api.bve.me/admin/request-logs?key_id=550e8400-e29b-41d4-a716-446655440000&error_code=model_not_allowed" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?status_range= to isolate successful, client-error, or server-error requests:

Terminal window
# Only 2xx (successful) requests
curl "https://api.bve.me/admin/request-logs?status_range=2xx" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Only 4xx (client errors, e.g. invalid requests, quota exceeded)
curl "https://api.bve.me/admin/request-logs?status_range=4xx" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Only 5xx (gateway or upstream failures)
curl "https://api.bve.me/admin/request-logs?status_range=5xx" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?search= to filter by a substring across endpoint, model, and key_name:

Terminal window
# All logs where endpoint, model, or key name contains "embedding"
curl "https://api.bve.me/admin/request-logs?search=embedding" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
Terminal window
curl "https://api.bve.me/admin/request-logs?endpoint=/v1/chat/completions" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Each API response includes an X-Request-Id header. If a client reports an error with that ID, pass it as ?request_id= to do an exact server-side lookup (result is empty if the request was not in the 1% sample):

Terminal window
# The client received X-Request-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
curl "https://api.bve.me/admin/request-logs?request_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?min_latency_ms= and ?max_latency_ms= to find slow or fast requests by total round-trip latency:

Terminal window
# All sampled requests that took more than 3 seconds
curl "https://api.bve.me/admin/request-logs?min_latency_ms=3000" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Requests between 1 and 5 seconds
curl "https://api.bve.me/admin/request-logs?min_latency_ms=1000&max_latency_ms=5000" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?min_upstream_latency_ms= to isolate requests where the model itself was slow, separate from gateway overhead:

Terminal window
# Requests where Fuelix took more than 2 seconds
curl "https://api.bve.me/admin/request-logs?min_upstream_latency_ms=2000" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# gpt-4o requests with slow upstream, sorted slowest first
curl "https://api.bve.me/admin/request-logs?model=gpt-4o&min_upstream_latency_ms=2000&sort_by=upstream_latency_ms&sort_dir=desc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?sort_by= with ?sort_dir= to control ordering. The default is sort_by=created_at&sort_dir=desc (most recent first):

Terminal window
# Slowest requests first (by total latency)
curl "https://api.bve.me/admin/request-logs?sort_by=latency_ms&sort_dir=desc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Fastest requests first (by total latency)
curl "https://api.bve.me/admin/request-logs?sort_by=latency_ms&sort_dir=asc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Sort by HTTP status code ascending (group 2xx before 4xx before 5xx)
curl "https://api.bve.me/admin/request-logs?sort_by=status&sort_dir=asc" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Valid sort_by values: created_at, latency_ms, upstream_latency_ms, status.

Terminal window
curl "https://api.bve.me/admin/request-logs?model=gpt-4o&endpoint=/v1/chat/completions&since=2026-05-01T00:00:00Z" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Use ?limit= and ?offset= together for cursor-free pagination:

Terminal window
# Page 1 — first 50 entries
curl "https://api.bve.me/admin/request-logs?limit=50&offset=0" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
# Page 2 — next 50 entries
curl "https://api.bve.me/admin/request-logs?limit=50&offset=50" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"

Combine with any filter parameter to paginate filtered results:

Terminal window
curl "https://api.bve.me/admin/request-logs?model=gpt-4o&limit=50&offset=50" \
-H "Authorization: Bearer admin_bve_YOUR_ADMIN_KEY"
  • Entries are inserted with 1% probability per request. At 100 RPM a key produces roughly 1 sampled row per minute.
  • Token counts are always accurate for sampled rows because the gateway buffers or tees the response body before sampling.
  • latency_ms is total gateway round-trip time from request received to last byte of the upstream response. It includes gateway overhead (auth, quota checks, model filter) plus Fuelix response time.
  • upstream_latency_ms isolates Fuelix’s own response time (the Fuelix-side clock, not including network). It is null when the request was rejected by the gateway before reaching Fuelix (auth, quota, model filter errors).
  • request_id is null for rows logged before D1 migration 0005 (which added the column). All rows written after that migration include the UUID.
  • The X-Request-Id header is also returned on every API response so clients can record it for support requests.
  • The default sort order is sort_by=created_at&sort_dir=desc (most recent first). Explicit sort_by and sort_dir override this.
  • The stats aggregate is computed over all rows matching the current filters regardless of sort_by / sort_dir / limit / offset.
  • Request log rows are pruned by the daily cron job after 90 days.