---
title: "Get a generation or orchestration-run billing receipt"
method: GET
path: "/v1/projects/{project_id}/usage/receipt"
tags: ["Projects"]
---

# Get a generation or orchestration-run billing receipt

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

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/usage/receipt`
- 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`)

What one occurrence was billed, line by line: per-event line items with their measured components and unit prices, a per-meter-type split, and the totals. Pass generation_id for one generation, or orchestration_run_id for a receipt summed across every event the run metered. Exactly one of the two is required.

This is the itemisation behind a single number — where [the meter](/docs/api/projects/get-project-usage) says a window cost $12.40, a receipt says which components of which call made up one occurrence of it. On an orchestration-run receipt every line carries node_id, so grouping by it gives the per-node cost the total hides; a retried node contributes one line per attempt, which is the intended reading for spend.

## Query parameters

- `generation_id` string
- `orchestration_run_id` string

## Response `200`

The receipt.

- ProjectUsageReceipt: The itemisation of one generation or one orchestration run. Exactly one of generation_id / orchestration_run_id is present, matching the selector that was asked for.
  - `generation_id` string: Present on a per-generation receipt.
  - `orchestration_run_id` string: Present on an orchestration-run receipt.
  - `currency` string, required
  - `line_items` object[], required: One line per usage event — for a generation receipt the events on that generation, for a run receipt every event across the run.
    - `event_id` string, required
    - `meter_type` string, required
    - `provider` string, nullable, required: As on an event: the vendor billed, or "naturali" for a platform meter.
    - `model` string, nullable, required: As on an event, with one caveat: a line carries no provider of its own, so the public name is resolved by reading the events behind the receipt. Where that read cannot cover every line, all of them keep the string the meter recorded rather than some being renamed and some not.
    - `node_id` string, nullable: The orchestration node that produced the event. On a run receipt every line carries it, so grouping by node_id gives the per-node cost the total hides. A retried node contributes one line per attempt — a retry is real money. Null when no node produced the event.
    - `cost_usd` number, nullable, required
    - `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.
  - `by_meter_type` object[], required: Per-meter-type cost rollup — the tokens-and-infra split. A single-type receipt has one entry whose cost equals the total.
    - `meter_type` string, required
    - `cost_usd` number, nullable, required
  - `totals` object, required: Token counts and cost summed across the line items.
    - `cost_usd` number, nullable: Sum of the priced components; null when nothing was priced.
    - `input_tokens` integer: Full prompt tokens, cached input included.
    - `output_tokens` integer
    - `cached_tokens` integer
    - `reasoning_tokens` integer: The part of output_tokens a reasoning model spent thinking. Reported for visibility and priced as output, so it is never counted twice.

## Other responses

- `400`: Neither selector was given, or both were.
- `401`: Missing or invalid credentials.
- `404`: No usage was recorded for that id in this project — which is also the answer for an id belonging to another project.

---

[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)
