The Anthropic Admin API Cost Report, and the Gap It Leaves

Last updated August 16, 2026

Short version:Anthropic’s Admin API exposes a usage report and a cost report for your organization, grouped by model, workspace, API key, and service tier, behind a special sk-ant-admin key. It is the right source for what Anthropic will bill you. It cannot tell you cost per end user, because your users all share one key, so per customer attribution still has to happen in your own code.

If you searched for this, you are probably past the console graphs and want the numbers in your own dashboard or spreadsheet. Here is how the API works, what it answers well, and where it stops.

The two endpoints

Both live under the organization scope and require an Admin API key, created by an organization admin in the Anthropic Console. A regular API key returns an authorization error.

  • Usage report: /v1/organizations/usage_report/messages, token consumption over time. Tokens are split into uncached input, cached input, cache creation, and output, which matters because those four rates differ several fold.
  • Cost report: /v1/organizations/cost_report, spend in USD over the same window, grouped by workspace or description, the number that reconciles against your invoice. Daily buckets only.

You can bucket by minute, hour, or day, and group or filter by API key, workspace, model, and service tier. Full parameters are in Anthropic’s usage and cost API docs.

curl "https://api.anthropic.com/v1/organizations/usage_report/messages?\
starting_at=2026-08-01T00:00:00Z&bucket_width=1d&group_by[]=model" \
  -H "x-api-key: $ANTHROPIC_ADMIN_KEY" \
  -H "anthropic-version: 2023-06-01"

How those tokens turn into the dollars on the cost report, rate by rate, is worked through in the Claude API cost calculator.

The limits and null values that trip up a first run

Four documented behaviours account for most “the API is returning nonsense” moments, and none of them are obvious from a successful first call:

  • Bucket counts are capped, and the defaults are small. Daily buckets default to 7 and max out at 31, hourly default to 24 with a max of 168, and minute buckets default to 60 with a max of 1,440. Ask for a quarter at 1d without raising limit and you silently get one week back, which is the most common way a monthly report comes out wrong rather than empty.
  • You have to paginate. When the response carries has_more: true, pass its next_page value back as page and keep going until it is false. A month at hourly grain is several pages.
  • Nulls are meaningful, not missing data. Usage from the Console Playground is not tied to an API key, so api_key_id comes back null even when you group by it. Traffic on the default workspace reports a null workspace_id. Both look like broken attribution and are simply how the report models “no key” and “no workspace”.
  • Two things are missing from the cost endpoint. Priority Tier bills on a different model and is not in /v1/organizations/cost_report at all, so track it through the usage endpoint by grouping on service_tier. Code execution is the mirror image: it appears in cost, under a Code Execution Usage description, and not in usage.

Costs come back as decimal strings and daily buckets only, so there is no hourly spend chart to build from this endpoint. Full parameter and response detail is in Anthropic’s Usage and Cost API docs.

What it answers well

  • Which model is the money going to, Opus versus Sonnet versus Haiku, per day.
  • Which workspace or API key spent what, useful if you split keys per environment or team.
  • How much of your input is cached versus fresh, which is your prompt caching report card.
  • Finance questions: month to date spend, trend lines, invoice reconciliation.

For a finance dashboard or a monthly close, this plus a cron job is genuinely all you need, and it is the authoritative record: it is what Anthropic bills.

The gap: your customers are not in it

The finest grain is the API key. Your product almost certainly calls Anthropic with one key for all customers, so the report can say “$1,900 on Sonnet in July” and cannot say which of your users caused it, which feature drove it, or whether the $49 account that made 6,000 calls is now costing you more than it pays. Anthropic cannot close this gap: it has no idea who your end users are.

Per customer cost only exists if you attribute it at call time, tagging every request with your user id and feature and pricing it as it happens. That is the approach in tracking Claude API cost per user, and the request level mechanics are in tracking Claude usage per user.

The setup that uses both

  • Per request, in your stack: tag user id, feature, and plan on every call, price it from current rates, enforce per user caps before the call. This is operational: it catches the runaway user today, not on the invoice.
  • Monthly, from the Admin API: pull the cost report and cross check it against the sum of your per request tracking. If they diverge more than a few percent, something is unattributed, a background job, a stray key, or a model you are not pricing.

Weckr is the per request half packaged: two lines around your Anthropic client and every call lands with user, feature, cost, and margin against the user’s plan. The console side of this story, what the graphs show and hide, is in Anthropic console billing explained.

Two things the monthly pull cannot do, because it arrives after the money is spent: LLM cost spike detection while the spike is still running, and Anthropic spend limits that stop a single account before it clears your margin. If you are weighing the cron job against a tool, the trade-offs are laid out in build vs buy for LLM cost tracking.

FAQ

How do I get Claude usage and cost data programmatically?

Use the Anthropic Admin API. The usage report endpoint at /v1/organizations/usage_report/messages returns token consumption over time, and the cost report endpoint returns spend in USD. Both need an Admin API key, which starts with sk-ant-admin and can only be created by an organization admin in the Anthropic Console. A normal sk-ant-api key will not work.

What can the Anthropic cost report break down by?

You can bucket by minute, hour, or day, and group or filter by API key, workspace, model, and service tier. Token data separates uncached input, cached input, cache creation, and output tokens. That is enough to answer which model, which workspace, and which key spent the money, but nothing finer than the key level.

Can the Admin API give me Claude cost per end user?

No. The finest grain is your API key or workspace, and all of your end users usually share one key. Anthropic cannot know your user ids, so per customer attribution has to happen in your own stack: tag each request with the user id at call time and aggregate on your side, which is what a per user tracker like Weckr automates.

How fresh is the Admin API data?

Anthropic documents usage and cost data as typically appearing within about 5 minutes of a request completing, and supports polling roughly once a minute for sustained use. That is fast for a reporting API and still the wrong shape for live control: a runaway agent can burn thousands of calls inside one 5 minute window, and blocking it needs cost computed at request time in your own path, not read back afterwards.

Should I use the Admin API or client side tracking?

Both, for different jobs. The Admin API is the authoritative record of what Anthropic will bill your organization, so use it for reconciliation and finance. Client side per request tracking is the only way to get per user, per feature cost and to enforce spending caps before a call happens. The strong setup is per user tracking for operations plus a monthly Admin API cross check.

Keep reading

The invoice tells you how much. Not who.

The Admin API is the best version of the aggregate answer. The per customer answer, which accounts are quietly unprofitable, lives in your own request path, and Weckr turns it on in two lines. See the per user view on the live demo, or start from the AI cost and margin guide.

See the dashboard with real data, no signup needed.

Try the demo