# List analytics

URL: https://docs.hanzo.ai/docs/openapi/usage/get-usage-analytics

> The entitlement-GATED per-provider breakdown of the caller org's LLM usage — the paid lens over the same warehouse ledger GET /v1/usage/summary reads its totals from.

`GET /v1/usage/analytics`

> [Usage →](https://docs.hanzo.ai/docs/openapi/usage) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                           |
| ------------- | ----------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/usage/analytics` |
| **Method**    | `GET`                                     |
| **Operation** | `get_usage_analytics`                     |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`    |

The entitlement-GATED per-provider breakdown of the caller org's LLM
usage — the paid lens over the same warehouse ledger GET /v1/usage/summary reads
its totals from. Basic own-org usage stays ungated at /v1/usage/summary.

A plan that does not grant the analytics datastore is refused with 402, and an
unresolvable plan fails closed to the free floor, which does not grant it. The
window is clamped forward to the plan's retention entitlement, so a tenant can
never read older than its plan allows even with a custom start. The response is
marked no-store.

INTERIM (mirrors apps/world's limits echo): no org→plan resolver exists in cloud
yet — the subscription lookup is owned by the billing plane and the gateway
principal carries no plan claim — so the caller passes the plan and the gate
resolves THAT plan's access.

## Request

4 fields.

| Field   | In    | Type   | Required | Description                                                                                                    |
| ------- | ----- | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
| `end`   | query | string | —        | End is the exclusive window end, RFC3339.                                                                      |
| `plan`  | query | string | —        | Plan is the plan id whose entitlement decides access and retention.                                            |
| `range` | query | string | —        | Range is the window: a count and a unit — 24h, 7d, 90d, any \<N>h or \<N>d — or day, week, month, all, custom. |
| `start` | query | string | —        | Start is the inclusive window start, RFC3339.                                                                  |

## Response

| Status    | Body                     | Meaning |
| --------- | ------------------------ | ------- |
| `200`     | usage.usageAnalyticsView | ok      |
| `default` | problem-details          | refused |

`200` body — 17 fields.

| Field                         | In   | Type                    | Always | Description                                                                                                                             |
| ----------------------------- | ---- | ----------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `end`                         | body | string                  | —      | End is the window's exclusive end, RFC3339 UTC.                                                                                         |
| `export`                      | body | boolean                 | —      | Export is whether the resolved plan allows exporting these rows.                                                                        |
| `plan`                        | body | string                  | —      | Plan echoes the plan id the entitlement was resolved from.                                                                              |
| `providers`                   | body | usage.ProviderBreakdown | —      |                                                                                                                                         |
| `providers.available`         | body | boolean                 | —      | Available is false when the warehouse could not be read, which means "no answer" and NOT "no usage" — Items is then empty for a reason. |
| `providers.items`             | body | usage.ProviderRow\[]    | —      | Items is one row per provider, most tokens first.                                                                                       |
| `providers.items[].costCents` | body | integer (int64)         | —      | CostCents is what they cost the org, in US cents.                                                                                       |
| `providers.items[].provider`  | body | string                  | —      | Provider is the upstream the requests were routed to, e.g. anthropic.                                                                   |
| `providers.items[].requests`  | body | integer (int64)         | —      | Requests is how many completions the org made against that provider.                                                                    |
| `providers.items[].tokens`    | body | integer (int64)         | —      | Tokens is the total tokens those completions consumed, prompt plus completion.                                                          |
| `providers.source`            | body | string                  | —      | Source names the warehouse table the rows came from.                                                                                    |
| `range`                       | body | string                  | —      | Range is the label that was ASKED for.                                                                                                  |
| `retentionDays`               | body | integer (int64)         | —      | RetentionDays is how far back the resolved plan allows reading.                                                                         |
| `scope`                       | body | usage.usageScope        | —      |                                                                                                                                         |
| `scope.org`                   | body | string                  | —      | Org is the IAM org slug the rows were read under — the validated principal's, never a client header.                                    |
| `scope.user`                  | body | string                  | —      | User is the caller's own subject, whose linked-account rows the accounts block carries.                                                 |
| `start`                       | body | string                  | —      | Start is the window's inclusive start, RFC3339 UTC, AFTER the retention clamp — so it may be later than the start that was asked for.   |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo usage analytics get
```

**SDK**

**.ts**

```ts
import { Configuration, UsageApi } from 'hanzoai';

const api = new UsageApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getUsageAnalytics();
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import UsageApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = UsageApi(client).get_usage_analytics()
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.UsageAPI.GetUsageAnalytics(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, usage_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = usage_api::get_usage_analytics(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.UsageApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new UsageApi(client).getUsageAnalytics();
```

**HTTP**

```bash
curl https://api.hanzo.ai/v1/usage/analytics \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

MCP reaches **usage** through the `usage` tool, which names its 5 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_usage_analytics"
         }
       }
     }'
```

---

[Usage API](https://docs.hanzo.ai/docs/openapi/usage) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
