Usage accounting
Understand which metrics each scope records, how usage is attributed, and which endpoint to query.
Choose an endpoint
Use the endpoint that matches the level of detail you need:
- Live totals: aggregated counters per period, optimised for quick dashboards and budget checks. Read them from
/v1/account/usage. - Request history: one entry per request with status, latency, and recorded usage. Read it from
/v1/account/history. - Token identity and usage: let a portal, API, or agent token inspect its own identity, permissions, limits, and usage through
/v1/meand/v1/me/usage.
Metrics per scope
Each service scope records the metrics relevant to its work:
completionsscope- tokens, prompt_tokens, completion_tokens
decisionsscope- requests, questions, input_characters, prompt_tokens, completion_tokens, total_tokens
ocrscope- requests, prompt_tokens, completion_tokens, output_characters, pages
languagescope- requests, corrections
piiscope- requests, entities_found, entities_redacted, replacements_made
prompt_shieldscope- requests, detections_count
sttscope- requests, audio_duration_seconds
ttsscope- requests, characters_synthesised, output_audio_seconds
Live totals: /v1/account/usage
/v1/account/usageReturn aggregated counters for the authenticated user, grouped by scope and model.
Request
periodstring- minute, day (default), week or month. Defines the time window.
scopestring- Optional filter, e.g. completions.
model_dimensionstring- Group the `models` map by the org-level profile id (default `profile`, e.g. `qwen3.5-35b:chat`) or by the upstream base model id used for billing (`base`, e.g. `qwen3.5-35b`). Multiple profiles roll up onto one base in `base` mode.
Response · 200
// model_dimension=profile (default)
{
"period": "day",
"model_dimension": "profile",
"scopes": {
"completions": {
"tokens": 5200,
"prompt_tokens": 3100,
"completion_tokens": 2100
}
},
"models": {
"qwen3.5-35b:chat": {
"tokens": 5200,
"prompt_tokens": 3100,
"completion_tokens": 2100
}
}
}
// model_dimension=base (billing-aligned)
{
"period": "day",
"model_dimension": "base",
"scopes": { /* unchanged */ },
"models": {
"qwen3.5-35b": {
"tokens": 5200,
"prompt_tokens": 3100,
"completion_tokens": 2100
}
}
}Reading the response
scopesis keyed by scope name. Each value is a metric-count map matching the table above.modelsis keyed by model ID: the addressable profile id by default (e.g.qwen3.5-35b:chat), or the upstream base model id whenmodel_dimension=base. Only completions traffic contributes, since only completions track per-model counts. The echoedmodel_dimensionfield tells you which lens the rollup used.- An empty
{}object means no usage was recorded in the selected period. Use request history for per-request records. - The completions totals do not include a
requestscounter; use request history to count completion requests. The language, PII, STT, and TTS scopes do include request counts.
Request history: /v1/account/history
/v1/account/historyReturn paginated request records for the authenticated user.
Request
pagenumber- Page number (1-based). Default 1.
per_pagenumber- Page size. Default 50, max 100.
scopestring- Filter by scope.
modelstring- Filter by model ID.
statusstring- Filter by success, rejected, error, or aborted. Rejected indicates a policy refusal; error indicates a service or network failure.
Response · 200
{
"data": [
{
"id": "uuid",
"user_id": "uuid",
"scope": "completions",
"model_id": "qwen3.5-35b",
"endpoint": "/v1/chat/completions",
"usage": {
"prompt_tokens": 200,
"completion_tokens": 150,
"processors": {
"anonymise": { "entities_redacted": 2 }
}
},
"latency_ms": 870,
"status": "success",
"stream": false,
"timestamp": "2026-04-15T14:30:00.000Z"
}
],
"meta": {
"total": 200,
"per_page": 50,
"current_page": 1,
"last_page": 4
}
}Timezone. timestamp is the absolute UTC instant. The portal renders it (and chart period boundaries) in your profile timezone. Change it under Profile → Settings, or override it per completion via inferada.timezone.
Self-introspection: /v1/me
/v1/me returns the identity, permissions, and limits associated with the bearer token. It accepts portal, API, and agent tokens. The endpoint cannot inspect another principal. The @inferada-ai/sdk client exposes these operations as inferada.token.info() and inferada.token.usage().
/v1/meIdentity, organisation, the calling token (with its own imposed limits), and the permission keys this caller may exercise.
Response · 200
{
"principal": "agent", // or "user"
"id": "agt_7f3c…", // user id or agent id
"organisation": { "id": "uuid", "name": "Acme", "slug": "acme" },
"token": {
"id": 42,
"name": "prod-agent",
"abilities": ["completions"], // the token's coarse scopes
"expires_at": null, // ISO-8601 or null
"limits": [
{ "metric": "requests", "period": "minute", "max": 60 }
]
},
"permissions": ["completions.create", "models.list"]
}Permissions and abilities
token.abilitiesare the coarse scopes the token was minted with (e.g.completions,pii).permissionsare the fine-grained keys the caller may actually exercise. For a user that is the role's permissions intersected with the token's scopes; for an agent (which has no role) it is the scopes expanded directly, socompletionsbecomescompletions.create+models.list.token.limitsis the caller's own imposed limits, each{ metric, period?, max, per_request? }. Empty when none are set.
/v1/me/usageThe calling principal’s own usage for the window, attributed by user_id or agent_id depending on who is calling. The shape is identical to /v1/account/usage.
Request
periodstring- minute, day (default), week or month. Defines the time window.
fromstring- Explicit ISO-8601 window start.
tostring- Explicit ISO-8601 window end.
scopestring- Optional filter, e.g. completions.
model_dimensionstring- Group the `models` map by profile id (default `profile`) or upstream base model id (`base`).
Response · 200
{
"period": "day",
"from": "2026-06-03T00:00:00.000Z",
"to": "2026-06-03T14:30:00.000Z",
"model_dimension": "profile",
"scopes": { "completions": { "requests": 1, "tokens": 15 } },
"models": {}
}Live in-flight requests: /v1/live-requests
Use this endpoint to retrieve currently in-flight gateway requests. The portal displays these records above persistent request history.
/v1/live-requestsCurrently in-flight gateway requests.
Request
organisation_iduuid (super-admin only)- Scope to a specific tenant. Non-super-admins are pinned to their own org regardless.
user_iduuid- Filter to one user.
scopeenum- One of completions, language, pii, stt, tts. Only service calls appear here; reads and admin traffic never do.
limitnumber- 1 to 500. Default 100, sorted newest-first by start time.
Response · 200
{
"data": [
{
"id": "uuid",
"organisation_id": "uuid",
"user_id": "uuid",
"scope": "completions",
"model_id": "qwen3.5-35b",
"endpoint": "/v1/chat/completions",
"timestamp": "2026-05-05T10:31:16.000Z",
"elapsed_ms": 4120,
"input_tokens": 12739,
"output_tokens": 217,
"status": "in_progress"
}
]
}input_tokens is estimated when the request starts, and output_tokens updates while the model streams. Treat both values as estimates. Final counts appear in request history after completion.
Shape of the usage object per scope
The usage field on a request history entry reflects what was counted for that specific call. The shape varies by scope:
completions
{
"prompt_tokens": 200,
"completion_tokens": 150,
"processors": {
"anonymise": { "entities_redacted": 2 }
}
}processors is only present when processors ran. Each processor adds its own keys under that object. See the Processors guide for the per-processor shape.
On rejected requests, some processors also record forensic fields (for example prompt_shield_detections). Those stay server-side for audit and never appear in API responses.
language
{ "requests": 1, "corrections": 2 }ocr
{
"requests": 1,
"prompt_tokens": 1240,
"completion_tokens": 184,
"total_tokens": 1424,
"output_characters": 3872,
"pages": 1
}pii (analyse)
{ "requests": 1, "entities_found": 3 }pii (redact / restore)
{ "requests": 1, "entities_redacted": 2, "replacements_made": 2 }stt
{ "requests": 1, "audio_duration_seconds": 4.2 }tts
{ "requests": 1, "characters_synthesised": 45, "output_audio_seconds": 3.2 }Latency and tokens-per-second
Every request history entry (and every time-series bucket) carries two timing values:
- Total latency (
latency_ms): wall-clock from request entry to finalisation. Includes queue time, pre/post processors, tool execution, the upstream LLM call, and gateway overhead. - Upstream latency (
upstream_ms): the LLM-only window. For completions this is the model's evaluation time; for service scopes (audio, PII, and language) it's the upstream HTTP call time.
Dashboards use p50_latency_ms and p95_latency_ms to show typical and tail latency. tokens_per_second on every time-series bucket is volume-weighted: SUM(completion_tokens) / SUM(upstream_ms) * 1000. That matches the per-response inferada.timings.tokens_per_second value. Both use the model-evaluation window rather than total wall-clock time.
Platform performance (super-admin)
Super-admins have a dedicated /admin/performance page with requests per minute, error rate, p95 latency, live in-flight requests, per-upstream error rollups, and a detailed errors panel with a 24h trend. An organisation selector at the top lets a super-admin step into any single org without leaving the page.
Org admins get the same page under /organisation/:orgId/performance, scoped to their own organisation.
See also
- Rate limits — see how the gateway uses these counters to enforce limits.
- Processors — see how processors add usage to their dependent service scopes.