Anthropic/analytics
Observe Claude Enterprise analytics via the Enterprise Analytics API
(/v1/organizations/analytics/*): seat counts, DAU/WAU/MAU, pending
invites, feature adoption (projects, skills, connectors), and token
cost/usage. Extracts structured seat, adoption, and cost data into
separate versioned resources for CEL queries.
Supports an optional discountRate global arg (fraction, e.g. 0.15 for
"15% off") applied to cost and per-user-usage totals derived from the
Analytics API's list-price amount fields, to reflect enterprise volume
discounts. listCostUsd on per-user rows always stays at list price.
Authentication
Requires an Analytics API key (scope read:analytics) created by the
primary owner in claude.ai. Store in a swamp vault.
Usage
swamp extension pull @webframp/anthropic/analytics
swamp model create @webframp/anthropic/analytics claude-analytics \
--global-arg 'analyticsKey=${{ vault.get("anthropic", "ANALYTICS_KEY") }}' \
--global-arg 'discountRate=0.15' # optional; defaults to 0
# Collect analytics
swamp model method run claude-analytics collect_analytics
# With date range
swamp model method run claude-analytics collect_analytics \
--input startDate=2026-06-01 --input endDate=2026-07-01Methods
- collect_analytics — fans out across /summaries, /users, and /cost_report; writes snapshot, seats, adoption, and cost resources
- collect_user_usage — per-user token usage + cost from /user_usage_report and /user_cost_report, grouped by product (Claude Code broken out); optionally filtered to one email. Writes a userUsage resource
2026.08.28.1
Changed: Normalized the extension license to Apache-2.0 and corrected the copyright holder to "Sean Escriva". Extensions that previously shipped an MIT LICENSE.md are now Apache-2.0, consistent with the repository root and every other extension. No code or behavioral changes.
Upgrade note: License text only. No API, schema, or runtime behavior changed.
2026.08.26.2
Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry
quality scorer can resolve dependencies and score the extension. An earlier
release used a bare "zod" import-map specifier, which published but scored as
unscored.
Changed: Retained explicit compilerOptions.strict in deno.json. No
behavioral or schema changes.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| analyticsKey | string | Analytics API key (scope read:analytics) from claude.ai (use vault reference) |
| discountRate | number | Enterprise volume discount off list usage/token pricing, as a fraction |
| Argument | Type | Description |
|---|---|---|
| startDate? | string | Start date (YYYY-MM-DD, UTC, inclusive; no earlier than 2026-01-01). Defaults to 7 days ago. |
| endDate? | string | End date (YYYY-MM-DD, UTC, exclusive). Defaults to today. |
| Argument | Type | Description |
|---|---|---|
| days? | number | Lookback window in days, ending now (mutually redundant with |
| startDate? | string | Start (YYYY-MM-DD, UTC, no earlier than 2026-01-01). Defaults to |
| endDate? | string | End (YYYY-MM-DD, UTC). Defaults to now. |
| email? | string | If set, keep only the user whose actor.email matches (case-insensitive). |
| products? | array | Product filter, e.g. ["claude_code"]. Omit for all products; rows are grouped by product either way. |
Resources
2026.08.26.2
Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry
quality scorer can resolve dependencies and score the extension. An earlier
release used a bare "zod" import-map specifier, which published but scored as
unscored.
Changed: Retained explicit compilerOptions.strict in deno.json. No
behavioral or schema changes.
2026.08.25.1
Changed: Updated labels for improved extension discoverability. Added cross-cutting category labels (security, observability, finops, infrastructure, networking, compliance, devops, ai, incident-response) where applicable.
updated labels
2026.08.24.1
Added: Output metadata attributes for observability.
durationMs: Method execution duration in milliseconds.collectedBy: Extension name that produced the data.fetchedAt: ISO 8601 timestamp when data was fetched (added to resources that previously lacked it).
2026.08.23.1
Changed: Documentation only — no code changes. Documented collect_user_usage
in the README, which previously had no usage example at all, and added a
## Troubleshooting section explaining the collected: false degrade pattern
shared by the adoption, cost, and userUsage collection paths.
2026.08.21.2
Changed: startDate/endDate on collect_analytics and collect_user_usage
are now validated as well-formed YYYY-MM-DD dates before any request is made.
Previously a malformed date (e.g. "not-a-date" or "2026-13-99") silently
passed the range check — Date parsing of garbage input produces NaN, which
made the "end must be after start" comparison a no-op — and the bad value was
sent straight to the Analytics API, surfacing only as an opaque upstream 400.
Malformed dates now fail fast with a message naming the argument and the value
that was rejected.
2026.08.21.1
Changed: Added descriptions to the previously undocumented fields across
the snapshot, seats, adoption, cost, and userUsage resource schemas
(e.g. total_cents, by_cost_type, collected, byProduct, totals). No
behavioral change.
2026.08.14.1
Added: discountRate global arg (fraction, default 0) applying an
enterprise volume discount to cost figures derived from the Analytics API's
list-price amount fields. Applies to cost.total_cents/total_usd/
by_cost_type and per-user costUsd/totalCostUsd; listCostUsd always
stays at list price so the discount and list reference remain comparable.
Both cost and userUsage resources gain a discountRate field echoing
the rate applied.
Added: totals field on the userUsage resource — grand
inputTokens/outputTokens/totalTokens and per-minute rates across all
returned users, in the shape @webframp/ai-usage's generic provider registry
expects, so this resource can be registered there without a bespoke adapter.
Added: days argument on collect_user_usage (capped at 31, the
Analytics API's max window) as an alternative to startDate, so callers
(including a future @webframp/ai-usage-scan step) can drive the lookback
the same way as the other provider scan methods.
Added: Both collect_analytics and collect_user_usage now reject an
inverted date range (endDate at or before startDate) via a shared
assertRange check, instead of silently sending a backwards window to the
Analytics API — collect_user_usage additionally used this to guard
against a near-zero periodMinutes producing wildly inflated per-minute
rates in totals.
2026.07.18.1
Added: An upgrades array entry (no-op) to analytics.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.
2026.07.14.1
Added: collect_user_usage — per-user token usage and cost, so you can see
who is spending what (and how much of it is Claude Code) rather than only the
org aggregate.
Reads the Enterprise Analytics
/v1/organizations/analytics/user_usage_report(tokens: total / output / uncached-input / cache-read, plus requests) and/user_cost_report(amountandlist_amount, USD minor units → USD), grouped byproductsoclaude_codeis broken out from chat/cowork/etc.Optional
emailfilter keeps just one user (matched onactor.email);productsfilters the surfaces;startDate/endDatebound the window (defaults to the last 30 days; the API caps a window at 31 days).Writes a
userUsageresource (instance = the sanitized email, orall) with a per-userbyProductbreakdown plustotalTokens/totalCostUsd. Reuses the samex-api-key(read:analytics) auth and cursor pagination ascollect_analytics. The two reports are collected independently: if onlyuser_cost_reportfails (common on seat-based plans, where it 403s while the usage report still serves tokens), the token data is retained withcollected: trueandcostUsdleft null —collected: falseonly when both fail. A singleemail-filtered result is keyed by the user's unique id (user-<userId>) so emails that sanitize alike cannot collide.Caveats: with no
emailfilter the resource stores email + name for every org user (admin-only PII — mind shared datastores); and very large orgs can page-truncate (the filter is applied after fetch), so prefer a date-bounded, filtered query for a single user.
Additive: collect_analytics and its snapshot/seats/adoption/cost resources are
unchanged.
2026.07.07.1
Fixed:
collect_analyticscalled a non-existent endpoint (/v1/organizations/analytics, HTTP 404) with the wrong param names (start_date/end_date) and a flat-metrics response shape that never matched the real API. Rewritten against the documented Enterprise Analytics API:/analytics/summaries(seats + DAU/WAU/MAU + pending invites,starting_date/ending_date),/analytics/users(paginated, aggregated into adopter counts), and/analytics/cost_report(paginated, summed by cost type).
Added:
costresource — token cost/usage over the window (usage-based Enterprise plans).- Adoption and cost collection are best-effort: a failure in
/usersor/cost_reportno longer fails the whole run (seat-based plans have no cost data).
Changed:
adoptionnow reports adopter counts (users with ≥1 project/skill/connector), aggregated from/analytics/users— there is no org-level adoption endpoint.- The
snapshotresource writes to therecentinstance (latestis reserved by swamp). Query viadata.latest("claude-analytics", "recent").
2026.07.02.1
Added: Initial release. Enterprise Analytics observation model. Collects raw metrics snapshot and extracts structured seat counts (total, active, pending, DAU/WAU/MAU) and adoption metrics (projects, skills, connectors) into separate versioned r
2026.08.14.1
Added: discountRate global arg (fraction, default 0) applying an
enterprise volume discount to cost figures derived from the Analytics API's
list-price amount fields. Applies to cost.total_cents/total_usd/
by_cost_type and per-user costUsd/totalCostUsd; listCostUsd always
stays at list price so the discount and list reference remain comparable.
Both cost and userUsage resources gain a discountRate field echoing
the rate applied.
Added: totals field on the userUsage resource — grand
inputTokens/outputTokens/totalTokens and per-minute rates across all
returned users, in the shape @webframp/ai-usage's generic provider registry
expects, so this resource can be registered there without a bespoke adapter.
Added: days argument on collect_user_usage (capped at 31, the
Analytics API's max window) as an alternative to startDate, so callers
(including a future @webframp/ai-usage-scan step) can drive the lookback
the same way as the other provider scan methods.
Added: Both collect_analytics and collect_user_usage now reject an
inverted date range (endDate at or before startDate) via a shared
assertRange check, instead of silently sending a backwards window to the
Analytics API — collect_user_usage additionally used this to guard
against a near-zero periodMinutes producing wildly inflated per-minute
rates in totals.
2026.07.18.1
Added: An upgrades array entry (no-op) to analytics.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.
2026.07.14.1
Added: collect_user_usage — per-user token usage and cost, so you can see
who is spending what (and how much of it is Claude Code) rather than only the
org aggregate.
Reads the Enterprise Analytics
/v1/organizations/analytics/user_usage_report(tokens: total / output / uncached-input / cache-read, plus requests) and/user_cost_report(amountandlist_amount, USD minor units → USD), grouped byproductsoclaude_codeis broken out from chat/cowork/etc.Optional
emailfilter keeps just one user (matched onactor.email);productsfilters the surfaces;startDate/endDatebound the window (defaults to the last 30 days; the API caps a window at 31 days).Writes a
userUsageresource (instance = the sanitized email, orall) with a per-userbyProductbreakdown plustotalTokens/totalCostUsd. Reuses the samex-api-key(read:analytics) auth and cursor pagination ascollect_analytics. The two reports are collected independently: if onlyuser_cost_reportfails (common on seat-based plans, where it 403s while the usage report still serves tokens), the token data is retained withcollected: trueandcostUsdleft null —collected: falseonly when both fail. A singleemail-filtered result is keyed by the user's unique id (user-<userId>) so emails that sanitize alike cannot collide.Caveats: with no
emailfilter the resource stores email + name for every org user (admin-only PII — mind shared datastores); and very large orgs can page-truncate (the filter is applied after fetch), so prefer a date-bounded, filtered query for a single user.
Additive: collect_analytics and its snapshot/seats/adoption/cost resources are
unchanged.
2026.07.07.1
Fixed:
collect_analyticscalled a non-existent endpoint (/v1/organizations/analytics, HTTP 404) with the wrong param names (start_date/end_date) and a flat-metrics response shape that never matched the real API. Rewritten against the documented Enterprise Analytics API:/analytics/summaries(seats + DAU/WAU/MAU + pending invites,starting_date/ending_date),/analytics/users(paginated, aggregated into adopter counts), and/analytics/cost_report(paginated, summed by cost type).
Added:
costresource — token cost/usage over the window (usage-based Enterprise plans).- Adoption and cost collection are best-effort: a failure in
/usersor/cost_reportno longer fails the whole run (seat-based plans have no cost data).
Changed:
adoptionnow reports adopter counts (users with ≥1 project/skill/connector), aggregated from/analytics/users— there is no org-level adoption endpoint.- The
snapshotresource writes to therecentinstance (latestis reserved by swamp). Query viadata.latest("claude-analytics", "recent").
2026.07.02.1
Added: Initial release. Enterprise Analytics observation model. Collects raw metrics snapshot and extracts structured seat counts (total, active, pending, DAU/WAU/MAU) and adoption metrics (projects, skills, connectors) into separate versioned resources.
2026.07.18.1
Added: An upgrades array entry (no-op) to analytics.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.
2026.07.14.1
Added: collect_user_usage — per-user token usage and cost, so you can see
who is spending what (and how much of it is Claude Code) rather than only the
org aggregate.
Reads the Enterprise Analytics
/v1/organizations/analytics/user_usage_report(tokens: total / output / uncached-input / cache-read, plus requests) and/user_cost_report(amountandlist_amount, USD minor units → USD), grouped byproductsoclaude_codeis broken out from chat/cowork/etc.Optional
emailfilter keeps just one user (matched onactor.email);productsfilters the surfaces;startDate/endDatebound the window (defaults to the last 30 days; the API caps a window at 31 days).Writes a
userUsageresource (instance = the sanitized email, orall) with a per-userbyProductbreakdown plustotalTokens/totalCostUsd. Reuses the samex-api-key(read:analytics) auth and cursor pagination ascollect_analytics. The two reports are collected independently: if onlyuser_cost_reportfails (common on seat-based plans, where it 403s while the usage report still serves tokens), the token data is retained withcollected: trueandcostUsdleft null —collected: falseonly when both fail. A singleemail-filtered result is keyed by the user's unique id (user-<userId>) so emails that sanitize alike cannot collide.Caveats: with no
emailfilter the resource stores email + name for every org user (admin-only PII — mind shared datastores); and very large orgs can page-truncate (the filter is applied after fetch), so prefer a date-bounded, filtered query for a single user.
Additive: collect_analytics and its snapshot/seats/adoption/cost resources are
unchanged.
2026.07.07.1
Fixed:
collect_analyticscalled a non-existent endpoint (/v1/organizations/analytics, HTTP 404) with the wrong param names (start_date/end_date) and a flat-metrics response shape that never matched the real API. Rewritten against the documented Enterprise Analytics API:/analytics/summaries(seats + DAU/WAU/MAU + pending invites,starting_date/ending_date),/analytics/users(paginated, aggregated into adopter counts), and/analytics/cost_report(paginated, summed by cost type).
Added:
costresource — token cost/usage over the window (usage-based Enterprise plans).- Adoption and cost collection are best-effort: a failure in
/usersor/cost_reportno longer fails the whole run (seat-based plans have no cost data).
Changed:
adoptionnow reports adopter counts (users with ≥1 project/skill/connector), aggregated from/analytics/users— there is no org-level adoption endpoint.- The
snapshotresource writes to therecentinstance (latestis reserved by swamp). Query viadata.latest("claude-analytics", "recent").
2026.07.02.1
Added: Initial release. Enterprise Analytics observation model. Collects raw metrics snapshot and extracts structured seat counts (total, active, pending, DAU/WAU/MAU) and adoption metrics (projects, skills, connectors) into separate versioned resources.
Modified 1 models
2026.07.07.1
Fixed:
collect_analyticscalled a non-existent endpoint (/v1/organizations/analytics, HTTP 404) with the wrong param names (start_date/end_date) and a flat-metrics response shape that never matched the real API. Rewritten against the documented Enterprise Analytics API:/analytics/summaries(seats + DAU/WAU/MAU + pending invites,starting_date/ending_date),/analytics/users(paginated, aggregated into adopter counts), and/analytics/cost_report(paginated, summed by cost type).
Added:
costresource — token cost/usage over the window (usage-based Enterprise plans).- Adoption and cost collection are best-effort: a failure in
/usersor/cost_reportno longer fails the whole run (seat-based plans have no cost data).
Changed:
adoptionnow reports adopter counts (users with ≥1 project/skill/connector), aggregated from/analytics/users— there is no org-level adoption endpoint.- The
snapshotresource writes to therecentinstance (latestis reserved by swamp). Query viadata.latest("claude-analytics", "recent").
2026.07.02.1
Added: Initial release. Enterprise Analytics observation model. Collects raw metrics snapshot and extracts structured seat counts (total, active, pending, DAU/WAU/MAU) and adoption metrics (projects, skills, connectors) into separate versioned resources.
Modified 1 models
2026.07.02.1
Added: Initial release. Enterprise Analytics observation model. Collects raw metrics snapshot and extracts structured seat counts (total, active, pending, DAU/WAU/MAU) and adoption metrics (projects, skills, connectors) into separate versioned resources.
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned