---
title: "Tokens and cost per model per day, for the whole project"
method: GET
path: "/api/v1/agents/usage"
tags: ["Agents"]
---

# Tokens and cost per model per day, for the whole project

`GET /api/v1/agents/usage`

## Request

- Base URL: `https://app.lastping.dev`
- URL: `https://app.lastping.dev/api/v1/agents/usage`
- Auth: API key in header `X-Api-Key`

Model usage for every agent and monitor in the project, per model per
UTC day, and per agent over the range. Read from the daily dependency
aggregate LastPing computes as spans arrive (kept 90 days), never
from raw spans, so it answers in one read whatever the volume.

A range covers every UTC day that overlaps it: `24h` reads yesterday
and today. Costs a model call did not report are estimated from
LastPing's price table and labelled `estimated`.

## Query parameters

- `range` '24h' | '7d' | '30d'
- `project` string

## Response `200`

The project's usage.

- FleetUsage: The body of `GET /api/v1/agents/usage`. `days` sums every model call in the project, including monitors with no agent; `by_agent` names only agents, so without `project` its rows can sum to less than `days`. Under `project`, `by_agent` is still the unfiltered range and can exceed `days`.
  - `range` '24h' | '7d' | '30d', required
  - `days` UsageDay[], required: One row per model per UTC day with usage, oldest first. Under `project`, one row per UTC day with `model` and `provider` empty (a run's totals are not split by model), summed from the label's traced runs as `by_project` is.
    - `day` string, date, required
    - `model` string, required: The model id. Empty either when the span named only a provider, or, under a `project` filter, on every row, because each row is then a whole day of the project's runs across all models.
    - `provider` string, required: The provider (`gen_ai.system`). Empty either when the span named only a model, or, under a `project` filter, on every row (one row per day across all models).
    - `tokens_in` integer, required
    - `tokens_out` integer, required
    - `tokens_cache_read` integer, required
    - `tokens_cache_write` integer, required
    - `cost_usd` string, nullable, required: US dollars as decimal text; null when no call reported or could be priced.
    - `cost_source` string, required: What `cost_usd` is made of. A plain string, not an enum, so a new value never breaks a client. `client` when `cost_usd` is the tool's own figure: a metric-derived row's (Claude Code's cost metric, or Cursor's best-effort estimate); for one agent's usage, a trace-derived row whose day and model Claude Code's cost metric also covers (its figure replaces the traces' figure, which moves to `estimated_cost_usd`); or a trace-derived row whose every priced call carried a client-reported cost. `estimated` when LastPing priced every call at API list prices, `mixed` when a trace-derived row holds both kinds. The client figure and the traces' figure may describe different sets of calls (the metric covers every Claude Code call of the day, the traces only the traced ones). Empty when `cost_usd` is null.
    - `estimated_cost_usd` string, nullable, required: The traces' figure for the day and model when Claude Code's cost metric also covers them and its figure is `cost_usd`; null otherwise. The traces' figure is LastPing's estimate at API list prices, except for calls whose own client-reported cost was attached to them.
    - `origin` 'traces' | 'metrics', required: Where the row's numbers come from. `traces`: the span-derived daily aggregate. `metrics`: an OTLP metrics export, shown only for a day and model no span covered. The two are never added: a tool such as Claude Code sends spans and metrics for the same calls, so for one day, provider and model the trace-derived row wins. The project-wide usage report is trace-derived only.
  - `by_agent` AgentUsage[], required: Highest cost first. Not narrowed by `project`, which the per-agent aggregate cannot see; `by_project` carries the label's figures.
    - `id` string, uuid, required
    - `name` string, required
    - `calls` integer, required: Model calls.
    - `tokens_in` integer, required
    - `tokens_out` integer, required
    - `tokens_cache_read` integer, required
    - `tokens_cache_write` integer, required
    - `cost_usd` string, nullable, required
    - `cost_source` string, required: What `cost_usd` is made of. A plain string, not an enum, so a new value never breaks a client: `client` when every priced call's cost was reported by the client (the exporter's own figure, or Claude Code's per-call cost), `estimated` when LastPing priced every call at API list prices, `mixed` when the sum holds both, empty when `cost_usd` is null.
  - `project` string, required: The `project` filter this response applied, after cleaning (a path reduced to its last element), or an empty string when there was none.
  - `project_scope` string, required: Where every figure that names a project comes from: `traces_only`. A project label rides a Claude Code hook's start ping, so only traced runs carry one; usage reported only through an OTLP metrics export has no project and is in no `by_project` row, nor in `days` under a `project` filter. A plain string, not an enum, so a new value never breaks a client.
  - `by_project` ProjectUsage[], required: Per project label, the usage of the label's traced runs over the range (see `ProjectUsage`), costliest first, at most 50. Runs with no label are in no row. Narrowed to one row by `project`. It need not sum to or match `days`: see `ProjectUsage`.
    - `project` string, required
    - `runs` integer, required: The label's traced runs whose start is in the range. A test run is not counted.
    - `tokens_in` integer, required
    - `tokens_out` integer, required
    - `tokens_cache_read` integer, required
    - `tokens_cache_write` integer, required
    - `cost_usd` string, nullable, required: US dollars as decimal text; null when no call reported or could be priced.
    - `cost_source` string, required: What `cost_usd` is made of, as `AgentUsage.cost_source`: `client` when every priced call's cost was reported by the client, `estimated` when LastPing priced every call at API list prices, `mixed` when the sum holds both, empty when `cost_usd` is null. A plain string, not an enum.

## Other responses

- `400`: An invalid `range` or `project` (`INVALID_FILTER`).
- `401`: Missing or invalid API key.

---

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