---
title: Usage Report
url: https://platform.claude.com/docs/en/api/php/beta/organization/analytics/usage_report
---

# Usage Report

## Get Token Usage Over Time

`$client->beta->organization->analytics->usageReport->list(\Datetime startingAt, ?BucketWidth bucketWidth, ?list<AnalyticsClaudeTagCategory> claudeTagCategories, ?list<string> claudeTagUserIDs, ?list<AnalyticsContextWindow> contextWindows, ?\Datetime endingAt, ?list<GroupBy> groupBy, ?list<AnalyticsInferenceGeoFilter> inferenceGeos, ?int limit, ?list<string> models, ?string page, ?list<AnalyticsProductFilter> products, ?list<string> rbacGroupIDs, ?list<string> slackChannelIDs, ?list<Speed> speeds, ?list<string> userIDs): ReportPageCursor<AnalyticsUsageReportTimeBucket>`

**GET** `/v1/organizations/analytics/usage_report`

Get token usage over time across a date range.

Returns token usage bucketed by minute, hour, or day, optionally broken
down by product, model, context window, inference region, or speed.
Available to organizations on a Claude Enterprise plan. Requires an API
key with the `read:analytics` scope.

### Parameters

- `startingAt: \Datetime` (query parameter)

  Start of range, inclusive. RFC 3339 tz-aware. Must be within the last 365 days and no earlier than 2026-01-01T00:00:00Z.

- `bucketWidth?:optional BucketWidth` (query parameter)

  Time bucket granularity.

  default: 1d

- `claudeTagCategories?:optional list<AnalyticsClaudeTagCategory>` (query parameter)

  Filter to Claude Tag (Claude in Slack) usage in specific spend categories. Usage with no category never matches. `dm` usage is reported under the user's product rather than `claude-tag`, so combining this filter with `products[]=claude-tag` excludes it. Use `group_by[]=claude_tag_category` to break out per-category values.

- `claudeTagUserIDs?:optional list<string>` (query parameter)

  Filter to Claude Tag (Claude in Slack) usage attributed to specific Slack users, by Slack user ID (for example `U0123ABCDEF`), not claude.ai user ID. Usage that is not Claude Tag, and Claude Tag usage not attributed to a single user, never matches. Use `group_by[]=claude_tag_user_id` to break out per-user values.

- `contextWindows?:optional list<AnalyticsContextWindow>` (query parameter)

  Filter to specific context-window pricing tiers. Use `group_by[]=context_window` to break out per-tier values.

- `endingAt?:optional \Datetime` (query parameter)

  End of range, exclusive. When omitted, defaults to the earlier of now and `starting_at` + 31 days. The range may span at most 31 days.

- `groupBy?:optional list<GroupBy>` (query parameter)

  Dimensions to break each time bucket out by. Defaults to no grouping (one total per bucket). Each bucket reports at most its top 100 groups; a group beyond that cap has no row in that bucket (there is no remainder row), so grouped buckets are not exhaustive when a dimension has more than 100 distinct values.

- `inferenceGeos?:optional list<AnalyticsInferenceGeoFilter>` (query parameter)

  Filter to specific inference regions. `not_available` matches rows where the region is unset. Use `group_by[]=inference_geo` to break out per-region values.

- `limit?:optional int` (query parameter)

  Maximum number of time buckets per page. Defaults and caps vary by `bucket_width` (`1d`: default 7, max 31; `1h`: default 24, max 168; `1m`: default 60, max 256).

- `models?:optional list<string>` (query parameter)

  Models to include. Defaults to all models. Use `group_by[]=model` to break out per-model values.

- `page?:optional string` (query parameter)

  Opaque cursor from a previous response's `next_page` field.

- `products?:optional list<AnalyticsProductFilter>` (query parameter)

  Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values.

