---
title: "List project usage events"
method: GET
path: "/v1/projects/{project_id}/usage/events"
tags: ["Projects"]
---

# List project usage events

`GET /v1/projects/{project_id}/usage/events`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/usage/events`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

The rows a rollup summed — one per metered occurrence, most recent first. Takes the same narrowings [the meter](/docs/api/projects/get-project-usage) does, so a query that produced a bucket answers here unchanged and reads back what went into it. This is the audit and reconciliation view: what was measured, when, against which agent, session, actor and provider, and what each component was priced at.

An id naming nothing in this project yields an empty page rather than dropping the filter, so a mistyped narrowing can never widen the list past what was asked for.

## Query parameters

- `meter_type` string
- `session_id` string
- `actor_id` string
- `agent_id` string
- `ai_provider_id` string
- `orchestration_run_id` string
- `orchestration_id` string
- `generation_id` string
- `trace_id` string
- `source` string
- `trigger_id` string
- `action_id` string
- `limit` integer
- `offset` integer

## Response `200`

One page of usage events.

- ProjectUsageEventPage: One page of events. total counts every event the narrowing matched, independent of limit.
  - `data` ProjectUsageEvent[], required
    - `id` string, required
    - `project_id` string, required
    - `generation_id` string, nullable
    - `trace_id` string, nullable
    - `agent_id` string, nullable
    - `actor_id` string, nullable: The end user the occurrence was produced for, frozen at write time. Null when no end user is behind the work — orchestration runs, triggers, direct API generations.
    - `session_id` string, nullable: The session the occurrence ran in, frozen at write time. Null for work not dispatched through a session.
    - `orchestration_run_id` string, nullable
    - `node_id` string, nullable: The orchestration node within the run, when applicable.
    - `ai_provider_id` string, nullable: The provider billed — the target a model route picked for the turn, or the agent's pinned provider. Null if the provider was since deleted; the provider/model snapshot still records what was billed.
    - `trigger_id` string, nullable
    - `action_id` string, nullable: The caller-supplied action label, when one was given.
    - `meter_type` string, required: llm_tokens, compute_execution, api_request, storage or tool_execution.
    - `source` string, nullable: What the spend was incurred for. eval is an eval run's item generations and eval_judge an llm_judge scorer's own completion, so running a suite is priced apart from grading it. embedding is any embedding call. Null for ordinary agent traffic.
    - `provider` string, nullable, required: The vendor the SKU was billed against, retained even if the provider record is deleted. Platform meters — storage, requests, compute execution — are billed by naturali itself and read "naturali".
    - `model` string, nullable, required: The model, or the billable SKU for a platform meter. On the managed offering this is the same public name GET /v1/models lists; a provider you brought yourself keeps the string that vendor uses.
    - `cost_usd` number, nullable, required: Total USD cost, the sum of the priced components, frozen at write time. Null when nothing was priced.
    - `components` UsageEventComponent[], required
      - `component` string, required: The measured dimension — input_tokens, compute_second, gb_day, …
      - `quantity` number, required: The measured amount, in unit.
      - `unit` string, required
      - `billable` boolean: Whether this component contributes to cost. Non-billable details — reasoning_tokens, which is a subset of output_tokens — are never priced and never double-counted into the totals.
      - `unit_price` number, nullable: USD per unit, frozen at write time; null when unpriced.
      - `cost_usd` number, nullable: quantity x unit_price, frozen at write time; null when unpriced.
      - `price_id` string, nullable: The price-book row that priced this component.
    - `created_at` string, date-time, required
  - `total` integer, required
  - `limit` integer, required
  - `offset` integer, required

## Other responses

- `400`: A narrowing was given more than once, or a bound is out of range.
- `401`: Missing or invalid credentials.
- `404`: The resource does not exist (existence is not leaked).

---

[API](https://skmtc.dev/naturali/apis/naturali-ai-api.md) · [All operations](https://skmtc.dev/naturali/apis/naturali-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/naturali/apis/naturali-ai-api/revisions/e4905b78f422?raw)
