Usage accounting
Every request through the gateway produces a record. This page is the schema and the access patterns.
Per-request record
The fields stored for each request:
generation_id- Opaque, globally unique. Returned in the response and used to look up the record later.
created_at- UTC timestamp when the gateway accepted the request.
api_key_id- The API key used. Names are joined in for display.
user_identifier- Identifier of the account the key belongs to.
model_id- The model that served the request. When the caller sent an auto-routed or aliased ID (e.g.
auto/mistralai/mistral-large-2512), this is the resolved route. provider_id- Upstream provider that served the request.
region- Region the upstream served from.
prompt_tokens- Token count of the input.
completion_tokens- Token count of the output.
total_tokens- Sum.
latency_ms- First-byte latency for streaming, end-to-end for non-streaming.
request_duration_ms- Total request duration measured at the gateway.
cost- Amount debited for this request, in EUR.
energy_wh- Estimated energy for the inference, in watt-hours.
carbon_gco2e- Estimated CO₂e for the request, in grams.
routing_mode- How the model was selected (e.g. explicit vs. auto).
routing_reason- Why the router picked this model/provider.
fallback_occurred- Whether a fallback provider served the request after a primary failed.
status_code- HTTP status returned to the caller.
Prompt and response content are not stored.
Where to read it
- API lookup — a completion response carries an
id(the samechatcmpl-…/cmpl-…value OpenAI clients already read). Pass it toGET /v1/generation/{id}for the full record, or toGET /v1/metrics/{id}for just the token/energy/carbon figures. Both require the same API key and only return records billed to that key’s account. See Looking up a generation below. - Dashboard → Recent transactions — the last ~50 requests, with filtering by date range, model, provider, region, key.
- Transaction detail page — the full record for a single request,
accessed by clicking a row in the transactions table (the detail
path is keyed on the transaction’s
referenceId). - Export — Dashboard → Recent transactions → Export produces a CSV of the filtered range, capped at 50,000 rows per export. Use this for programmatic queries, reconciliation, or piping into your own data warehouse.
Looking up a generation
Every completion response includes a top-level id. That value is the
generation’s lookup key — there is no separate generation_id field in
the response body.
# The id from a prior chat/completions response
GENERATION_ID="chatcmpl-abc123"
curl https://api.lowrouter.ai/v1/generation/$GENERATION_ID \
-H "Authorization: Bearer $LOWROUTER_API_KEY"The record is scoped to the calling key’s account: a key can only read
generations billed to its own customer. An unknown id — or one that
belongs to another account — returns 404, so the id space can’t be
probed across accounts.
For just the metrics (tokens, energy, carbon, duration) without the
routing detail, use GET /v1/metrics/{id} with the same id.
Aggregates
The dashboard pre-computes a small set of aggregates and updates them on each request:
- Tokens per day, per model.
- Cost per day, per model.
- Energy and carbon per day, per model.
These aggregates power the charts. They are derived from the per-request records and are reproducible from a CSV export.
Retention
| Data | Retention |
|---|---|
| Per-request records | 13 months from created_at. |
| Daily aggregates | 36 months. |
| Audit log entries | 36 months. |
| Account profile | For the lifetime of the account. |
After retention expires the per-request rows are deleted and replaced by anonymised aggregates. Aggregates are kept for sustainability reporting and platform analytics; they cannot be used to reconstruct individual requests.
You can request earlier deletion of all your usage records via the support email; the deletion is irreversible and may affect your ability to dispute past invoices.
Reconciliation tips
- The sum of
costover a day should equal the daily cost on the dashboard within a rounding tolerance. - The sum of
total_tokensover a day grouped by model is what the upstream provider’s usage report (if you have one) should show. - The carbon estimate is reproducible: given the same
model_id,region, andtotal_tokens, recomputing with the formula in methodology should yield the same gram count.
If the numbers diverge more than rounding allows, that is a bug — open an issue.
