Skip to content

Request inspection

Every call gets a request id (req_…) before Belarel does any work. Log it with your own records: it lets you look the call up later — its status, usage, final cost and tags — and it is the one thing support needs to trace a call.

Where Format
X-Request-Id response header req_ followed by 32 hex characters.
belarel.request_id in a successful answer The same value.
The id of a Responses answer resp_ + the same hex: resp_6f1c… names the same call as req_6f1c….
belarel.request_id in an error body Only on policy refusals; otherwise read the header.

The header is set on every answer of the inference endpoints (/v1/chat/completions, /v1/responses, /v1/embeddings) and of GET /v1/models, /v1/usage, /v1/requests/{id}, /v1/key and /v1/credits — refusals included (except 405 Method Not Allowed), and before a stream starts. The key-management endpoints (/v1/keys, /v1/keys/{id}) do not set it. A Chat Completions id (chatcmpl-…) is not the request id.

The official OpenAI SDKs read X-Request-Id for you:

Terminal window
curl -si https://api.belarel.com/v1/chat/completions \
-H "Authorization: Bearer $BELAREL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "<model-id>", "messages": [{"role": "user", "content": "Hello"}]}' \
| grep -i '^x-request-id'

GET /v1/requests/{id} (scope usage:read) returns one call made by the key or by one of its sub-keys. Pass either the req_… or the resp_… form. The answer is limited to the fields shown below: nothing else about the call is published.

Terminal window
curl https://api.belarel.com/v1/requests/req_6f1c0a7e2b9d4c3f8e5a1b2c3d4e5f60 \
-H "Authorization: Bearer $BELAREL_API_KEY"
{
"object": "request",
"request_id": "req_6f1c0a7e2b9d4c3f8e5a1b2c3d4e5f60",
"api_key_id": "5b0e…",
"created_at": "2026-10-02T14:03:11.204+00:00",
"status": "succeeded",
"http_status": 200,
"duration_ms": 1843,
"model_served": "<model-id>",
"usage": { "input_tokens": 1250, "output_tokens": 310, "cached_tokens": 1024, "cache_write_tokens": 0, "reasoning_tokens": 128 },
"cost": { "usd": 0.000412, "credits": 0.412, "source": "reconciled", "reserved_usd": 0.0061, "settled_usd": 0.000412, "reservation": "settled" },
"tags": { "customer": "acme", "feature": "support" }
}
Field Meaning
status succeeded, failed, or blocked (stopped by a platform safety check on the model, such as a model switched off).
http_status, duration_ms What the call answered, and how long it took.
model_served The model that served the call.
usage Input, output, cached, cache-write and reasoning tokens.
cost.usd, cost.credits The cost at your organization’s sale price.
cost.source pending (not known yet — and permanent when no cost could be computed; read cost.settled_usd then), estimated (computed when the call closed), reconciled (confirmed against the provider’s real cost).
cost.reserved_usd, cost.settled_usd, cost.reservation What the call reserved against your caps, what it settled at, and the reservation’s state: open, settled or released. For a failed call, see what a failed call counts.
tags The call’s tags, defaults and application tags included. See Tags & attribution.

A sandbox call is never billed: its cost.usd and cost.credits stay null and cost.source reads pending. Sandbox embeddings calls are not recorded at all.

A call is recorded once it reaches the model step — served, failed, or blocked there. A call refused before that — invalid key, missing scope, tag error, policy refusal, spend cap, rate limit, insufficient credits — is not recorded: looking up its id answers 404 not_found. Its X-Request-Id is still useful to support.

This endpoint never returns the content of a call: no prompts, no outputs. It also does not return the finish reason, nor the provider that served the model. To keep the finish reason, log it from the answer on your side. For how content is handled, see Data handling.

Code HTTP Meaning What to do
not_found 404 No call with this id for this key or its sub-keys — another key’s call, a malformed id, or a call refused before the model step. Check the id and the key you query with.
scope_denied 403 The key lacks the usage:read scope. Use a key with usage:read.
admission_unavailable 503 The record could not be read. Retry after Retry-After.

Send the request id, the approximate time (UTC) and the HTTP status you received. The id is how support locates a call; you never need to send your prompt.