Skip to content

Aggregate Usage

Aggregates usage log rows and returns grouped decimal measures. Use this endpoint for dashboard charts, totals, grouped billing analytics, and reconciliation checks.

Deprecated: new projects should build on Analysis Query instead. Keep using this page only if you still need the legacy flat grouped-row response shape.

POST /v1/projects/:project_id/usage/query
Terminal window
Authorization: Bearer <api-key>
Content-Type: application/json

Requires analytics read access.

Field Required Description
project_id Yes Project that owns the usage analytics rows.
Field Required Description
start_time Yes Inclusive start time as Unix seconds. Must be before end_time.
end_time Yes Exclusive end time as Unix seconds. The query range cannot exceed 31 days.
measures Yes Measures to calculate. Supported values: quantity, amount, quantity_avg, amount_avg, item_count, usage_event_count, event_count.
metric No Legacy single-metric alias. Prefer metrics for new integrations.
metrics Conditionally Explicit metric selector list. Required for metric measures; send a one-item array for a single metric.
billing_account_id No Filter by the usage event’s real billing account ID. Use this top-level field rather than filters.
subject_type No Filter by usage subject type. A non-empty top-level value overrides filters.subject_type.
subject_id No Filter by usage subject ID. A non-empty top-level value overrides filters.subject_id.
filters No Dimension and label filters, for example { "model": "gpt-4.1-mini" }. Generic subject filters remain supported when the matching top-level field is omitted.
group_by No Up to 4 dimensions. Built-ins are bucket, metric, subject_type, and subject_id; label keys can also be used.
bucket_size Conditionally Required when group_by includes bucket. Supported values: 1m, 5m, 15m, 1h, 1d, day.
limit No Maximum number of rows. Defaults to 100; maximum is 1000.

Metric measures (quantity, amount, quantity_avg, amount_avg, and item_count) require an explicit metrics selector. Send metric only for backward compatibility with older clients; new integrations should always send metrics, even for a single metric. The API does not dynamically aggregate every metric when the selector is omitted. Event-count measures, usage_event_count and event_count, do not require a metric selector; they cannot be mixed with metric measures and cannot filter or group by metric.

Dotted metric names such as tool_call.web_search are logical metric identifiers. Send the complete dotted name; the service resolves its Doris VARIANT path internally.

billing_account_id filters the persisted billing-account ownership snapshot, not a same-named label supplied by an event. It is a dedicated top-level filter and cannot be used in filters or group_by.

Terminal window
curl 'http://127.0.0.1:8080/v1/projects/proj_gateway/usage/query' \
-H 'Authorization: Bearer <api-key>' \
-H 'Content-Type: application/json' \
-d '{
"start_time": 1778580000,
"end_time": 1778666400,
"billing_account_id": "acct_org_001",
"metrics": ["input_tokens", "output_tokens"],
"group_by": ["bucket", "model"],
"bucket_size": "1h",
"measures": ["quantity", "amount"],
"limit": 100
}'
{
"rows": [
{
"dimensions": {
"bucket": "1778580000",
"model": "gpt-4.1-mini"
},
"measures": {
"quantity": "1500",
"amount": "0.00048"
}
}
]
}
  • Time fields are Unix seconds.
  • end_time is exclusive, and one query can span at most 31 days.
  • Amounts and quantities are returned as decimals to preserve billing precision.
  • Use Query Bills when you need per-metric quantities and amounts, mandatory time grouping, and cursor pagination.