Usage
Package usage is what your org ran and what it cost, broken down per account.
Package usage is what your org ran and what it cost, broken down per account.
| Base URL | https://api.hanzo.ai |
| Operations | 11 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
usage
Activity returns the per-day usage series for ONE authorized subject — the points a contribution heatmap and a timeline are drawn from, gap-filled so every day in the range is present.
GET /v1/usage/activity
Activity returns the per-day usage series for ONE authorized subject — the points a contribution heatmap and a timeline are drawn from, gap-filled so every day in the range is present. Authorization is resolved server-side from the validated principal, so a caller can never widen the subject past what they are entitled to: a non-admin reads only themselves and their own org. subject=project answers empty with a note, because the usage ledger records no project column yet. When the warehouse is not connected the series answers empty with available=false rather than fabricated days.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
subject | query | string | — | Subject is what the series is about: "user" (default), "org" or "project". |
id | query | string | — | ID names the subject within what the caller is entitled to see. |
from | query | string | — | From is the first day of the range, "2006-01-02". |
to | query | string | — | To is the last day of the range, "2006-01-02". |
Echoes a plan's resolved analytics entitlement so a dashboard can configure itself against the LIVE catalog instead of hardcoding tier numbers.
GET /v1/usage/analytics/access
Echoes a plan's resolved analytics entitlement so a dashboard can configure itself against the LIVE catalog instead of hardcoding tier numbers. An empty plan resolves the free floor, and a catalog resolution failure serves that same floor rather than erroring — so this always answers 200. It is a read-only contract echo and carries no tenant data.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
plan | query | string | — | Plan is a plan id from the live @hanzo/plans catalog. |
Is 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
Is 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.
| Parameter | 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: 24h, 7d, 30d, or custom. |
start | query | string | — | Start is the inclusive window start, RFC3339. |
PutOrgOptin sets the ORG's listing on the cross-org global board.
PUT /v1/usage/leaderboard/optin/org
PutOrgOptin sets the ORG's listing on the cross-org global board. Only an admin of the caller's own org — an org admin or a platform SuperAdmin — may change it, and the org written is the caller's validated tenant, never a value from the request. Listing consents to publishing the org's usage VOLUME; cross-org spend stays restricted to platform admins regardless.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
display | string | — | Display is the name shown for the org on that board: 1-40 characters of letters, digits, space, dot, underscore, apostro |
listed | boolean | — | Listed publishes the org on the cross-org global board when true, and withdraws it when false. |
GetOptin returns the caller's own public-listing preference and their org's, each with whether the caller may change it.
GET /v1/usage/leaderboard/optin
GetOptin returns the caller's own public-listing preference and their org's, each with whether the caller may change it. Public listing is opt-in and private by default, so a fresh caller reads listed=false for both.
PutUserOptin sets the CALLER's own public-listing preference on the leaderboard.
PUT /v1/usage/leaderboard/optin
PutUserOptin sets the CALLER's own public-listing preference on the leaderboard. Self only: the row written is keyed by the caller's validated ledger identity, so this can never edit another member's visibility whatever the request says. A caller opting in with no handle is given their username, so a listed row never renders as "Anonymous" to its own owner.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
handle | string | — | Handle is the display name shown on a listed row: 1-40 characters of letters, digits, space, dot, underscore, apostrophe |
listed | boolean | — | Listed publishes the caller's row to other viewers of the board when true, and anonymizes it when false. |
Leaderboard ranks AI usage over a window, either the users of the caller's own org or organizations against each other, and always reports the caller's own standing even when it falls outside the returned page.
GET /v1/usage/leaderboard
Leaderboard ranks AI usage over a window, either the users of the caller's own org or organizations against each other, and always reports the caller's own standing even when it falls outside the returned page. Identities are private by default: a caller sees themselves, plus the peers or orgs that opted into public listing, and only an admin sees their own org's members named. Cross-org spend is restricted to platform admins. When the warehouse is not connected the board answers empty with available=false rather than a fabricated rank.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
scope | query | string | — | Scope picks the board: "personal" (default) ranks the caller among their own org's users, "org" is that same org board n |
metric | query | string | — | Metric is the value ranked: tokens (default), requests, or cost. |
period | query | string | — | Period is the window ranked: day, week, month (default) or all. |
limit | query | integer | — | Limit caps the rows returned, clamped to 100. |
Backfill seeds the derived usage rollup from ledger history — the rows written before the incremental view existed, which that view can never capture.
POST /v1/usage/rollup/backfill
Backfill seeds the derived usage rollup from ledger history — the rows written before the incremental view existed, which that view can never capture. SuperAdmin only. Because the rollup accumulates, a second unguarded run would double every day it re-reads, so it refuses with 409 when the rollup already holds rows unless force=true is passed; forcing WILL double-count.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
before | string | — | Before bounds the seed to ledger rows written before this RFC3339 instant. |
force | string | — | Force must be exactly "true" to seed a rollup that already holds rows. |
Is the PER-PROVIDER view: one connected account's own consumption of its own plan — "my Claude Max plan is 47% through its 6h window, resets at 14:20".
GET /v1/usage/samples
Is the PER-PROVIDER view: one connected account's own consumption of its own plan — "my Claude Max plan is 47% through its 6h window, resets at 14:20".
current is the newest instance of each lane (the headline); windows is the
history behind it. Both come from ONE deduped read, so they can never disagree.
The rows are the caller's OWN linked accounts, scoped to the validated principal
and its subject — never another user's, and never another org's.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
account | query | string | — | Account narrows to ONE linked account of that provider. |
provider | query | string | — | Provider is the upstream to read, e.g. |
range | query | string | — | Range is the window to read: 1h, 24h, 7d or 30d. |
window | query | string | — | Window narrows to ONE window class: 6h, day, week or month. |
Answers GET /v1/usage/summary: the caller's own usage footprint over one window — the categorized spend roll-up from the commerce ledger, the org's LLM usage totals from the warehouse, and the caller's OWN linked provider accounts beside the org's Hanzo-routed usage.
GET /v1/usage/summary
Answers GET /v1/usage/summary: the caller's own usage footprint over one window — the categorized spend roll-up from the commerce ledger, the org's LLM usage totals from the warehouse, and the caller's OWN linked provider accounts beside the org's Hanzo-routed usage.
Every source degrades INDEPENDENTLY to honest zeros and says so in sources and
in its own available flag, so a partial deploy reports "no data" rather than
fabricating spend. The account rows and the Hanzo rows are concatenated and never
summed: a plan's percent is not money.
The response is org-scoped from the validated principal and marked no-store — a signed-out caller is refused.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
range | query | string | — | Range is the window: 24h, 7d, 30d, or custom. Empty means 24h. |
start | query | string | — | Start is the inclusive window start, RFC3339. |
end | query | string | — | End is the exclusive window end, RFC3339. |
Ingests a batch of account-usage samples — what a developer's OWN AI accounts have consumed of their OWN plans, metered from each provider's own login — and appends them to the warehouse series.
POST /v1/usage
Ingests a batch of account-usage samples — what a developer's OWN AI accounts have consumed of their OWN plans, metered from each provider's own login — and appends them to the warehouse series. Answers 202.
Send either a samples array or one sample's fields at the top level. Every
sample needs a provider, a machine and a known window class; an unknown window or
kind is refused rather than silently rewritten, because a dash filled with a class
nobody reported is worse than an error. There is no timestamp field: the server
owns the observation clock, and a sample says which window it measured with
windowStart or resetsAt.
It is FAIL-SOFT on storage: a warehouse outage costs a poll of history (stored:false), never a failed request. It records usage ONLY — the link registry is refreshed separately via POST /v1/links, so there is one and only one way to update an account row.
Request body — application/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
account | string | — | Account is the linked account the window was metered from. |
cachedInputTokens | integer | — | CachedInputTokens is the prompt tokens the provider served from cache. |
confidence | string | — | Confidence says how much the counters below mean. |
costCents | integer | — | CostCents is what the window cost on the PROVIDER's own plan, in US cents. |
costLimitCents | integer | — | CostLimitCents is the plan's spend ceiling for the window, in US cents. |
currency | string | — | Currency is the provider's currency when it is not US cents. |
inputTokens | integer | — | InputTokens is prompt tokens consumed in the window. |
kind | string | — | Kind is subscription or apikey. |
lane | string | — | Lane is the meter lane within the account. |
machine | string | — | Machine is the host whose meter read the window. |
outputTokens | integer | — | OutputTokens is completion tokens produced in the window. |
plan | string | — | Plan is the provider plan the account is on, e.g. |
provider | string | — | Provider is the upstream the account belongs to, e.g. |
requests | integer | — | Requests is how many requests the window covers. |
resetsAt | string | — | ResetsAt is when the measured window rolls over, RFC3339. |
samples | cloud_sampleReq[] | — | Samples is the batch form: every lane a poller measured, in one call. |
synthetic | boolean | — | Synthetic marks a window the meter inferred rather than read. |
totalTokens | integer | — | TotalTokens is the window's total tokens. |
usedPct | number | — | UsedPct is how much of the window's allowance is consumed, 0–100. |
window | string | — | Window is the window class: 6h, day, week or month. |
windowMinutes | integer | — | WindowMinutes is the window's real length in minutes, as the meter reports it. |
windowStart | string | — | WindowStart is when the measured window opened, RFC3339. |
How is this guide?