503 and the page shows that error; with a store but no rows yet, the page shows how to send a first request.
Find a call
- Open Observability → Relay Logs.
- Choose a time window. Filter by relay, method, status, billable, virtual key and, where your access allows, user, team, customer, business unit and project. Cost bounds and a request id narrow further.
- Search matches the path, matched route, model and request id. It does not search bodies.
- Select a row to open its details. Live polls for new rows.
Read a row
The details sheet opens on a hero card with the kind (Call), a Streamed badge where it applies, the status and HTTP code, a Not billable badge for free calls, the route, the request id, and four headline figures: latency, units (or tokens), cost and bytes out. More details expands into:- Timings — start and end, total latency, Upstream Latency (time blocked on the upstream socket) and Bifrost Overhead (the rest), with the per-stage overhead breakdown once the trace completes.
- Cost — the figure charged and every term behind it: fee per call, price per unit, units read, units billed, reported cost, and token counts when mapped (marked not priced).
- Request Details — relay, kind, detected client App (from the
User-Agent), method, path and query, matched route, billable, streamed, model, and the virtual key, user, team, customer, business unit and project. - Metadata — the same map LLM and MCP rows carry: the request headers the
client.logging_headerssetting names (exact names and wildcard patterns), everyx-bf-lh-*header as a label (prefix stripped), thex-bf-dim-*dimensions, and the virtual key’s own metadata. - Matched Headers — the headers the matched route matches on, with the value that selected the route: the relay’s own extra header when it sets that header, else the caller’s. They decided the route and its price. A value the relay reads from the environment or a vault is stored redacted. No other header, and never the reply’s, is stored. Metadata and matched headers stay on the row when content logging is off; only bodies and the query string are content.
Content logging
Bodies and the query string are content, and follow the same content logging decision as LLM rows:client.disable_content_logging, the virtual key’s and project’s overrides, and the x-bf-disable-content-logging request header when per-request overrides are allowed. A row whose content is hidden keeps its metadata and cost and shows Content logging has been disabled for this request. Query parameters that carry credentials (key, token, api_key, signature, …) are redacted before the path is stored even when content is kept.
Row statuses
A call refused before the hooks (unknown relay, no matching route, an unmeasurable request body) returns
404 or 400 to the caller and writes no row.
Query the API
Next steps
- Content logging — Decide what the bodies columns keep.
- Latency breakdown — How upstream latency and Bifrost overhead are measured.
- Troubleshooting — Work from a row’s status to the cause.

