Skip to content

Subject Usage Details

List this subject’s events with aggregated metrics and cursor pagination.

GET /v1/subject/usage/events/details

Use a Subject Token with the analysis rule. Tenant, project, subject type and subject ID come from the token. Obtain it through Grant Subject Token. Missing, invalid or expired tokens return 401; missing analysis returns 403.

Authorization: Bearer <subject-token>

Omit subject_type and subject_id to use the token identity. If supplied, they must match the token or the request returns 403. Subject constraints override generic subject filters. A billing-account filter can only narrow this subject’s data.

The request body is empty. All supported query parameters are listed below.

Field Contract
raw_event_id Optional exact raw event ID.
billing_account_id Optional persisted payer ownership filter.
subject_type / subject_id Optional; must match the token.
metric Optional single metric; prefer metrics.
metrics Optional metric names, repeated or comma-separated. Takes precedence over metric.
filter.<key> Optional dimension/label equality, e.g. filter.model=gpt-4.1-mini. filter.billing_account_id is rejected; use the top-level parameter. Subject filters cannot override the token identity.
start_time Optional inclusive occurrence time, Unix seconds.
end_time Optional exclusive occurrence time, Unix seconds.
after_id Optional opaque cursor from next_after_id; retain all other filters.
limit Optional integer 1–1000. Default 100; values ≤ 0 or > 1000 fall back to 100.
include_revoked Optional 1 or true includes revoked events; omitted or other values exclude them.

This uses the same detail query as the project endpoint, with token subject and metric constraints applied. Metric selectors intersect with the token allowlist; with no selector, only allowed metrics are visible. Events containing only hidden metrics do not appear. Fully unauthorized selectors return {"usage_events":[],"total":0}.

For the next page, send after_id=<next_after_id> with the same token, time range and filters. Stop when the cursor is absent. This is an analytics view; newly ingested usage may not be visible immediately.

Terminal window
curl 'http://127.0.0.1:8080/v1/subject/usage/events/details?start_time=1781222400&end_time=1781308800&limit=100' \
-H 'Authorization: Bearer <subject-token>'

200 OK

{
"total": 1,
"usage_events": [
{
"tenant_id": "tenant_123",
"project_id": "proj_demo",
"event_date": "2026-06-12",
"occurred_at": 1781222400,
"raw_event_id": "raw_evt_01",
"source": "llm_gateway",
"subject_type": "user",
"subject_id": "user_123",
"billing_account_id": "acct_001",
"labels": {
"model": "gpt-4.1-mini"
},
"metrics": {
"input_tokens": {
"value": "1200",
"unit": "token",
"currency": "USD",
"amount": "0.00024",
"unit_price": "0.0000002"
}
},
"ingested_at": 1781222401,
"processed_at": 1781222402
}
]
}
Field Contract
usage_events Event array, empty when no matching authorized usage exists.
total Total visible events matching all subject, metric, account, time, label and revocation filters, independent of limit and after_id; 0 when no events match.
next_after_id Optional next-page cursor: the last raw event ID on this page. Returned only if another event matches the same filters and authorization; omitted on the last page.
usage_events[].tenant_id / project_id Owning tenant and project.
usage_events[].raw_event_id Event identity.
usage_events[].event_date UTC date of business occurrence, YYYY-MM-DD.
usage_events[].occurred_at Business occurrence, Unix seconds; time-filter source.
usage_events[].ingested_at Original Kafka ingress time, Unix seconds; preserved on retries.
usage_events[].processed_at Successful persistence time, Unix seconds. Historical unknown timestamps can be 0.
usage_events[].source Event source.
usage_events[].external_event_id Optional external correlation ID.
usage_events[].subject_type / subject_id Optional subject identity fields; scoped to token.
usage_events[].billing_account_id Optional actual payer snapshot.
usage_events[].extractor_rule_set_id / extractor_version Optional applied extractor ID and version for audit.
usage_events[].labels Optional string map of event labels.
usage_events[].metrics Optional map keyed by logical metric name, sorted by name; only selected, authorized metrics are returned. Dotted names remain intact.
usage_events[].metrics.<name> value: quantity string; optional unit, currency, amount, unit_price, matched_rule_id, analytics_only. Money values are decimal strings. analytics_only: true identifies non-billable analytical usage.
usage_events[].revoked_at Optional revocation time, Unix seconds.

Errors use {"error":"message"}.

401: invalid or expired token. 403: missing rule or subject mismatch. 400: invalid query. Query cancellation returns 408, timeout 504, and other query failures 500, including failures while counting results or checking the next page. Error messages are public English strings; internal causes are retained only in server logs.

Count, page and next-page checks are separate queries, not a cross-page snapshot. Concurrent ingestion or revocation can change totals and page contents.