# Get aggregated usage for a project

> Returns a project's usage rolled up over an optional `[from, to]` time window, optionally bucketed by a single dimension and narrowed by any combination of thirteen filters — session, actor, agent, AI provider, orchestration run, orchestration, generation, trace, meter type, model, source, trigger and action. That is how 'what did this conversation cost', 'what has this end user cost' and 'what did this agent cost' are answered. Each group and the grand total carry an `event_count`, summed token counts, a measured `quantity` per component (so infra meters report their real amount, not zeros), and `cost_usd` (null when no event in the bucket was priced). This is the per-project cost-by-range/by-category query — a monthly figure without scanning raw usage events client-side.

<Heading
  as={"h1"}
  className={"openapi__heading"}
  children={"Get aggregated usage for a project"}
>
</Heading>

<MethodEndpoint
  method={"get"}
  path={"/api/v1/usage/aggregate"}
  context={"endpoint"}
>
  
</MethodEndpoint>

Returns a project's usage rolled up over an optional `[from, to]` time window, optionally bucketed by a single dimension and narrowed by any combination of thirteen filters — session, actor, agent, AI provider, orchestration run, orchestration, generation, trace, meter type, model, source, trigger and action. That is how "what did this conversation cost", "what has this end user cost" and "what did this agent cost" are answered. Each group and the grand total carry an `event_count`, summed token counts, a measured `quantity` per component (so infra meters report their real amount, not zeros), and `cost_usd` (null when no event in the bucket was priced). This is the per-project cost-by-range/by-category query — a monthly figure without scanning raw usage events client-side.

Narrowings intersect and apply to the whole rollup — every bucket, `totals` and `totals.distinct` alike — so each composes with any `group_by`, and all thirteen are echoed back under `filters`. The eight naming a resource are resolved against the project, and one naming nothing there empties the rollup rather than being dropped: a mistyped id must never read back as the project's whole spend. The other five are matched against the value the event recorded.

`groups` is paginated. Its `total` is the number of distinct buckets in the window — bucket cardinality, including a null bucket for the events the dimension does not apply to, and never a count of entities. To count entities, send `include=distinct` and read `totals.distinct`. `totals` always describes the whole window — never the page above it, and never the bucketing: omit `group_by` and `totals` is unchanged while `groups` is empty.

<Heading
  id={"request"}
  as={"h2"}
  className={"openapi-tabs__heading"}
>
  <Translate id="theme.openapi.request.title">Request</Translate>
</Heading>

<ParamsDetails
  {...require("./get-usage-aggregate.ParamsDetails.json")}
>
  
</ParamsDetails>

<RequestSchema
  {...require("./get-usage-aggregate.RequestSchema.json")}
>
  
</RequestSchema>

<StatusCodes
  {...require("./get-usage-aggregate.StatusCodes.json")}
>
  
</StatusCodes>