- `rbacGroupIDs?:optional list<string>` (query parameter)

  Filter to usage attributed to specific RBAC groups. Accepts tagged RBAC group IDs (`rbac_group_...`) or bare group UUIDs. A row matches when the user belonged to any of the listed groups on the (UTC) day the usage occurred; usage with no group attribution never matches.

- `slackChannelIDs?:optional list<string>` (query parameter)

  Filter to usage originating from specific Slack channels. Use `group_by[]=slack_channel_id` to break out per-channel values.

- `speeds?:optional list<Speed>` (query parameter)

  Filter to fast or standard inference mode. Use `group_by[]=speed` to break out per-mode values.

- `userIDs?:optional list<string>` (query parameter)

  Filter to specific users by tagged user ID.

### Returns

- `class AnalyticsUsageReportTimeBucket`

  - `\Datetime endingAt`

    End of the time bucket (exclusive) in RFC 3339 format.

  - `list<AnalyticsUsageBucketedResult> results`

    Rows for this time bucket. Empty when the bucket has no data; otherwise a single combined row when `group_by[]` is omitted, or one row per group (subject to the per-bucket group cap described on the `group_by[]` parameter).

  - `\Datetime startingAt`

    Start of the time bucket (inclusive) in RFC 3339 format.

### Example

```php
<?php

require_once dirname(__DIR__) . '/vendor/autoload.php';

use Anthropic\Client;
use Anthropic\Beta\Organization\Analytics\AnalyticsClaudeTagCategory;
use Anthropic\Beta\Organization\Analytics\AnalyticsContextWindow;
use Anthropic\Beta\Organization\Analytics\AnalyticsInferenceGeoFilter;
use Anthropic\Beta\Organization\Analytics\AnalyticsProductFilter;

$client = new Client(apiKey: 'my-anthropic-api-key');

$page = $client->beta->organization->analytics->usageReport->list(
  startingAt: new \DateTimeImmutable('2019-12-27T18:11:19.117Z'),
  bucketWidth: '1d',
  claudeTagCategories: [AnalyticsClaudeTagCategory::ENGAGED],
  claudeTagUserIDs: ['U0123ABCDEF'],
  contextWindows: [AnalyticsContextWindow::FROM_0_TO_200K],
  endingAt: new \DateTimeImmutable('2019-12-27T18:11:19.117Z'),
  groupBy: ['claude_tag_category'],
  inferenceGeos: [AnalyticsInferenceGeoFilter::GLOBAL],
  limit: 1,
  models: ['string'],
  page: 'page',
  products: [AnalyticsProductFilter::CHAT],
  rbacGroupIDs: ['rbac_group_012rppKaSVsmTo6NqRDXQXNF'],
  slackChannelIDs: ['C0123ABCDEF'],
  speeds: ['fast'],
  userIDs: ['string'],
);

var_dump($page);
```

#### Response (200)

```json
{
  "data": [
    {
      "ending_at": "2019-12-27T18:11:19.117Z",
      "results": [
        {
          "cache_creation": {
            "ephemeral_1h_input_tokens": 0,
            "ephemeral_5m_input_tokens": 0
          },
          "cache_read_input_tokens": 0,
          "claude_tag_category": "dm",
          "claude_tag_user_id": "U0123ABCDEF",
          "context_window": "0-200k",
          "inference_geo": "global",
          "model": "claude-opus-5-5",
          "output_tokens": 0,
          "product": "chat",
          "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
          "requests": 0,
          "server_tool_use": {
            "web_search_requests": 10
          },
          "slack_channel_id": "C0123ABCDEF",
          "speed": "fast",
          "uncached_input_tokens": 0
        }
      ],
      "starting_at": "2019-12-27T18:11:19.117Z"
    }
  ],
  "data_refreshed_at": "2019-12-27T18:11:19.117Z",
  "has_more": true,
  "next_page": "next_page",
  "organization_id": "org_013FP9SaFPBg7Kw7fetjn6cF"
}
```
