One read of Claude Developer Platform
127 pages moved out of 688 read.
about-claude/models/optimizing-for-cost-and-intelligence Changed · +88 / -51 lines
#### Why caching comes first #### Pick the cache duration #### Turn on caching #### What breaks the cache
| Your situation | Do this | Where | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Any workload, any model | Turn on prompt caching and trim unneeded tokens; both are free | [Cache repeated context](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#cache-repeated-context) · [Trim tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | +| A person waits between turns | Use the 1-hour cache duration; it is cheaper once about 1 turn in 20 follows a pause between 5 minutes and an hour and few gaps run over an hour | [Pick the cache duration](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#pick-the-cache-duration) | | Costs are too high; quality is fine | Sweep effort down on your current model | [Tune effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#tune-effort) | | You are not on the latest model | Upgrade; the current model solves more, usually at lower cost per solved task | [Upgrade the model](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#upgrade-the-model) | | You are choosing or switching models | Compare on cost per completed task, not per token | [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) |
### Cache repeated context +#### Why caching comes first + Turn on [prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching) before any other lever, because every turn of an agentic task resends the entire growing conversation: system prompt, tool definitions, and every prior turn. A 40-turn task sends its first turn 40 times, so task cost grows with roughly the square of turn count. Caching does not stop the resending, but each resend costs about a tenth as much and processes faster: the prefix is billed at the [cache-read rate](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing), a tenth of the input price, and each turn pays the 1.25x cache-write rate only for what is new. Across Anthropic's measured runs, cache reads are routinely the largest single component of task cost, making caching worth more than most model-choice decisions. Anthropic priced WideSearch[1](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs) and DeepResearch Bench II[7](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs) runs with and without caching:
 -The cache's default lifetime is 5 minutes and an agent loop's turns are seconds apart, so the discount applies to most tokens on every turn; the charted runs achieved 81% to 90% hit rates. The saving varies with episode depth, because shorter loops re-read less, but caching stayed the largest single lever on every model and benchmark measured. +The cache's default lifetime is 5 minutes and an agent loop's turns are seconds apart, so the discount applies to most tokens on every turn. The caching chart's runs achieved 81% to 90% hit rates. The saving varies with episode depth, because shorter loops re-read less, but caching stayed the largest single lever on every model and benchmark measured. -If your loop waits on humans between turns, use the [1-hour cache duration](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#1-hour-cache-duration). It costs more to write (2x the input price instead of 1.25x) but pays for itself on the first prevented miss, because a miss resends the whole prefix at full price and writes it again. +#### Pick the cache duration +If your loop waits on a person between turns, use the [1-hour cache duration](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#1-hour-cache-duration). It costs more to write (2x the input price instead of 1.25x). A miss on either duration bills the whole prefix at the write price instead of the read price, so the longer duration pays off once a few turns per session follow a pause between 5 minutes and an hour. + +To decide, count the gaps between consecutive requests in a conversation: + +* More than about 1 gap in 20 falls between 5 minutes and an hour, and gaps over an hour are rare: use the 1-hour duration. +* Turns arrive seconds apart: stay on the 5-minute default. With no pauses, it cost 15% less than the 1-hour setting on Claude Sonnet 5 and 11% less on Claude Opus 5. +* Gaps over an hour are common: stay on the default. A gap over an hour expires both durations, and the 1-hour setting then re-writes the prefix at 2x the input price instead of 1.25x, so it loses on each of those gaps. It pays off only when, beyond the 1-in-20 share, gaps between 5 minutes and an hour are at least about two-thirds as frequent as gaps over an hour (each in-band gap saves about 1.15x the prefix; each gap over an hour costs about 0.75x). + +Anthropic measured the 20-issue triage job from [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) with pauses inserted before some turns to simulate a person's delay[16](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs). On both models measured, Claude Sonnet 5 and Claude Opus 5, the 1-hour cache became the cheaper setting once about 3% of turns followed a pause, about 1 turn in 30. The 1-in-20 rule is set above that crossover to leave a margin. With a pause before every turn, the 5-minute setting cost $4.13 per 20-issue session compared with $0.70 for the 1-hour setting on Claude Sonnet 5, and $13.41 compared with $2.70 on Claude Opus 5. Every current model uses the same cache multipliers, so the crossover is in the same range on the other models; the exact share depends on how much of a session the model re-reads. Accuracy stayed within run-to-run noise in every cell. The turn after a pause kept its warm-cache latency on the 1-hour setting. The following chart plots cost per session against the share of paused turns on Claude Sonnet 5: + + + +Anthropic also measured extra requests that keep the 5-minute cache warm. They saved nothing measurable over the 1-hour duration at any share of paused turns and cost more with a pause before every turn, so use the duration instead. + +#### Turn on caching + Setup takes little work. [Automatic caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#automatic-caching) places breakpoints for you; otherwise, the [Claude API skill](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/claude-api-skill) that ships with Claude Code can add caching to an existing integration from one prompt. The following excerpt shows the skill adding it to the harness that produced these measurements: ```text wrap
Those breakpoint placements follow the standard pattern in [Explicit cache breakpoints](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#explicit-cache-breakpoints). +#### What breaks the cache + Four things can break your cache during a task. Anything that changes per request, such as a timestamp or a queue position, placed ahead of the stable prefix turns every request into a full cache write: on the triage run in [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens), a 25-token status line at the front of the system prompt cost $4.24 per run instead of $0.59, more than running with caching off. Keep per-request text in the newest user turn. Changing [`effort`](https://platform.claude.com/docs/en/build-with-claude/effort) between requests invalidates the cached prefix, so change it only where you would re-cache anyway, such as at a [compaction](https://platform.claude.com/docs/en/build-with-claude/compaction) boundary. Changing a [task budget](https://platform.claude.com/docs/en/build-with-claude/task-budgets) partway through does the same, so set it once, on the first request. Every [context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing#context-editing-and-prompt-caching) pass invalidates the prefix from the point it clears and the next request pays to re-cache everything after it, so clear in a few large batches rather than many small ones. Make the last three changes at natural breaks, then confirm cache reads have not dropped; if they have, [cache diagnostics](https://platform.claude.com/docs/en/build-with-claude/cache-diagnostics) shows where the prefix diverged. ### Trim input and context tokens
## Measure on your own workload -The numbers on this page are from July and August 2026, at the list prices of the time, and will drift as models and prices change. Your escalation rate, how cleanly tasks split, and transcript length move them too. The method stays the same: +The numbers on this page reflect list prices at the time of measurement and drift as models and prices change. Your escalation rate, how cleanly tasks split, and transcript length move them too. The method stays the same: -1. Pull a few tasks from production logs, weighted like real traffic, and [write outcome checks](https://platform.claude.com/docs/en/test-and-evaluate/develop-tests) for each: tests pass, ticket closed, row count correct. Record cost per task beside the score: price the four token counts in each response's `usage` at their own rates, summed across the task's requests (the [Usage and Cost API](https://platform.claude.com/docs/en/manage-claude/usage-cost-api) reports the aggregate). +1. Pull a few tasks from production logs, weighted like real traffic, and [write outcome checks](https://platform.claude.com/docs/en/test-and-evaluate/develop-tests) for each: tests pass, ticket closed, row count correct. Record cost per task beside the score: price the five priced token counts in each response's `usage` at their own rates, summed across the task's requests (the [Usage and Cost API](https://platform.claude.com/docs/en/manage-claude/usage-cost-api) reports the aggregate). The 1-hour cache write bills at 2x the input price, and the 5-minute write at 1.25x. 2. Baseline the model tiers across effort levels, not only the default, and plot score against spend. A multi-model configuration must beat the single model's whole curve. 3. If the curve shows a gap effort can't close, add the multi-model strategy that fits and re-run the suite. 4. Run the winner in shadow on a traffic slice before cutover, then keep the suite running.
cost=$(jq -r --argjson in_price "$INPUT_PER_MTOK" --argjson out_price "$OUTPUT_PER_MTOK" ' .usage | (.input_tokens * $in_price - + (.cache_creation_input_tokens // 0) * $in_price * 1.25 # 5-minute cache write - + (.cache_read_input_tokens // 0) * $in_price * 0.10 # cache read + + (.cache_creation.ephemeral_1h_input_tokens // 0) * $in_price * 2.00 # 1-hour cache write + + (.cache_creation.ephemeral_5m_input_tokens // 0) * $in_price * 1.25 # 5-minute cache write + + (.cache_read_input_tokens // 0) * $in_price * 0.10 # cache read + .output_tokens * $out_price) / 1e6 ' <<<"$response") printf 'Request cost: $%.6f\n' "$cost"
COST=$(jq -r --argjson in_price "$INPUT_PER_MTOK" --argjson out_price "$OUTPUT_PER_MTOK" ' (.input_tokens * $in_price - + (.cache_creation_input_tokens // 0) * $in_price * 1.25 # 5-minute cache write - + (.cache_read_input_tokens // 0) * $in_price * 0.10 # cache read + + (.cache_creation.ephemeral_1h_input_tokens // 0) * $in_price * 2.00 # 1-hour cache write + + (.cache_creation.ephemeral_5m_input_tokens // 0) * $in_price * 1.25 # 5-minute cache write + + (.cache_read_input_tokens // 0) * $in_price * 0.10 # cache read + .output_tokens * $out_price) / 1e6 ' <<<"$USAGE") printf 'Request cost: $%.6f\n' "$COST"
messages=[{"role": "user", "content": "Hello, Claude"}], ) usage = response.usage + cache_writes = usage.cache_creation + writes_1h = cache_writes.ephemeral_1h_input_tokens if cache_writes else 0 + writes_5m = cache_writes.ephemeral_5m_input_tokens if cache_writes else 0 cost = ( usage.input_tokens * INPUT_PER_MTOK - # Cache writes bill at 1.25x the input price (5-minute cache); cache reads at 0.1x. - + (usage.cache_creation_input_tokens or 0) * INPUT_PER_MTOK * 1.25 + # 1-hour cache writes bill at 2x the input price, 5-minute at 1.25x; reads at 0.1x. + + writes_1h * INPUT_PER_MTOK * 2.0 + + writes_5m * INPUT_PER_MTOK * 1.25 + (usage.cache_read_input_tokens or 0) * INPUT_PER_MTOK * 0.10 + usage.output_tokens * OUTPUT_PER_MTOK ) / 1_000_000
const usage = response.usage; const cost = (usage.input_tokens * INPUT_PER_MTOK + - (usage.cache_creation_input_tokens ?? 0) * INPUT_PER_MTOK * 1.25 + // 5-minute cache write + (usage.cache_creation?.ephemeral_1h_input_tokens ?? 0) * INPUT_PER_MTOK * 2 + // 1-hour cache write + (usage.cache_creation?.ephemeral_5m_input_tokens ?? 0) * INPUT_PER_MTOK * 1.25 + // 5-minute cache write (usage.cache_read_input_tokens ?? 0) * INPUT_PER_MTOK * 0.1 + // cache read usage.output_tokens * OUTPUT_PER_MTOK) / 1_000_000;
double cost = ( usage.InputTokens * InputPerMtok - + (usage.CacheCreationInputTokens ?? 0) * InputPerMtok * 1.25 // 5-minute cache write + + (usage.CacheCreation?.Ephemeral1hInputTokens ?? 0) * InputPerMtok * 2.00 // 1-hour cache write + + (usage.CacheCreation?.Ephemeral5mInputTokens ?? 0) * InputPerMtok * 1.25 // 5-minute cache write + (usage.CacheReadInputTokens ?? 0) * InputPerMtok * 0.10 // cache read + usage.OutputTokens * OutputPerMtok ) / 1_000_000;
usage := response.Usage cost := (float64(usage.InputTokens)*inputPerMTok + - float64(usage.CacheCreationInputTokens)*inputPerMTok*1.25 + // 5-minute cache write + float64(usage.CacheCreation.Ephemeral1hInputTokens)*inputPerMTok*2.00 + // 1-hour cache write + float64(usage.CacheCreation.Ephemeral5mInputTokens)*inputPerMTok*1.25 + // 5-minute cache write float64(usage.CacheReadInputTokens)*inputPerMTok*0.10 + // cache read float64(usage.OutputTokens)*outputPerMTok) / 1_000_000 fmt.Printf("Request cost: $%.6f\n", cost)
.build()); Usage usage = response.usage(); + long writes1h = usage.cacheCreation().map(CacheCreation::ephemeral1hInputTokens).orElse(0L); + long writes5m = usage.cacheCreation().map(CacheCreation::ephemeral5mInputTokens).orElse(0L); double cost = (usage.inputTokens() * INPUT_PER_MTOK - + usage.cacheCreationInputTokens().orElse(0L) * INPUT_PER_MTOK * 1.25 // 5-minute cache write + + writes1h * INPUT_PER_MTOK * 2.00 // 1-hour cache write + + writes5m * INPUT_PER_MTOK * 1.25 // 5-minute cache write + usage.cacheReadInputTokens().orElse(0L) * INPUT_PER_MTOK * 0.10 // cache read + usage.outputTokens() * OUTPUT_PER_MTOK) / 1_000_000; IO.println("Request cost: $%.6f".formatted(cost));
$usage = $response->usage; $cost = ( $usage->inputTokens * INPUT_PER_MTOK - + ($usage->cacheCreationInputTokens ?? 0) * INPUT_PER_MTOK * 1.25 // 5-minute cache write + + ($usage->cacheCreation?->ephemeral1hInputTokens ?? 0) * INPUT_PER_MTOK * 2.00 // 1-hour cache write + + ($usage->cacheCreation?->ephemeral5mInputTokens ?? 0) * INPUT_PER_MTOK * 1.25 // 5-minute cache write + ($usage->cacheReadInputTokens ?? 0) * INPUT_PER_MTOK * 0.10 // cache read + $usage->outputTokens * OUTPUT_PER_MTOK ) / 1_000_000;
usage = response.usage cost = ( usage.input_tokens * INPUT_PER_MTOK + - usage.cache_creation_input_tokens.to_i * INPUT_PER_MTOK * 1.25 + # 5-minute cache write + usage.cache_creation&.ephemeral_1h_input_tokens.to_i * INPUT_PER_MTOK * 2.00 + # 1-hour cache write + usage.cache_creation&.ephemeral_5m_input_tokens.to_i * INPUT_PER_MTOK * 1.25 + # 5-minute cache write usage.cache_read_input_tokens.to_i * INPUT_PER_MTOK * 0.10 + # cache read usage.output_tokens * OUTPUT_PER_MTOK ) / 1_000_000
``` </CodeGroup> -In agent loops the cache-read term is usually the largest of the four; if not, check that caching is engaged. When the [advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#usage-and-billing) or [compaction](https://platform.claude.com/docs/en/build-with-claude/compaction#understanding-usage) is enabled, some tokens are reported only in `usage.iterations` and not in the top-level totals, so sum over `usage.iterations` instead, pricing `advisor_message` entries at the advisor model's rates. +In agent loops the cache-read term is usually the largest of the five; if not, check that caching is engaged. When the [advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#usage-and-billing) or [compaction](https://platform.claude.com/docs/en/build-with-claude/compaction#understanding-usage) is enabled, some tokens are reported only in `usage.iterations` and not in the top-level totals, so sum over `usage.iterations` instead, pricing `advisor_message` entries at the advisor model's rates. The following table lists the levers in the order to try them: -| Lever | Saving in these runs | Quality cost | Latency | Where | -| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Prompt caching | Cost cut by a factor of 2.5 to 3.7 on agent loops; 83% on the triage run | None | Faster | [Cache repeated context](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#cache-repeated-context) | -| Input trimming | A further 5 percentage points on the triage run | None | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | -| Prune stale tool results at task boundaries | 39% on the long triage run (compaction 32%); nothing on short loops | None measured | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | -| Tool search | 45% with 500 tool definitions attached; 20% with a GitHub MCP server | None | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | -| Data files through code execution | 92% on a 25-question data task | A gain, 25 of 25 instead of 6 of 25 | Faster | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | -| Batch API | 50% | None | Results within 24 hours | [Batch work that can wait](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#batch-work-that-can-wait) | -| Prompt audit against the current model | 14% on both migrations measured | None; a gain on one | Faster (fewer tool rounds) | [Audit prompts against the current model](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#audit-prompts-against-the-current-model) | -| Upgrade the model | Opus 4.7 to Opus 5: about 12% less per solved task, 11 more points; Sonnet 4.6 to Sonnet 5: 14% less, 5 more points | A gain | Neutral | [Upgrade the model](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#upgrade-the-model) | -| Lower effort | Knowledge work: `medium` 15% to 30%, `low` a third to a half; long coding: `medium` about half, `low` about three quarters | 1 to 3 points on knowledge work, 2 to 8 on long coding | Faster | [Tune effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#tune-effort) | -| Re-run failures | About half, at the same pass rate | None | Two runs on the tasks that fail | [Re-run failures at higher effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#re-run-failures-at-higher-effort) | -| Task budget | 18% to 47% | 3 to 4 points | Faster | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | -| Ask for shorter answers | 39% of output tokens, 14% of cost on the triage run | None | Faster | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | -| Raising `max_tokens` | None per solved task, but more tasks solved | Gains of 2 to 18 points | Neutral | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | -| Advisor | Depends on the capability gap and the consult rate; the chart-reading pairing scored above both models' effort curves, the coding pairing only marginally | Small gains | About two extra calls per task | [Advisor strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#advisor-strategy-escalate-hard-decisions) | -| Orchestrator | More than 60% below the frontier model beyond one context window; about half on routine tails | 2 to 6 points below the frontier model | Much faster on large inputs | [Orchestrator strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#orchestrator-strategy-delegate-bulk-work) | +| Lever | Saving in these runs | Quality cost | Latency | Where | +| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Prompt caching | Cost cut by a factor of 2.5 to 3.7 on agent loops; 83% on the triage run | None | Faster | [Cache repeated context](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#cache-repeated-context) | +| 1-hour cache duration | Cheaper than the 5-minute default once about 1 turn in 20 follows a pause between 5 minutes and an hour and few gaps run over an hour; with no pauses the default cost 15% less on Claude Sonnet 5 and 11% less on Claude Opus 5 | None | Stays warm after a pause | [Pick the cache duration](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#pick-the-cache-duration) | +| Input trimming | A further 5 percentage points on the triage run | None | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | +| Prune stale tool results at task boundaries | 39% on the long triage run (compaction 32%); nothing on short loops | None measured | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | +| Tool search | 45% with 500 tool definitions attached; 20% with a GitHub MCP server | None | Neutral | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | +| Data files through code execution | 92% on a 25-question data task | A gain, 25 of 25 instead of 6 of 25 | Faster | [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens) | +| Batch API | 50% | None | Results within 24 hours | [Batch work that can wait](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#batch-work-that-can-wait) | +| Prompt audit against the current model | 14% on both migrations measured | None; a gain on one | Faster (fewer tool rounds) | [Audit prompts against the current model](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#audit-prompts-against-the-current-model) | +| Upgrade the model | Opus 4.7 to Opus 5: about 12% less per solved task, 11 more points; Sonnet 4.6 to Sonnet 5: 14% less, 5 more points | A gain | Neutral | [Upgrade the model](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#upgrade-the-model) | +| Lower effort | Knowledge work: `medium` 15% to 30%, `low` a third to a half; long coding: `medium` about half, `low` about three quarters | 1 to 3 points on knowledge work, 2 to 8 on long coding | Faster | [Tune effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#tune-effort) | +| Re-run failures | About half, at the same pass rate | None | Two runs on the tasks that fail | [Re-run failures at higher effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#re-run-failures-at-higher-effort) | +| Task budget | 18% to 47% | 3 to 4 points | Faster | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | +| Ask for shorter answers | 39% of output tokens, 14% of cost on the triage run | None | Faster | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | +| Raising `max_tokens` | None per solved task, but more tasks solved | Gains of 2 to 18 points | Neutral | [Set budgets and output caps](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) | +| Advisor | Depends on the capability gap and the consult rate; the chart-reading pairing scored above both models' effort curves, the coding pairing only marginally | Small gains | About two extra calls per task | [Advisor strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#advisor-strategy-escalate-hard-decisions) | +| Orchestrator | More than 60% below the frontier model beyond one context window; about half on routine tails | 2 to 6 points below the frontier model | Much faster on large inputs | [Orchestrator strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#orchestrator-strategy-delegate-bulk-work) | ## Benchmarks referenced -All measurements are Anthropic-internal runs of these benchmarks. Unless noted, costs are USD at August 2026 list prices; Claude Sonnet 5 figures use $2 and $10 per million input and output tokens. Charts labeled "notional USD" price each request's token counts at those rates rather than reporting invoices. +All measurements are Anthropic-internal runs of these benchmarks. Unless noted, costs are USD at the list prices in effect when each benchmark ran; Claude Sonnet 5 figures use $2 and $10 per million input and output tokens. Charts labeled "notional USD" price each request's token counts at those rates rather than reporting invoices. -1. **WideSearch:** Wong et al., "WideSearch: Benchmarking Agentic Broad Info-Seeking," arXiv:2508.07999, 2025. Broad web-research tasks graded on a many-row table's completeness and accuracy; 200 problems, 3 runs per configuration. The caching and effort charts come from separate runs, so per-problem costs differ slightly. The cost-concentration chart is a separate 20-problem run, 3 runs per problem, costed from per-request billing records. -2. **GDPval:** OpenAI, "GDPval: Evaluating AI Model Performance on Real-World Economically Valuable Tasks," 2025. Knowledge-work deliverables graded against task rubrics; a 210-task run of the released gold set, one attempt per task. A Claude model grades, so absolute scores may differ from published results. -3. **SWE-bench Pro:** Scale AI, "SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks?", 2025. A 482-problem subset selected for compatibility with Anthropic's evaluation harness; scores are not comparable to the public leaderboard. Claude Opus 5 at the default effort averages two runs; reduced-effort settings are single runs. Escalation figures come task by task from those runs: `low` first, then the default on its failures, solved 92.5% to 93.6% across run pairings for about $0.70; `medium` first, 93.8% to 94.2% for about $0.95; the default re-run on its own failures, 94.0% for $1.58; everything at the default, 90.9% to 92.5% for $1.39. The Claude Sonnet 5 executor pairings on the advisor chart come from the same August 2026 series on this subset: the Sonnet-plus-Opus pairing was run twice (a run and an exact replication), the low-effort pairing once, and Claude Sonnet 5 alone twice (77.4%, the baseline for both Pro rows); the task-budget figures are one run per budget on the same subset. The Claude Fable 5 figure in [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) is a single July 2026 run, also the task-budget chart's unbudgeted baseline; every budgeted run completed all 482 problems without harness errors. The upgrade ladder is one run per model at its shipped defaults (two each for Opus 5 and Sonnet 5), run the same week in one harness and organization. -4. **BrowseComp:** Wei et al., "BrowseComp: A Simple Yet Challenging Benchmark for Browsing Agents," OpenAI, 2025. Effort figures use a 500-problem cut, one to three runs per setting. The cost-insurance chart uses 10 reliably solved problems from a 26-problem slice, 50 delegated and 70 solo runs ($6.45 compared with $11.99 per run in expectation); delegated figures carry a measurement band of about 20%. +1. **WideSearch:** Wong et al., "WideSearch: Benchmarking Agentic Broad Info-Seeking," arXiv:2508.07999, 2025. Broad web-research tasks graded on a many-row table's completeness and accuracy; 200 problems, 3 runs per configuration, run August 1 to 2, 2026. The caching chart re-prices the effort chart's default-effort runs from their per-request billing records; per-problem costs differ slightly because the two charts use different cost accounting. The cost-concentration chart is a separate 20-problem run, 3 runs per problem, run August 3 to 4, 2026, costed from per-request billing records. +2. **GDPval:** OpenAI, "GDPval: Evaluating AI Model Performance on Real-World Economically Valuable Tasks," 2025. Knowledge-work deliverables graded against task rubrics; a 210-task run of the released gold set, one attempt per task, run August 2, 2026. A Claude model grades, so absolute scores may differ from published results. +3. **SWE-bench Pro:** Scale AI, "SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks?", 2025. A 482-problem subset selected for compatibility with Anthropic's evaluation harness; scores are not comparable to the public leaderboard. Claude Opus 5 at the default effort averages two runs; reduced-effort settings are single runs; all ran August 4, 2026, as did the task-budget arms. Escalation figures come task by task from those runs: `low` first, then the default on its failures, solved 92.5% to 93.6% across run pairings for about $0.70; `medium` first, 93.8% to 94.2% for about $0.95; the default re-run on its own failures, 94.0% for $1.58; everything at the default, 90.9% to 92.5% for $1.39. The Claude Sonnet 5 executor pairings on the advisor chart come from the same measurement series on this subset: the Sonnet-plus-Opus pairing was run twice (August 7 and August 8, 2026, a run and an exact replication), the low-effort pairing once (August 8, 2026), and Claude Sonnet 5 alone twice (77.4%, the baseline for both Pro rows); the task-budget figures are one run per budget on the same subset. The Claude Fable 5 figure in [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) is a single run from July 2, 2026, also the task-budget chart's unbudgeted baseline; every budgeted run completed all 482 problems without harness errors. The upgrade ladder is one run per model at its shipped defaults (two each for Opus 5 and Sonnet 5), run the same week in one harness and organization. +4. **BrowseComp:** Wei et al., "BrowseComp: A Simple Yet Challenging Benchmark for Browsing Agents," OpenAI, 2025. Effort figures use a 500-problem cut, one to three runs per setting, run August 3, 2026, with the default point pooling two runs from July 26 to 27, 2026. The cost-insurance chart uses 10 reliably solved problems from a 26-problem slice, 50 delegated runs (August 1 to 2, 2026) and 70 solo runs (50 from August 2 to 3, 2026; 20 archived from July 12 to 13 and August 1, 2026), $6.45 compared with $11.99 per run in expectation; delegated figures carry a measurement band of about 20%. 5. **Agent-architecture scaling:** Kim et al., "Towards a Science of Scaling Agent Systems," arXiv:2512.08296, 2025. Independent external study, cited only for the direction of the finding on when delegation does not pay, not for any figure. -6. **DeepWideSearch:** "DeepWideSearch: Benchmarking Depth and Width in Agentic Information Seeking," arXiv:2510.20168, 2025. The 220 questions span 15 domains, each combining many-row collection with multi-hop retrieval; measured on the benchmark's standing row set, 3 runs per configuration. -7. **DeepResearch Bench II:** Li et al., "DeepResearch Bench II: Diagnosing Deep Research Agents via Rubrics from Expert Report," arXiv:2601.08536, 2026. Its 132 research tasks across 22 domains are graded against expert-derived binary rubrics; measured on a 50-task subset stratified across all themes, one attempt per task, 3 runs, scored on tasks no configuration refused. Claude Opus 4.6 judges under the benchmark's rubric protocol; the original uses a different judge, and an Anthropic judge may favor the house style. The runs predate Claude Opus 5, hence its absence from the [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) chart. The Sonnet 5 cost differs slightly between the caching chart (inference cost, with and without caching) and that chart (all-in cost, caching on); both come from the same runs. -8. **Corpus defect sweep:** Anthropic-internal, for work larger than one context window: a 21.6-million-token corpus from 14 public Python package sources with 130 planted defects and deterministic grading; protocol fixed before the runs and internally reviewed; three runs per configuration. Every configuration ran on Claude Managed Agents. The charted team configuration is an August 2026 run in which the Claude Fable 5 coordinator ran the whole sweep inside the platform at its documented limit of 25 concurrent Claude Sonnet 5 workers; its three episodes scored F1 0.842, 0.805, and 0.810 for $263, $299, and $261. The solo configurations are July 2026 runs on the same corpus build. Absolute F1 is specific to this corpus build, not comparable across benchmarks; configuration comparisons are like for like. -9. **GPQA Diamond:** Rein et al., "GPQA: A Graduate-Level Google-Proof Q\&A Benchmark," 2023. The 198-question Diamond subset, measured August 2026, two runs per configuration, model-graded against reference answers, advisor tokens metered per request. A platform safety check refused two biology questions on the Sonnet and Opus executors; excluding them changes no comparison by more than one point. -10. **DeepSWE:** Datacurve, "DeepSWE: Measuring Frontier Coding Agents on Original, Long-Horizon Engineering Tasks," arXiv:2607.07946, 2026. Measured August 2026: 113 original tasks across five languages with program-based verifiers. Pairings are two runs each with advisor tokens metered per request, and used a client-side advisor loop rather than the advisor tool, with identical accounting. Single-model effort sweeps are single runs priced from token counts, a cache-aware approximation. Costs per task are run totals divided by 113. -11. **Internal agentic-coding benchmark:** Anthropic-internal: 370 repository tasks graded by the repositories' own tests. The API figures (Opus 5 alone, Fable 5 alone, and the pairing) were measured August 2026 at the default effort with a 128,000-token output cap, one run per configuration: five attempts per task at the default settings and for the pairing, one at `low` and `medium`; the pairing averaged about two advisor consultations per attempt; costs are per attempt. The Claude Code figures are July 2026 runs of the same tasks, one run per configuration, costs approximate. -12. **Internal repository-task benchmark (cap measurement):** A separate Anthropic-internal set of about 130 repository tasks, run August 2026 with a plain API agent loop, one attempt per task. The 16,384-token figures average two runs per model; the 64,000-token figures are single runs (124 tasks scored for Opus 5; 108 for Claude Fable 5, the environment having skipped the rest before the model ran). About half the Fable attempts the 16,384 cap had ended solved at 64,000; a further Fable run at 128,000 scored 56.1%, within noise of the 64,000 run. The SWE-bench Pro cap figures are one Claude Fable 5 run per cap at the default effort on a 100-problem subset stratified from reference 3's 482-problem set, not comparable to its scores. The chart's per-turn distributions come from the Opus run at 64,000 and the Fable run at 128,000, so neither is cut off by its own cap. -13. **Chartography:** Surge AI, "Chartography," 2026. The complete released 100-question set, measured August 2026 with Anthropic's implementation on Claude Managed Agents (standard cloud sandbox; advisor configurations use the Managed Agents advisor). Claude Sonnet 4.6 grades instead of the reference judge and the benchmark runs with tools, so scores compare across configurations here but not to the published leaderboard. Two runs per configuration, pooled; run-to-run spreads were 4 to 10 points. Costs exclude sandbox time, which added under 1%. The consult-rate comparison comes from rerunning the same configurations on the Messages API with a container tool set. +6. **DeepWideSearch:** "DeepWideSearch: Benchmarking Depth and Width in Agentic Information Seeking," arXiv:2510.20168, 2025. The 220 questions span 15 domains, each combining many-row collection with multi-hop retrieval; measured on the benchmark's standing row set, 3 runs per configuration, run August 2, 2026 (the single-worker team point ran July 26 to 27, 2026). +7. **DeepResearch Bench II:** Li et al., "DeepResearch Bench II: Diagnosing Deep Research Agents via Rubrics from Expert Report," arXiv:2601.08536, 2026. Its 132 research tasks across 22 domains are graded against expert-derived binary rubrics; measured on a 50-task subset stratified across all themes, one attempt per task, 3 runs (August 2 to 3, 2026), scored on tasks no configuration refused. Claude Opus 4.6 judges under the benchmark's rubric protocol; the original uses a different judge, and an Anthropic judge may favor the house style. Anthropic did not run Claude Opus 5 on this benchmark, so it is absent from the [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) chart. The Sonnet 5 cost differs slightly between the caching chart (inference cost, with and without caching) and that chart (all-in cost, caching on); both come from the same runs. +8. **Corpus defect sweep:** Anthropic-internal, for work larger than one context window: a 21.6-million-token corpus from 14 public Python package sources with 130 planted defects and deterministic grading; protocol fixed before the runs and internally reviewed; three runs per configuration. Every configuration ran on Claude Managed Agents. The charted team configuration is an August 13, 2026, run in which the Claude Fable 5 coordinator ran the whole sweep inside the platform at its documented limit of 25 concurrent Claude Sonnet 5 workers; its three episodes scored F1 0.842, 0.805, and 0.810 for $263, $299, and $261. The solo configurations ran August 3 to 4, 2026, on the same corpus build. Absolute F1 is specific to this corpus build, not comparable across benchmarks; configuration comparisons are like for like. +9. **GPQA Diamond:** Rein et al., "GPQA: A Graduate-Level Google-Proof Q\&A Benchmark," 2023. The 198-question Diamond subset, two runs per configuration, run August 7, 2026, model-graded against reference answers, advisor tokens metered per request. A platform safety check refused two biology questions on the Sonnet and Opus executors; excluding them changes no comparison by more than one point. +10. **DeepSWE:** Datacurve, "DeepSWE: Measuring Frontier Coding Agents on Original, Long-Horizon Engineering Tasks," arXiv:2607.07946, 2026. The set has 113 original tasks across five languages with program-based verifiers. Pairings are two runs each, run August 7, 2026, with advisor tokens metered per request, and used a client-side advisor loop rather than the advisor tool, with identical accounting. Single-model effort sweeps are single runs priced from token counts, a cache-aware approximation. Costs per task are run totals divided by 113. +11. **Internal agentic-coding benchmark:** Anthropic-internal: 370 repository tasks graded by the repositories' own tests. The API figures (Opus 5 alone, Fable 5 alone, and the pairing) were measured August 9 to 10, 2026, at the default effort with a 128,000-token output cap, one run per configuration: five attempts per task at the default settings and for the pairing, one at `low` and `medium`; the pairing averaged about two advisor consultations per attempt; costs are per attempt. The Claude Code figures are runs of the same tasks from July 8 to 23, 2026, one run per configuration, costs approximate. +12. **Internal repository-task benchmark (cap measurement):** A separate Anthropic-internal set of about 130 repository tasks, run August 8 to 10, 2026, with a plain API agent loop, one attempt per task. The 16,384-token figures average two runs per model; the 64,000-token figures are single runs (124 tasks scored for Opus 5; 108 for Claude Fable 5, the environment having skipped the rest before the model ran). About half the Fable attempts the 16,384 cap had ended solved at 64,000; a further Fable run at 128,000 scored 56.1%, within noise of the 64,000 run. The SWE-bench Pro cap figures are one Claude Fable 5 run per cap (August 10, 2026) at the default effort on a 100-problem subset stratified from reference 3's 482-problem set, not comparable to its scores. The chart's per-turn distributions come from the Opus run at 64,000 and the Fable run at 128,000, so neither is cut off by its own cap. +13. **Chartography:** Surge AI, "Chartography," 2026. The complete released 100-question set, measured August 8 to 10, 2026, with Anthropic's implementation on Claude Managed Agents (standard cloud sandbox; advisor configurations use the Managed Agents advisor). Claude Sonnet 4.6 grades instead of the reference judge and the benchmark runs with tools, so scores compare across configurations here but not to the published leaderboard. Two runs per configuration, pooled; run-to-run spreads were 4 to 10 points. Costs exclude sandbox time, which added under 1%. The consult-rate comparison comes from rerunning the same configurations on the Messages API with a container tool set, August 10 to 11, 2026. 14. **Support-desk prompt-audit evaluation:** An Anthropic-constructed set of 44 support tickets with deterministic grading, run August 2026 under six system prompts, each adding to the same clean prompt one pattern common in prompts written for Claude Opus 4.8 and Claude Sonnet 4.6. Each chart point is one of three cases (older model, newer model on the same prompt, newer model after the audit) averaged over the six prompts and 44 tickets. The Opus 5 accuracy gain has a 95% confidence interval of 3 to 8 points; the Sonnet accuracy differences are within noise. -15. **Data-file question set:** An Anthropic-constructed set of 25 aggregate questions over a 1,862-row slice of a public liquor-sales CSV, with ground truth computed by pandas and exact-match grading, run August 2026 on Claude Sonnet 5 and Claude Opus 5 with thinking disabled (the in-context arm cannot complete at the default), a 4,000-token output cap, and no prompt caching, three runs per configuration. The file arm uploads the CSV through the Files API and uses the `code_execution_20260120` tool. +15. **Data-file question set:** An Anthropic-constructed set of 25 aggregate questions over a 1,862-row slice of a public liquor-sales CSV, with ground truth computed by pandas and exact-match grading, run on Claude Sonnet 5 and Claude Opus 5 with thinking disabled (the in-context arm cannot complete at the default), a 4,000-token output cap, and no prompt caching, three runs per configuration, run August 19, 2026. The file arm uploads the CSV through the Files API and uses the `code_execution_20260120` tool. +16. **Cache duration measurement:** The 20-issue triage job from [Trim input and context tokens](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#trim-input-and-context-tokens), run August 23, 2026, on Claude Sonnet 5 and Claude Opus 5 on the Messages API with the same harness, the Claude Opus 5 cells with `max_tokens` raised to 4,096, with pauses inserted before a randomly chosen share of turns (none, 5%, 10%, and every turn at 6 minutes on all 20 issues on both models, plus every turn at 2 minutes on Claude Sonnet 5; 20-minute pauses on a 5-issue subset on both models; 45-minute pauses on a 5-issue subset on Claude Sonnet 5 only). Three runs per cell, cost computed from each response's `usage` fields on a customer-billed organization at list prices, accuracy against the same gold labels. The crossover is about 3.3% of turns on both models: the median of each session's break-even share, computed by the cost model from that session's turn-by-turn context sizes, over all 45 Claude Sonnet 5 and 36 Claude Opus 5 twenty-issue sessions in the analysis (every pause schedule run on the full job, under all three cache settings, three runs each; the 5-issue cells are not in it). The 5% cell tied on Claude Sonnet 5 because that draw's pauses fell on small prefixes. The page's 1-in-20 rule sits above the measured crossover. Anthropic measured keep-alive requests that refresh the 5-minute cache as a comparator only. They matched the 1-hour setting at best and cost more with a pause before every turn, so do not use them. ## Next steps
api/admin Changed · +795 / -367 lines
This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.
The two sides of this change are too far apart to line up, so this is the differ's own diff of it.
**POST** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Invite a user to join the organization by email. On plans that draw members from a finite pool of purchased seats, the invite automatically consumes a seat from the lowest tier with availability; there is no seat-tier parameter. When no seat is free the request fails with a 400 error rather than purchasing a seat.
Role for the invited User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
- `rbac_group_ids: optional array of string` - RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups (beta), and requires the key to carry the `write:rbac_groups` scope. + RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups, and requires the key to carry the `write:rbac_groups` scope. maxItems: 100
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**GET** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve an invite by ID. #### Path parameters
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**GET** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's invites. #### Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. - `statuses: optional array of "accepted" or "expired" or "pending"`
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**DELETE** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Delete a pending invite. #### Path parameters
**GET** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve a member of the organization by user ID. #### Path parameters
**GET** `/v1/organizations/users` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's members. #### Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. #### Returns
**POST** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Update a member's organization role. #### Path parameters
New role for the User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
**DELETE** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Remove a member from the organization. #### Path parameters
List RBAC Groups in the Claude Enterprise tenant. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Query parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
Retrieve an RBAC Group by ID. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters - `group_id: string` ID of the RBAC Group. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
Create an RBAC Group in the Claude Enterprise tenant. Groups created via the API have source type `"direct"`. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Body parameters
Update an RBAC Group's name. Groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters - `group_id: string` ID of the RBAC Group. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Body parameters
Delete an RBAC Group. Groups provisioned by an identity provider (source type `"scim"`) cannot be deleted via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters - `group_id: string` ID of the RBAC Group. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
List members of an RBAC Group. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
Add a User to an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters - `group_id: string` ID of the RBAC Group. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Body parameters
Remove a User from an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters
- `user_id: string` ID of the User. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
List RBAC Roles in the organization. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. #### Query parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
Retrieve an RBAC Role by ID. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. #### Path parameters - `role_id: string` ID of the RBAC Role. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
List the permissions an RBAC Role grants. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. #### Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
- `data_residency: optional object or null` - Data residency configuration for the workspace. If omitted, defaults to workspace_geo=`"us"`, allowed_inference_geos=`"unrestricted"`, and default_inference_geo=`"global"`. + Data residency configuration for the workspace. If omitted, defaults to `workspace_geo: "us"`, `allowed_inference_geos: "unrestricted"`, and `default_inference_geo: "global"`. - `allowed_inference_geos: optional array of "global" or "us" or "unrestricted" or null`
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
- `workspace_role: "workspace_admin" or "workspace_developer" or "workspace_restricted_developer" or "workspace_user"` - Role of the new Workspace Member. Cannot be "workspace_billing". + Role of the new Workspace Member. Cannot be `workspace_billing`. - `"workspace_admin"`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` - - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. - - - `id: string` - - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. - - - `type: "service_account" or "user"` - - Type of the principal the API key acts as. - - - `"service_account"` - - - `"user"` + - `principal: object or object or null` + + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. + + - `UserActor object` + + - `type: "user_actor"` + + Principal type. Always `"user_actor"` for a User. + + default: user_actor + + - `user_id: string` + + ID of the User the API key acts as. + + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. - `status: "active" or "archived" or "expired" or "inactive"`
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. #### Example
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` - - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. - - - `id: string` - - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. - - - `type: "service_account" or "user"` - - Type of the principal the API key acts as. - - - `"service_account"` - - - `"user"` + - `principal: object or object or null` + + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. + + - `UserActor object` + + - `type: "user_actor"` + + Principal type. Always `"user_actor"` for a User. + + default: user_actor + + - `user_id: string` + + ID of the User the API key acts as. + + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. - `status: "active" or "archived" or "expired" or "inactive"`
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. - `first_id: string or null`
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` - - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. - - - `id: string` - - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. - - - `type: "service_account" or "user"` - - Type of the principal the API key acts as. - - - `"service_account"` - - - `"user"` + - `principal: object or object or null` + + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. + + - `UserActor object` + + - `type: "user_actor"` + + Principal type. Always `"user_actor"` for a User. + + default: user_actor + + - `user_id: string` + + ID of the User the API key acts as. + + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. - `status: "active" or "archived" or "expired" or "inactive"`
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. #### Example
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
"cache_read_input_tokens": 200, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 500, "server_tool_use": { "web_search_requests": 10
UTC date in YYYY-MM-DD format. Returns metrics for this single day only. - pattern: ^\d{4}-\d{2}-\d{2}$ + pattern: ^\d{4}-\d{2}-\d{2}$, format: date - `limit: optional number`
"amount": 186, "currency": "USD" }, - "model": "claude-opus-4-8", + "model": "claude-opus-5", "tokens": { "cache_creation": 2340, "cache_read": 8790,
End of the time bucket (exclusive) in RFC 3339 format. + format: date-time + - `results: array of object` List of cost items for this time bucket. There may be multiple items if one or more `group_by[]` parameters are specified.
- `starting_at: string` Start of the time bucket (inclusive) in RFC 3339 format. + + format: date-time - `has_more: boolean`
"context_window": "0-200k", "cost_type": "tokens", "currency": "USD", - "description": "Claude Sonnet 4 Usage - Input Tokens", + "description": "Claude Opus 5 Usage - Input Tokens", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "service_tier": "standard", "token_type": "uncached_input_tokens", "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
Get organization-wide activity summaries for a date range. -Returns one entry per day in [starting_date, ending_date). Data is -typically available with a 1-day lag and may be revised by a few percent -over the following days: when ending_date is omitted it defaults to the -most recent available day + 1, so the last entry covers the most recent -available day. The series can be scoped to an RBAC group via -filter[]=rbac_group_id:<id>. Available to organizations on a Claude -Enterprise plan. Requires an API key with the `read:analytics` scope. +Returns one entry per day from `starting_date` (inclusive) to `ending_date` +(exclusive). Data is typically available with a 1-day lag and may be +revised by a few percent over the following days: when `ending_date` is +omitted it defaults to the most recent available day + 1, so the last +entry covers the most recent available day. The series can be scoped to +an RBAC group via `filter[]=rbac_group_id:{id}`. Available to +organizations on a Claude Enterprise plan. Requires an API key with the +`read:analytics` scope. #### Query parameters
- `filter: optional array of string` - Filters as 'dimension:value'. Only rbac_group_id is supported (e.g. filter[]=rbac_group_id:<id>); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. rbac_group_id accepts the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. + Filters as `dimension:value`. Only `rbac_group_id` is supported (e.g. `filter[]=rbac_group_id:{id}`); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. `rbac_group_id` accepts the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. maxItems: 100
- `ending_at: string` - End time in UTC of aggregation period (e.g. 2026-01-16T00:00:00Z) + End of the aggregation period (exclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-16T00:00:00Z`). + + format: date-time - `monthly_active_user_count: number`
- `starting_at: string` - Start time in UTC of aggregation period (e.g. 2026-01-15T00:00:00Z) + Start of the aggregation period (inclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-15T00:00:00Z`). + + format: date-time - `weekly_active_user_count: number`
"cowork_weekly_active_user_count": 0, "daily_active_user_count": 0, "daily_adoption_rate": 0, - "ending_at": "ending_at", + "ending_at": "2019-12-27T18:11:19.117Z", "monthly_active_user_count": 0, "monthly_adoption_rate": 0, "pending_invite_count": 0, - "starting_at": "starting_at", + "starting_at": "2019-12-27T18:11:19.117Z", "weekly_active_user_count": 0, "weekly_adoption_rate": 0, "chat_daily_active_user_count": 0,
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` - - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` + + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"cache_read_input_tokens": 0, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 0, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` - - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` + + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `total_tokens: number` - Total token count across all token types. This is the value the default order_by='total_tokens' sorts on. + Total token count across all token types. This is the value the default `order_by` (`total_tokens`) sorts on. - `uncached_input_tokens: number`
"context_window": "0-200k", "ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 891000, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` - - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` + + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"currency": "USD", "inference_geo": "global", "list_amount": "list_amount", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 0,
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` - - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` + + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `token_type: "cache_creation.ephemeral_1h_input_tokens" or "cache_creation.ephemeral_5m_input_tokens" or "cache_read_input_tokens" or 2 more or null` - Token type when cost_type=tokens; null otherwise. + Token type when `cost_type` is `tokens`; null otherwise. - `"cache_creation.ephemeral_1h_input_tokens"`
"ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", "list_amount": "51600.000000", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 128,
Get per-user activity for a given day, with cursor-based pagination. Returns activity metrics for each user in the organization, sorted by email -address. Use group_by[] for per-RBAC-group aggregates, or filter[] to +address. Use `group_by[]` for per-RBAC-group aggregates, or `filter[]` to scope results to specific members, groups, or a chat project. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with group_by[] or an rbac_group_id filter); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with `group_by[]` or an `rbac_group_id` filter); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id"` - Dimensions to break results out by (e.g. group_by[]=rbac_group_id). Supported on this endpoint: rbac_group_id. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=rbac_group_id`). Supported on this endpoint: `rbac_group_id`. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
Core Claude Code activity metrics for a single user on a given day. + - `artifacts_created_count: number` + + Number of artifacts created in Claude Code sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `commit_count: number` Number of commits made via Claude Code
Number of tool actions completed in Cowork sessions + - `artifacts_created_count: number` + + Number of artifacts created in Cowork sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `connectors_used_count: number` Total number of connector invocations in Cowork sessions
- `last_activity_date: optional string or null` - Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested date in single-day mode, and to the latest active day in [starting_date, ending_date) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id` it is the last day the user was active while a member of that group, consistent with the row's other metrics. Null on grouped (`group_by[]`) rows. Omitted from the response while last-activity reporting is not enabled for this organization. + Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested `date` in single-day mode, and to the latest active day from `starting_date` (inclusive) to `ending_date` (exclusive) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id:{id}` it is the last day the user was active while a member of that group, consistent with the row's other metrics. On grouped (`group_by[]`) rows it is the latest day any member of the group was active (the requested `date` in single-day mode). Omitted from the response while last-activity reporting is not enabled for this organization. + + format: date - `rbac_group_id: optional string or null`
- `user: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
}, "claude_code_metrics": { "core_metrics": { + "artifacts_created_count": 0, "commit_count": 0, "distinct_session_count": 0, "lines_of_code": {
}, "cowork_metrics": { "action_count": 0, + "artifacts_created_count": 0, "connectors_used_count": 0, "dispatch_turn_count": 0, "distinct_connectors_used_count": 0,
}, "web_search_count": 0, "distinct_user_count": 0, - "last_activity_date": "last_activity_date", + "last_activity_date": "2019-12-27", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", "user": {
Get per-skill usage for a given day, with cursor-based pagination. Returns skill usage metrics for the organization, sorted by skill name. -Use group_by[] to break usage out per member, per RBAC group, or per -product surface, and filter[] to scope results; the parameter +Use `group_by[]` to break usage out per member, per RBAC group, or per +product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: product, rbac_group_id, share_status, skill_name, user_id. Value forms: product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); share_status is one of organization, private, or public; skill_name matches case-insensitively; user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `product`, `rbac_group_id`, `share_status`, `skill_name`, `user_id`. Value forms: `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `share_status` is one of `organization`, `private`, or `public`; `skill_name` matches case-insensitively; `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `attributed_list_price: optional string or null` - List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that INVOLVED the skill, not the skill's incremental cost. Unlike estimated_overage_spend this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does NOT tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on chat product rows and on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as estimated_overage_spend (spend reporting not enabled for this organization, office_agent product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that involved the skill, not the skill's incremental cost. Unlike `estimated_overage_spend` this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does not tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on `chat` product rows and on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as `estimated_overage_spend` (spend reporting not enabled for this organization, `office_agent` product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `currency: optional "USD" or null` - Currency for this row's monetary fields (estimated_overage_spend and attributed_list_price), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. + Currency for this row's monetary fields (`estimated_overage_spend` and `attributed_list_price`), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. - `enable_count: optional number or null` - Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin install_count). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (starting_date/ending_date). + Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin `install_count`). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (`starting_date`/`ending_date`). - `estimated_overage_spend: optional string or null` - Estimated OVERAGE spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see attributed_list_price for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that INVOLVED the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (starting_date/ending_date) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + Estimated overage spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see `attributed_list_price` for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that involved the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (`starting_date`/`ending_date`) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `invocation_count: optional number or null` - Total number of times this skill was invoked on the requested day (the skill analog of plugin invocation_count). Unlike distinct_user_count — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (starting_date/ending_date) returns this sum directly. + Total number of times this skill was invoked on the requested day (the skill analog of plugin `invocation_count`). Unlike `distinct_user_count` — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (`starting_date`/`ending_date`) returns this sum directly. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Resolved RBAC group display name, alongside `rbac_group_id` when name resolution is available. Null if the group has been deleted or its name could not be resolved; `rbac_group_id` remains the stable key. - - `share_status: optional string or null` - - Skill share status (claude.ai only): one of 'private', 'organization', or 'public'. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:<value>`. + - `share_status: optional "organization" or "private" or "public" or null` + + Skill share status (claude.ai only): one of `private`, `organization`, or `public`. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:{value}`. + + - `"organization"` + + - `"private"` + + - `"public"` - `skill_display_name: optional string or null` - Human-readable display name for rows whose skill_name is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when skill_name is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `skill_name` is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when `skill_name` is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. - `user_id: optional string or null`
"product": "product", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", - "share_status": "share_status", + "share_status": "organization", "skill_display_name": "skill_display_name", "user_id": "user_id" }
Returns connector usage metrics for the organization, sorted by connector name. Connector names are normalized from their various sources — for example, "Atlassian MCP server" and "mcp-atlassian" both appear as -"atlassian". Use group_by[] to break usage out per member, per RBAC -group, or per product surface, and filter[] to scope results; the +"atlassian". Use `group_by[]` to break usage out per member, per RBAC +group, or per product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: connector_name, product, rbac_group_id, user_id. Value forms: connector_name matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose connector_name is an opaque connector id the connector's display name (connector_display_name) also matches; product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `connector_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `connector_name` matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose `connector_name` is an opaque connector id the connector's display name (`connector_display_name`) also matches; `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `connector_name: string` - Name of the connector. Some rows carry an opaque connector id here instead of a readable name; connector_display_name holds the resolved name for those rows. + Name of the connector. Some rows carry an opaque connector id here instead of a readable name; `connector_display_name` holds the resolved name for those rows. - `cowork_metrics: object`
- `connector_display_name: optional string or null` - Human-readable display name for rows whose connector_name is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). connector_name remains the row's stable key for sorting and pagination, and filter[]=connector_name:<value> also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable connector_name. Null when connector_name is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `connector_name` is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). `connector_name` remains the row's stable key for sorting and pagination, and `filter[]=connector_name:{value}` also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable `connector_name`. Null when `connector_name` is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. - `individual_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to managed_auth_distinct_user_count, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. + Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to `managed_auth_distinct_user_count`, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. - `managed_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on user_id and rbac_group_id cuts — attributed to the user the credential was provisioned for — but never on a cut that references product (group or filter). Date-range rollup mode (starting_date/ending_date) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. + Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on `user_id` and `rbac_group_id` cuts — attributed to the user the credential was provisioned for — but never on a cut that references `product` (group or filter). Date-range rollup mode (`starting_date`/`ending_date`) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `read_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of read_call_count, write_call_count, or unclassified_call_count, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in unclassified_call_count). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (starting_date/ending_date) applies both rules server-side. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of `read_call_count`, `write_call_count`, or `unclassified_call_count`, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in `unclassified_call_count`). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (`starting_date`/`ending_date`) applies both rules server-side. - `unclassified_call_count: optional number or null` - Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `user_id: optional string or null`
- `write_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `next_page: string or null`
Get per-project activity for a given day, with cursor-based pagination. Returns activity metrics for each project in the organization, sorted by -project ID. Use group_by[] to break projects out per member or per RBAC -group, and filter[] to scope results; the parameter descriptions list the +project ID. Use `group_by[]` to break projects out per member or per RBAC +group, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `project_id: string` - Tagged project identifier (e.g. claude_proj_...) + Tagged project identifier (e.g. `claude_proj_...`) - `project_name: string`
- `created_at: optional string or null` - Project creation timestamp, RFC 3339. Null if the project was deleted before attribution was recorded. + Project creation timestamp in RFC 3339 format. Null if the project was deleted before attribution was recorded. + + format: date-time - `created_by: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
"message_count": 0, "project_id": "project_id", "project_name": "project_name", - "created_at": "created_at", + "created_at": "2019-12-27T18:11:19.117Z", "created_by": { "id": "id", "email_address": "email_address",
an aggregate bucket, not a plugin: it collects plugin activity, from either surface, for which the reporting client did not provide a plugin name — so an organization's own plugins can contribute both to their own -named rows and to this bucket. Use group_by[] to break usage out per +named rows and to this bucket. Use `group_by[]` to break usage out per member, per RBAC group, or per product surface (Cowork / Claude Code), -and filter[] to scope results; the parameter descriptions list the +and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Requires an API key with the `read:analytics` scope. `starting_date` / `ending_date` select -range-rollup mode like /skills. +range-rollup mode like `/skills`. #### Query parameters
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: plugin_name, product, rbac_group_id, user_id. Value forms: plugin_name matches case-insensitively; product is claude_code or cowork (the only surfaces with plugin attribution); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `plugin_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `plugin_name` matches case-insensitively; `product` is `claude_code` or `cowork` (the only surfaces with plugin attribution); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. On this endpoint product takes the values claude_code or cowork only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. On this endpoint `product` takes the values `claude_code` or `cowork` only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `plugin_id: optional string or null` - Stable plugin identifier when available (e.g. serena@claude-plugins-official). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. + Stable plugin identifier when available (e.g. `serena@claude-plugins-official`). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Get artifact-creation activity for a given day, broken out by MIME type. -Returns the full (artifact_type, is_shared) cube for the organization; +Returns the full (`artifact_type`, `is_shared`) cube for the organization; `next_page` is null except for grouped queries, which paginate. The cube -can be broken out per member or per RBAC group via group_by[], and scoped -via filter[]. Requires an API key with the `read:analytics` scope. +can be broken out per product, per member, or per RBAC group via +`group_by[]`, and scoped via `filter[]`. Requires an API key with the +`read:analytics` scope. #### Query parameters
- `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: artifact_type, is_shared, rbac_group_id, user_id. Value forms: artifact_type is a canonical artifact MIME type (e.g. text/markdown) or 'other'; is_shared is 'true' or 'false'; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `artifact_type`, `is_shared`, `product`, `rbac_group_id`, `user_id`. Value forms: `artifact_type` is a canonical artifact MIME type (e.g. `text/markdown`) or `other`; `is_shared` is `true` or `false`; `product` is `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 -- `group_by: optional array of "rbac_group_id" or "user_id"` - - Dimensions to break results out by: user_id and/or rbac_group_id. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via next_page. rbac_group_id attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. +- `group_by: optional array of "product" or "rbac_group_id" or "user_id"` + + Dimensions to break results out by: `product`, `user_id` and/or `rbac_group_id`. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via `next_page`. `product` takes the values `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts). `rbac_group_id` attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. maxItems: 100 + - `"product"` + - `"rbac_group_id"` - `"user_id"` - `limit: optional number` - Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; limit is the page size only when group_by[] multiplies the cube. + Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; `limit` is the page size only when `group_by[]` multiplies the cube. minimum: 1, maximum: 1000 - `page: optional string` - Opaque cursor from a previous response's next_page field. Only valid with group_by[] — the ungrouped cube is never paginated. + Opaque cursor from a previous response's `next_page` field. Only valid with `group_by[]` — the ungrouped cube is never paginated. #### Returns
Response for GET /v1/organizations/analytics/artifacts. `next_page` is null on ungrouped queries — the artifact-type cube is - finite and returned in full. Grouped queries (`group_by[]` on `user_id` / - `rbac_group_id`) multiply the cube and paginate like the other analytics - list endpoints. + finite and returned in full. Grouped queries (`group_by[]` on `product` / + `user_id` / `rbac_group_id`) multiply the cube and paginate like the other + analytics list endpoints. - `data: array of object` - `artifact_type: string` - Canonical artifact MIME type (e.g. text/markdown, application/vnd.ant.react, image/svg+xml), or 'other'. + Canonical artifact MIME type (e.g. `text/markdown`, `application/vnd.ant.react`, `image/svg+xml`), or `other`. Claude Code and Cowork artifacts report as `text/html`. - `artifacts_created_count: number`
- `is_shared: boolean` - Whether the artifacts in this bucket have ever been shared. + Whether the artifacts in this bucket have ever been shared (a Claude Code / Cowork artifact is shared once anyone beyond its creator may open it: named members, the whole organization, or anyone with the link). - `published_artifacts_created_count: number` - Number of those artifacts that have been published + Number of those artifacts that have been published (for Claude Code / Cowork artifacts: open to anyone with the link); never exceeds `artifacts_created_count` - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Tagged user identifier (e.g. `user_...`). Present only when the request grouped by `user_id`. - - `next_page: optional string or null` + - `next_page: string or null` Cursor for the next page of a grouped query; always null for the ungrouped artifact-type cube, which is returned in full.
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `period: optional "daily" or "monthly" or "weekly"` - `"daily"`
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + + RFC 3339 datetime at which the spend limit was last modified. format: date-time
"amount": "50000", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "period": "monthly" }'
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + + RFC 3339 datetime at which the spend limit was last modified. format: date-time
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
- `limit: optional number` + Maximum number of members per page. A member's period rows never split across pages, so a page may carry more rows than this. Defaults to `20`. + default: 20, maximum: 1000, minimum: 1 - `page: optional string` -- `period: optional array of string` + Opaque cursor from a previous response's `next_page` field. + +- `period: optional array of "daily" or "monthly" or "weekly"` + + Restrict the report to these limit periods. Omit to return one row per period each member resolves a spend limit for. maxItems: 3 + - `"daily"` + + - `"monthly"` + + - `"weekly"` + - `user_ids: optional array of string` + + Restrict the report to these members, by tagged user ID (`user_...`). At most 100 entries. maxItems: 100
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" }
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_limit: SpendLimit` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time - `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit": { "id": "id",
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/update Changed · +1 / -1 lines
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
build-with-claude/claude-in-amazon-bedrock Changed · +2 / -2 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java-bedrock:2.57.0") + implementation("com.anthropic:anthropic-java-bedrock:2.58.0") ``` </Tab>
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-bedrock</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ``` </Tab>
api/admin/workspaces/service_accounts/create Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/service_accounts/retrieve Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/service_accounts Changed · +2 / -2 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/members Changed · +1 / -1 lines
- `workspace_role: "workspace_admin" or "workspace_developer" or "workspace_restricted_developer" or "workspace_user"` - Role of the new Workspace Member. Cannot be "workspace_billing". + Role of the new Workspace Member. Cannot be `workspace_billing`. - `"workspace_admin"`
api/admin/invites/delete Changed · +1 / -1 lines
**DELETE** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Delete a pending invite. ## Path parameters
api/admin/invites/retrieve Changed · +2 / -2 lines
**GET** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve an invite by ID. ## Path parameters
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
api/admin/external_keys/retrieve Changed · +2 / -2 lines
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
api/admin/external_keys/list Changed · +2 / -2 lines
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
agents-and-tools/tool-use/code-execution-tool Changed · +1 / -1 lines
* **External connections:** No outbound network requests permitted * **Sandbox isolation:** Full isolation from host system and other containers * **File access:** Limited to workspace directory only -* **Workspace scoping:** Like the [Files API](https://platform.claude.com/docs/en/build-with-claude/files), containers are scoped to the workspace of the API key +* **Workspace scoping:** Like the [Files API](https://platform.claude.com/docs/en/build-with-claude/files), containers are scoped to the request's workspace * **Expiration:** Containers expire 30 days after creation ### Pre-installed libraries
api/admin/users/update Changed · +2 / -2 lines
**POST** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Update a member's organization role. ## Path parameters
New role for the User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
api/admin/service_accounts/workspaces/create Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/create Changed · +2 / -2 lines
- `data_residency: optional object or null` - Data residency configuration for the workspace. If omitted, defaults to workspace_geo=`"us"`, allowed_inference_geos=`"unrestricted"`, and default_inference_geo=`"global"`. + Data residency configuration for the workspace. If omitted, defaults to `workspace_geo: "us"`, `allowed_inference_geos: "unrestricted"`, and `default_inference_geo: "global"`. - `allowed_inference_geos: optional array of "global" or "us" or "unrestricted" or null`
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
api/admin/service_accounts/workspaces/list Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/members/create Changed · +1 / -1 lines
- `workspace_role: "workspace_admin" or "workspace_developer" or "workspace_restricted_developer" or "workspace_user"` - Role of the new Workspace Member. Cannot be "workspace_billing". + Role of the new Workspace Member. Cannot be `workspace_billing`. - `"workspace_admin"`
api/admin/usage_report/retrieve_claude_code Changed · +2 / -2 lines
UTC date in YYYY-MM-DD format. Returns metrics for this single day only. - pattern: ^\d{4}-\d{2}-\d{2}$ + pattern: ^\d{4}-\d{2}-\d{2}$, format: date - `limit: optional number`
"amount": 186, "currency": "USD" }, - "model": "claude-opus-4-8", + "model": "claude-opus-5", "tokens": { "cache_creation": 2340, "cache_read": 8790,
api/admin/workspaces/service_accounts/list Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/usage_report/retrieve_messages Changed · +1 / -1 lines
"cache_read_input_tokens": 200, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 500, "server_tool_use": { "web_search_requests": 10
api/admin/workspaces/service_accounts/update Changed · +1 / -1 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/users/delete Changed · +1 / -1 lines
**DELETE** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Remove a member from the organization. ## Path parameters
api/admin/analytics Changed · +243 / -155 lines
Get organization-wide activity summaries for a date range. -Returns one entry per day in [starting_date, ending_date). Data is -typically available with a 1-day lag and may be revised by a few percent -over the following days: when ending_date is omitted it defaults to the -most recent available day + 1, so the last entry covers the most recent -available day. The series can be scoped to an RBAC group via -filter[]=rbac_group_id:<id>. Available to organizations on a Claude -Enterprise plan. Requires an API key with the `read:analytics` scope. +Returns one entry per day from `starting_date` (inclusive) to `ending_date` +(exclusive). Data is typically available with a 1-day lag and may be +revised by a few percent over the following days: when `ending_date` is +omitted it defaults to the most recent available day + 1, so the last +entry covers the most recent available day. The series can be scoped to +an RBAC group via `filter[]=rbac_group_id:{id}`. Available to +organizations on a Claude Enterprise plan. Requires an API key with the +`read:analytics` scope. ### Query parameters
- `filter: optional array of string` - Filters as 'dimension:value'. Only rbac_group_id is supported (e.g. filter[]=rbac_group_id:<id>); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. rbac_group_id accepts the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. + Filters as `dimension:value`. Only `rbac_group_id` is supported (e.g. `filter[]=rbac_group_id:{id}`); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. `rbac_group_id` accepts the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. maxItems: 100
- `ending_at: string` - End time in UTC of aggregation period (e.g. 2026-01-16T00:00:00Z) + End of the aggregation period (exclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-16T00:00:00Z`). + format: date-time + - `monthly_active_user_count: number` Number of users with token consumption in the 30-day rolling window
- `starting_at: string` - Start time in UTC of aggregation period (e.g. 2026-01-15T00:00:00Z) + Start of the aggregation period (inclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-15T00:00:00Z`). + format: date-time + - `weekly_active_user_count: number` Number of users with token consumption in the 7-day rolling window
"cowork_weekly_active_user_count": 0, "daily_active_user_count": 0, "daily_adoption_rate": 0, - "ending_at": "ending_at", + "ending_at": "2019-12-27T18:11:19.117Z", "monthly_active_user_count": 0, "monthly_adoption_rate": 0, "pending_invite_count": 0, - "starting_at": "starting_at", + "starting_at": "2019-12-27T18:11:19.117Z", "weekly_active_user_count": 0, "weekly_adoption_rate": 0, "chat_daily_active_user_count": 0,
- `ending_at: string` - End time in UTC of aggregation period (e.g. 2026-01-16T00:00:00Z) + End of the aggregation period (exclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-16T00:00:00Z`). + format: date-time + - `monthly_active_user_count: number` Number of users with token consumption in the 30-day rolling window
- `starting_at: string` - Start time in UTC of aggregation period (e.g. 2026-01-15T00:00:00Z) + Start of the aggregation period (inclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-15T00:00:00Z`). + format: date-time + - `weekly_active_user_count: number` Number of users with token consumption in the 7-day rolling window
- `AnalyticsUser object` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"cache_read_input_tokens": 0, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 0, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `total_tokens: number` - Total token count across all token types. This is the value the default order_by='total_tokens' sorts on. + Total token count across all token types. This is the value the default `order_by` (`total_tokens`) sorts on. - `uncached_input_tokens: number`
"context_window": "0-200k", "ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 891000, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"currency": "USD", "inference_geo": "global", "list_amount": "list_amount", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 0,
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `token_type: "cache_creation.ephemeral_1h_input_tokens" or "cache_creation.ephemeral_5m_input_tokens" or "cache_read_input_tokens" or 2 more or null` - Token type when cost_type=tokens; null otherwise. + Token type when `cost_type` is `tokens`; null otherwise. - `"cache_creation.ephemeral_1h_input_tokens"`
"ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", "list_amount": "51600.000000", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 128,
Get per-user activity for a given day, with cursor-based pagination. Returns activity metrics for each user in the organization, sorted by email -address. Use group_by[] for per-RBAC-group aggregates, or filter[] to +address. Use `group_by[]` for per-RBAC-group aggregates, or `filter[]` to scope results to specific members, groups, or a chat project. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with group_by[] or an rbac_group_id filter); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with `group_by[]` or an `rbac_group_id` filter); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id"` - Dimensions to break results out by (e.g. group_by[]=rbac_group_id). Supported on this endpoint: rbac_group_id. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=rbac_group_id`). Supported on this endpoint: `rbac_group_id`. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
Core Claude Code activity metrics for a single user on a given day. + - `artifacts_created_count: number` + + Number of artifacts created in Claude Code sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `commit_count: number` Number of commits made via Claude Code
Number of tool actions completed in Cowork sessions + - `artifacts_created_count: number` + + Number of artifacts created in Cowork sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `connectors_used_count: number` Total number of connector invocations in Cowork sessions
- `last_activity_date: optional string or null` - Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested date in single-day mode, and to the latest active day in [starting_date, ending_date) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id` it is the last day the user was active while a member of that group, consistent with the row's other metrics. Null on grouped (`group_by[]`) rows. Omitted from the response while last-activity reporting is not enabled for this organization. + Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested `date` in single-day mode, and to the latest active day from `starting_date` (inclusive) to `ending_date` (exclusive) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id:{id}` it is the last day the user was active while a member of that group, consistent with the row's other metrics. On grouped (`group_by[]`) rows it is the latest day any member of the group was active (the requested `date` in single-day mode). Omitted from the response while last-activity reporting is not enabled for this organization. + format: date + - `rbac_group_id: optional string or null` Tagged RBAC group identifier (`rbac_group_...`), matching the spend-limits API spelling. Present only when the request grouped by `rbac_group_id`.
- `user: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
}, "claude_code_metrics": { "core_metrics": { + "artifacts_created_count": 0, "commit_count": 0, "distinct_session_count": 0, "lines_of_code": {
}, "cowork_metrics": { "action_count": 0, + "artifacts_created_count": 0, "connectors_used_count": 0, "dispatch_turn_count": 0, "distinct_connectors_used_count": 0,
}, "web_search_count": 0, "distinct_user_count": 0, - "last_activity_date": "last_activity_date", + "last_activity_date": "2019-12-27", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", "user": {
Get per-skill usage for a given day, with cursor-based pagination. Returns skill usage metrics for the organization, sorted by skill name. -Use group_by[] to break usage out per member, per RBAC group, or per -product surface, and filter[] to scope results; the parameter +Use `group_by[]` to break usage out per member, per RBAC group, or per +product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: product, rbac_group_id, share_status, skill_name, user_id. Value forms: product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); share_status is one of organization, private, or public; skill_name matches case-insensitively; user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `product`, `rbac_group_id`, `share_status`, `skill_name`, `user_id`. Value forms: `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `share_status` is one of `organization`, `private`, or `public`; `skill_name` matches case-insensitively; `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `attributed_list_price: optional string or null` - List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that INVOLVED the skill, not the skill's incremental cost. Unlike estimated_overage_spend this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does NOT tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on chat product rows and on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as estimated_overage_spend (spend reporting not enabled for this organization, office_agent product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that involved the skill, not the skill's incremental cost. Unlike `estimated_overage_spend` this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does not tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on `chat` product rows and on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as `estimated_overage_spend` (spend reporting not enabled for this organization, `office_agent` product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `currency: optional "USD" or null` - Currency for this row's monetary fields (estimated_overage_spend and attributed_list_price), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. + Currency for this row's monetary fields (`estimated_overage_spend` and `attributed_list_price`), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. - `enable_count: optional number or null` - Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin install_count). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (starting_date/ending_date). + Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin `install_count`). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (`starting_date`/`ending_date`). - `estimated_overage_spend: optional string or null` - Estimated OVERAGE spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see attributed_list_price for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that INVOLVED the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (starting_date/ending_date) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + Estimated overage spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see `attributed_list_price` for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that involved the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (`starting_date`/`ending_date`) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `invocation_count: optional number or null` - Total number of times this skill was invoked on the requested day (the skill analog of plugin invocation_count). Unlike distinct_user_count — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (starting_date/ending_date) returns this sum directly. + Total number of times this skill was invoked on the requested day (the skill analog of plugin `invocation_count`). Unlike `distinct_user_count` — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (`starting_date`/`ending_date`) returns this sum directly. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Resolved RBAC group display name, alongside `rbac_group_id` when name resolution is available. Null if the group has been deleted or its name could not be resolved; `rbac_group_id` remains the stable key. - - `share_status: optional string or null` + - `share_status: optional "organization" or "private" or "public" or null` - Skill share status (claude.ai only): one of 'private', 'organization', or 'public'. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:<value>`. + Skill share status (claude.ai only): one of `private`, `organization`, or `public`. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:{value}`. + - `"organization"` + + - `"private"` + + - `"public"` + - `skill_display_name: optional string or null` - Human-readable display name for rows whose skill_name is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when skill_name is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `skill_name` is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when `skill_name` is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. - `user_id: optional string or null`
"product": "product", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", - "share_status": "share_status", + "share_status": "organization", "skill_display_name": "skill_display_name", "user_id": "user_id" }
Returns connector usage metrics for the organization, sorted by connector name. Connector names are normalized from their various sources — for example, "Atlassian MCP server" and "mcp-atlassian" both appear as -"atlassian". Use group_by[] to break usage out per member, per RBAC -group, or per product surface, and filter[] to scope results; the +"atlassian". Use `group_by[]` to break usage out per member, per RBAC +group, or per product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: connector_name, product, rbac_group_id, user_id. Value forms: connector_name matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose connector_name is an opaque connector id the connector's display name (connector_display_name) also matches; product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `connector_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `connector_name` matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose `connector_name` is an opaque connector id the connector's display name (`connector_display_name`) also matches; `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `connector_name: string` - Name of the connector. Some rows carry an opaque connector id here instead of a readable name; connector_display_name holds the resolved name for those rows. + Name of the connector. Some rows carry an opaque connector id here instead of a readable name; `connector_display_name` holds the resolved name for those rows. - `cowork_metrics: object`
- `connector_display_name: optional string or null` - Human-readable display name for rows whose connector_name is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). connector_name remains the row's stable key for sorting and pagination, and filter[]=connector_name:<value> also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable connector_name. Null when connector_name is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `connector_name` is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). `connector_name` remains the row's stable key for sorting and pagination, and `filter[]=connector_name:{value}` also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable `connector_name`. Null when `connector_name` is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. - `individual_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to managed_auth_distinct_user_count, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. + Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to `managed_auth_distinct_user_count`, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. - `managed_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on user_id and rbac_group_id cuts — attributed to the user the credential was provisioned for — but never on a cut that references product (group or filter). Date-range rollup mode (starting_date/ending_date) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. + Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on `user_id` and `rbac_group_id` cuts — attributed to the user the credential was provisioned for — but never on a cut that references `product` (group or filter). Date-range rollup mode (`starting_date`/`ending_date`) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `read_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of read_call_count, write_call_count, or unclassified_call_count, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in unclassified_call_count). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (starting_date/ending_date) applies both rules server-side. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of `read_call_count`, `write_call_count`, or `unclassified_call_count`, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in `unclassified_call_count`). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (`starting_date`/`ending_date`) applies both rules server-side. - `unclassified_call_count: optional number or null` - Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `user_id: optional string or null`
- `write_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `next_page: string or null`
Get per-project activity for a given day, with cursor-based pagination. Returns activity metrics for each project in the organization, sorted by -project ID. Use group_by[] to break projects out per member or per RBAC -group, and filter[] to scope results; the parameter descriptions list the +project ID. Use `group_by[]` to break projects out per member or per RBAC +group, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `project_id: string` - Tagged project identifier (e.g. claude_proj_...) + Tagged project identifier (e.g. `claude_proj_...`) - `project_name: string`
- `created_at: optional string or null` - Project creation timestamp, RFC 3339. Null if the project was deleted before attribution was recorded. + Project creation timestamp in RFC 3339 format. Null if the project was deleted before attribution was recorded. + format: date-time + - `created_by: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
"message_count": 0, "project_id": "project_id", "project_name": "project_name", - "created_at": "created_at", + "created_at": "2019-12-27T18:11:19.117Z", "created_by": { "id": "id", "email_address": "email_address",
an aggregate bucket, not a plugin: it collects plugin activity, from either surface, for which the reporting client did not provide a plugin name — so an organization's own plugins can contribute both to their own -named rows and to this bucket. Use group_by[] to break usage out per +named rows and to this bucket. Use `group_by[]` to break usage out per member, per RBAC group, or per product surface (Cowork / Claude Code), -and filter[] to scope results; the parameter descriptions list the +and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Requires an API key with the `read:analytics` scope. `starting_date` / `ending_date` select -range-rollup mode like /skills. +range-rollup mode like `/skills`. #### Query parameters
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: plugin_name, product, rbac_group_id, user_id. Value forms: plugin_name matches case-insensitively; product is claude_code or cowork (the only surfaces with plugin attribution); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `plugin_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `plugin_name` matches case-insensitively; `product` is `claude_code` or `cowork` (the only surfaces with plugin attribution); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. On this endpoint product takes the values claude_code or cowork only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. On this endpoint `product` takes the values `claude_code` or `cowork` only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `plugin_id: optional string or null` - Stable plugin identifier when available (e.g. serena@claude-plugins-official). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. + Stable plugin identifier when available (e.g. `serena@claude-plugins-official`). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Get artifact-creation activity for a given day, broken out by MIME type. -Returns the full (artifact_type, is_shared) cube for the organization; +Returns the full (`artifact_type`, `is_shared`) cube for the organization; `next_page` is null except for grouped queries, which paginate. The cube -can be broken out per member or per RBAC group via group_by[], and scoped -via filter[]. Requires an API key with the `read:analytics` scope. +can be broken out per product, per member, or per RBAC group via +`group_by[]`, and scoped via `filter[]`. Requires an API key with the +`read:analytics` scope. #### Query parameters
- `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: artifact_type, is_shared, rbac_group_id, user_id. Value forms: artifact_type is a canonical artifact MIME type (e.g. text/markdown) or 'other'; is_shared is 'true' or 'false'; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `artifact_type`, `is_shared`, `product`, `rbac_group_id`, `user_id`. Value forms: `artifact_type` is a canonical artifact MIME type (e.g. `text/markdown`) or `other`; `is_shared` is `true` or `false`; `product` is `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 -- `group_by: optional array of "rbac_group_id" or "user_id"` +- `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by: user_id and/or rbac_group_id. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via next_page. rbac_group_id attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. + Dimensions to break results out by: `product`, `user_id` and/or `rbac_group_id`. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via `next_page`. `product` takes the values `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts). `rbac_group_id` attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. maxItems: 100 + - `"product"` + - `"rbac_group_id"` - `"user_id"`
- `limit: optional number` - Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; limit is the page size only when group_by[] multiplies the cube. + Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; `limit` is the page size only when `group_by[]` multiplies the cube. minimum: 1, maximum: 1000 - `page: optional string` - Opaque cursor from a previous response's next_page field. Only valid with group_by[] — the ungrouped cube is never paginated. + Opaque cursor from a previous response's `next_page` field. Only valid with `group_by[]` — the ungrouped cube is never paginated. #### Returns
Response for GET /v1/organizations/analytics/artifacts. `next_page` is null on ungrouped queries — the artifact-type cube is - finite and returned in full. Grouped queries (`group_by[]` on `user_id` / - `rbac_group_id`) multiply the cube and paginate like the other analytics - list endpoints. + finite and returned in full. Grouped queries (`group_by[]` on `product` / + `user_id` / `rbac_group_id`) multiply the cube and paginate like the other + analytics list endpoints. - `data: array of object` - `artifact_type: string` - Canonical artifact MIME type (e.g. text/markdown, application/vnd.ant.react, image/svg+xml), or 'other'. + Canonical artifact MIME type (e.g. `text/markdown`, `application/vnd.ant.react`, `image/svg+xml`), or `other`. Claude Code and Cowork artifacts report as `text/html`. - `artifacts_created_count: number`
- `is_shared: boolean` - Whether the artifacts in this bucket have ever been shared. + Whether the artifacts in this bucket have ever been shared (a Claude Code / Cowork artifact is shared once anyone beyond its creator may open it: named members, the whole organization, or anyone with the link). - `published_artifacts_created_count: number` - Number of those artifacts that have been published + Number of those artifacts that have been published (for Claude Code / Cowork artifacts: open to anyone with the link); never exceeds `artifacts_created_count` - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Tagged user identifier (e.g. `user_...`). Present only when the request grouped by `user_id`. - - `next_page: optional string or null` + - `next_page: string or null` Cursor for the next page of a grouped query; always null for the ungrouped artifact-type cube, which is returned in full.
api/admin/users/list Changed · +2 / -2 lines
**GET** `/v1/organizations/users` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's members. ## Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. ## Returns
build-with-claude/claude-in-microsoft-foundry Changed · +2 / -2 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java-foundry:2.57.0") + implementation("com.anthropic:anthropic-java-foundry:2.58.0") // For Entra ID authentication, also add the Azure Identity library implementation("com.azure:azure-identity:1.18.3")
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-foundry</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> <!-- For Entra ID authentication, also add the Azure Identity library --> <dependency>
api/admin/users/retrieve Changed · +1 / -1 lines
**GET** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve a member of the organization by user ID. ## Path parameters
build-with-claude/files Changed · +2 / -2 lines
* **Manage your files** with list, retrieve, and delete operations <Warning id="workspace-scoped-access"> - **Uploaded files are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key in the same workspace can access any file uploaded there, and all of your keys share your organization's Default Workspace unless you have assigned them to separate [workspaces](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping). Never accept `file_id` values from end users or other untrusted sources: a user-supplied file ID would let one user of your application read content that another user uploaded. Treat file IDs as server-side references, and keep the mapping between your users and their files in your application. + **Uploaded files are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key with access to a workspace can access any files uploaded to that workspace. Every service account, and every user whose organization role allows API access, can use the Default Workspace in addition to any workspace you add them to, so keep files that must stay separate in their own [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping) and access them only with keys scoped to that workspace. Never accept `file_id` values from end users or other untrusted sources: a user-supplied file ID would let one user of your application read content that another user uploaded. Treat file IDs as server-side references, and keep the mapping between your users and their files in your application. If you are building a multi-tenant application on the Files API, create a separate [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) for each tenant. The workspace is the isolation boundary for files, so a workspace per tenant gives each tenant's data hard isolation from every other tenant. Each organization can have up to 100 workspaces; contact your account team if you need more. </Warning>
### File lifecycle -* Files are scoped to the workspace of the API key that uploaded them. Any API key in the same workspace can reference them; never accept file IDs from untrusted sources (see the [workspace access warning](https://platform.claude.com/docs/en/build-with-claude/files#workspace-scoped-access)) +* Files are scoped to the workspace they were uploaded in. Any request in the same workspace can reference them; never accept file IDs from untrusted sources (see the [workspace access warning](https://platform.claude.com/docs/en/build-with-claude/files#workspace-scoped-access)) * Files cannot be modified or renamed after upload. To change a file's content, upload a new file and delete the old one * Files persist until you delete them with the `DELETE /v1/files/{file_id}` endpoint or they reach their `expires_at` * Deleted files cannot be recovered
build-with-claude/cache-diagnostics Changed · +1 / -1 lines
* **Beta:** Field names and semantics may change while this feature is in beta. * **Claude API only:** Not available on Amazon Bedrock or Google Cloud. * **Limited retention:** Fingerprints for `previous_message_id` lookup expire after a short period. Run diagnostic comparisons between closely spaced requests. -* **Same workspace:** The previous request must have been made with an API key from the same organization and workspace. To check, compare the `anthropic-workspace-id` [response header](https://platform.claude.com/docs/en/api/overview#response-headers) on the two responses. +* **Same workspace:** The previous request must have run in the same organization and workspace. To check, compare the `anthropic-workspace-id` [response header](https://platform.claude.com/docs/en/api/overview#response-headers) on the two responses. * **Comparison horizon:** For very long conversations where the only change is deep in the message list, the response may be `unavailable` rather than a precise location. * **Best-effort:** Diagnostics never blocks or fails your request. If diagnostic information is not available, the response returns `unavailable`, or `cache_miss_reason: null` when the comparison was still running.
api/admin/analytics/artifacts Changed · +27 / -24 lines
Get artifact-creation activity for a given day, broken out by MIME type. -Returns the full (artifact_type, is_shared) cube for the organization; +Returns the full (`artifact_type`, `is_shared`) cube for the organization; `next_page` is null except for grouped queries, which paginate. The cube -can be broken out per member or per RBAC group via group_by[], and scoped -via filter[]. Requires an API key with the `read:analytics` scope. +can be broken out per product, per member, or per RBAC group via +`group_by[]`, and scoped via `filter[]`. Requires an API key with the +`read:analytics` scope. ### Query parameters
- `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: artifact_type, is_shared, rbac_group_id, user_id. Value forms: artifact_type is a canonical artifact MIME type (e.g. text/markdown) or 'other'; is_shared is 'true' or 'false'; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `artifact_type`, `is_shared`, `product`, `rbac_group_id`, `user_id`. Value forms: `artifact_type` is a canonical artifact MIME type (e.g. `text/markdown`) or `other`; `is_shared` is `true` or `false`; `product` is `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 -- `group_by: optional array of "rbac_group_id" or "user_id"` +- `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by: user_id and/or rbac_group_id. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via next_page. rbac_group_id attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. + Dimensions to break results out by: `product`, `user_id` and/or `rbac_group_id`. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via `next_page`. `product` takes the values `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts). `rbac_group_id` attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. maxItems: 100 + - `"product"` + - `"rbac_group_id"` - `"user_id"`
- `limit: optional number` - Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; limit is the page size only when group_by[] multiplies the cube. + Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; `limit` is the page size only when `group_by[]` multiplies the cube. minimum: 1, maximum: 1000 - `page: optional string` - Opaque cursor from a previous response's next_page field. Only valid with group_by[] — the ungrouped cube is never paginated. + Opaque cursor from a previous response's `next_page` field. Only valid with `group_by[]` — the ungrouped cube is never paginated. ### Returns
Response for GET /v1/organizations/analytics/artifacts. `next_page` is null on ungrouped queries — the artifact-type cube is - finite and returned in full. Grouped queries (`group_by[]` on `user_id` / - `rbac_group_id`) multiply the cube and paginate like the other analytics - list endpoints. + finite and returned in full. Grouped queries (`group_by[]` on `product` / + `user_id` / `rbac_group_id`) multiply the cube and paginate like the other + analytics list endpoints. - `data: array of object` - `artifact_type: string` - Canonical artifact MIME type (e.g. text/markdown, application/vnd.ant.react, image/svg+xml), or 'other'. + Canonical artifact MIME type (e.g. `text/markdown`, `application/vnd.ant.react`, `image/svg+xml`), or `other`. Claude Code and Cowork artifacts report as `text/html`. - `artifacts_created_count: number`
- `is_shared: boolean` - Whether the artifacts in this bucket have ever been shared. + Whether the artifacts in this bucket have ever been shared (a Claude Code / Cowork artifact is shared once anyone beyond its creator may open it: named members, the whole organization, or anyone with the link). - `published_artifacts_created_count: number` - Number of those artifacts that have been published + Number of those artifacts that have been published (for Claude Code / Cowork artifacts: open to anyone with the link); never exceeds `artifacts_created_count` - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Tagged user identifier (e.g. `user_...`). Present only when the request grouped by `user_id`. - - `next_page: optional string or null` + - `next_page: string or null` Cursor for the next page of a grouped query; always null for the ungrouped artifact-type cube, which is returned in full.
Response for GET /v1/organizations/analytics/artifacts. `next_page` is null on ungrouped queries — the artifact-type cube is - finite and returned in full. Grouped queries (`group_by[]` on `user_id` / - `rbac_group_id`) multiply the cube and paginate like the other analytics - list endpoints. + finite and returned in full. Grouped queries (`group_by[]` on `product` / + `user_id` / `rbac_group_id`) multiply the cube and paginate like the other + analytics list endpoints. - `data: array of object` - `artifact_type: string` - Canonical artifact MIME type (e.g. text/markdown, application/vnd.ant.react, image/svg+xml), or 'other'. + Canonical artifact MIME type (e.g. `text/markdown`, `application/vnd.ant.react`, `image/svg+xml`), or `other`. Claude Code and Cowork artifacts report as `text/html`. - `artifacts_created_count: number`
- `is_shared: boolean` - Whether the artifacts in this bucket have ever been shared. + Whether the artifacts in this bucket have ever been shared (a Claude Code / Cowork artifact is shared once anyone beyond its creator may open it: named members, the whole organization, or anyone with the link). - `published_artifacts_created_count: number` - Number of those artifacts that have been published + Number of those artifacts that have been published (for Claude Code / Cowork artifacts: open to anyone with the link); never exceeds `artifacts_created_count` - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Tagged user identifier (e.g. `user_...`). Present only when the request grouped by `user_id`. - - `next_page: optional string or null` + - `next_page: string or null` Cursor for the next page of a grouped query; always null for the ungrouped artifact-type cube, which is returned in full.
managed-agents/self-hosted-sandboxes Changed · +2 / -2 lines
For Linux environments, download the release binary directly. ```bash - VERSION=1.26.1 + VERSION=1.27.0 OS=$(uname -s | tr '[:upper:]' '[:lower:]') case $(uname -m) in x86_64) ARCH=amd64 ;;
```text FROM your-base-image - ARG ANT_VERSION=1.26.1 + ARG ANT_VERSION=1.27.0 ARG TARGETARCH RUN ARCH=$([ "$TARGETARCH" = "arm64" ] && echo arm64 || echo amd64) && \ curl -fsSL "https://github.com/anthropics/anthropic-cli/releases/download/v${ANT_VERSION}/ant_${ANT_VERSION}_linux_${ARCH}.tar.gz" \
managed-agents/vaults Changed · +1 / -1 lines
## Create a vault <Warning> - Vaults and credentials are workspace-scoped, meaning anyone with an API key for the same workspace can reference them when creating a session. To revoke access, delete the vault or credential. + Vaults and credentials are workspace-scoped, meaning any API key with workspace access can reference them when creating a session. To revoke access, delete the vault or credential. </Warning> A vault is the collection of `credentials` associated with an end user. Give it a `display_name` and optionally tag it with `metadata` so you can map it back to your own user records.
manage-claude/user-management Changed · +2 / -0 lines
3. Remove members who should no longer be in the group with `DELETE /v1/organizations/rbac_groups/{group_id}/members/{user_id}`. For `scim` groups, make the change in your identity provider instead. +For a workflow that combines group membership with a temporary spend limit raise, see [Temporarily raise a member's spend limit during an incident](https://platform.claude.com/docs/en/manage-claude/spend-limits-api#temporarily-raise-a-members-spend-limit-during-an-incident) on the Spend Limits API page. + ## Frequently asked questions ### Is this a different API from the Admin API?
managed-agents/quickstart Changed · +2 / -2 lines
For Linux environments, download the release binary directly. ```bash - VERSION=1.26.1 + VERSION=1.27.0 OS=$(uname -s | tr '[:upper:]' '[:lower:]') case $(uname -m) in x86_64) ARCH=amd64 ;;
<Tab title="Java"> ```groovy Gradle - implementation("com.anthropic:anthropic-java:2.57.0") + implementation("com.anthropic:anthropic-java:2.58.0") ``` </Tab>
cli-sdks-libraries/libraries/openai-sdk Changed · +1 / -0 lines
* Update your base URL to point to the Claude API * Replace your API key with a [Claude API key](https://platform.claude.com/settings/keys) + * If your key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, also send the `anthropic-workspace-id` header on every request (for example, `default_headers` in the Python SDK or `defaultHeaders` in TypeScript); see [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) * Update your model name to use a [Claude model](https://platform.claude.com/docs/en/models/overview) 3. Review the following sections for what features are supported
manage-claude/rate-limits-api Changed · +1 / -1 lines
* **Audit workspace configuration:** Verify that workspace overrides match what your provisioning automation expects. <Check> - **Admin API key required.** These endpoints require an Admin API key, which is different from a standard Claude API key. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) to find where to create one for your organization type and which scopes to select. + **Admin API credentials required.** These endpoints are part of the Admin API. You can access them using an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an OAuth token with the `org:admin` scope, or a personal or service account key that isn't scoped to a workspace; workspace API keys don't work. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication) for details. </Check> The SDK and CLI examples on this page construct the default client, which reads the Admin API key from the `ANTHROPIC_API_KEY` environment variable. The SDKs expose these endpoints as `client.beta.organization.rate_limits` and `client.beta.organization.workspaces.rate_limits`; the Python, TypeScript, C#, Go, and Java list methods return an iterator that follows `next_page` for you, while the PHP, Ruby, and curl examples read one page.
cli-sdks-libraries/sdks/typescript Changed · +1 / -1 lines
} ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ## Request and response types
api/admin/analytics/artifacts/list Changed · +19 / -16 lines
Get artifact-creation activity for a given day, broken out by MIME type. -Returns the full (artifact_type, is_shared) cube for the organization; +Returns the full (`artifact_type`, `is_shared`) cube for the organization; `next_page` is null except for grouped queries, which paginate. The cube -can be broken out per member or per RBAC group via group_by[], and scoped -via filter[]. Requires an API key with the `read:analytics` scope. +can be broken out per product, per member, or per RBAC group via +`group_by[]`, and scoped via `filter[]`. Requires an API key with the +`read:analytics` scope. ## Query parameters
- `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: artifact_type, is_shared, rbac_group_id, user_id. Value forms: artifact_type is a canonical artifact MIME type (e.g. text/markdown) or 'other'; is_shared is 'true' or 'false'; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `artifact_type`, `is_shared`, `product`, `rbac_group_id`, `user_id`. Value forms: `artifact_type` is a canonical artifact MIME type (e.g. `text/markdown`) or `other`; `is_shared` is `true` or `false`; `product` is `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 -- `group_by: optional array of "rbac_group_id" or "user_id"` +- `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by: user_id and/or rbac_group_id. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via next_page. rbac_group_id attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. + Dimensions to break results out by: `product`, `user_id` and/or `rbac_group_id`. The ungrouped artifact-type cube is finite and returned in full; grouped queries multiply the cube and paginate via `next_page`. `product` takes the values `chat`, `claude_code`, or `cowork` (the surfaces that create artifacts). `rbac_group_id` attributes a user to every group they held at any point during the requested UTC day, so grouped rows are not an exclusive partition. At most 100 entries. maxItems: 100 + - `"product"` + - `"rbac_group_id"` - `"user_id"`
- `limit: optional number` - Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; limit is the page size only when group_by[] multiplies the cube. + Maximum rows to return (1-1000, default 100). The ungrouped artifact-type cube is finite and returned in full; `limit` is the page size only when `group_by[]` multiplies the cube. minimum: 1, maximum: 1000 - `page: optional string` - Opaque cursor from a previous response's next_page field. Only valid with group_by[] — the ungrouped cube is never paginated. + Opaque cursor from a previous response's `next_page` field. Only valid with `group_by[]` — the ungrouped cube is never paginated. ## Returns
Response for GET /v1/organizations/analytics/artifacts. `next_page` is null on ungrouped queries — the artifact-type cube is - finite and returned in full. Grouped queries (`group_by[]` on `user_id` / - `rbac_group_id`) multiply the cube and paginate like the other analytics - list endpoints. + finite and returned in full. Grouped queries (`group_by[]` on `product` / + `user_id` / `rbac_group_id`) multiply the cube and paginate like the other + analytics list endpoints. - `data: array of object` - `artifact_type: string` - Canonical artifact MIME type (e.g. text/markdown, application/vnd.ant.react, image/svg+xml), or 'other'. + Canonical artifact MIME type (e.g. `text/markdown`, `application/vnd.ant.react`, `image/svg+xml`), or `other`. Claude Code and Cowork artifacts report as `text/html`. - `artifacts_created_count: number`
- `is_shared: boolean` - Whether the artifacts in this bucket have ever been shared. + Whether the artifacts in this bucket have ever been shared (a Claude Code / Cowork artifact is shared once anyone beyond its creator may open it: named members, the whole organization, or anyone with the link). - `published_artifacts_created_count: number` - Number of those artifacts that have been published + Number of those artifacts that have been published (for Claude Code / Cowork artifacts: open to anyone with the link); never exceeds `artifacts_created_count` - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Tagged user identifier (e.g. `user_...`). Present only when the request grouped by `user_id`. - - `next_page: optional string or null` + - `next_page: string or null` Cursor for the next page of a grouped query; always null for the ungrouped artifact-type cube, which is returned in full.
cli-sdks-libraries/sdks/python Changed · +1 / -1 lines
Consider using [python-dotenv](https://pypi.org/project/python-dotenv/) to add `ANTHROPIC_API_KEY="my-anthropic-api-key"` to your `.env` file so that your API key isn't stored in source control. </Tip> -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ## Async usage
cli-sdks-libraries/sdks/ruby Changed · +1 / -1 lines
end ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ## Streaming
cli-sdks-libraries/sdks/php Changed · +1 / -1 lines
echo $textBlock->text; ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ## Value objects
cli-sdks-libraries/sdks/go Changed · +1 / -1 lines
} ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. <AccordionGroup> <Accordion title="Conversations">
cli-sdks-libraries/sdks/csharp Changed · +1 / -1 lines
} ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ## Client configuration
api/admin/analytics/chat_projects/list Changed · +16 / -14 lines
Get per-project activity for a given day, with cursor-based pagination. Returns activity metrics for each project in the organization, sorted by -project ID. Use group_by[] to break projects out per member or per RBAC -group, and filter[] to scope results; the parameter descriptions list the +project ID. Use `group_by[]` to break projects out per member or per RBAC +group, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `project_id: string` - Tagged project identifier (e.g. claude_proj_...) + Tagged project identifier (e.g. `claude_proj_...`) - `project_name: string`
- `created_at: optional string or null` - Project creation timestamp, RFC 3339. Null if the project was deleted before attribution was recorded. + Project creation timestamp in RFC 3339 format. Null if the project was deleted before attribution was recorded. + format: date-time + - `created_by: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
"message_count": 0, "project_id": "project_id", "project_name": "project_name", - "created_at": "created_at", + "created_at": "2019-12-27T18:11:19.117Z", "created_by": { "id": "id", "email_address": "email_address",
get-started Changed · +2 / -2 lines
} dependencies { - implementation("com.anthropic:anthropic-java:2.57.0") + implementation("com.anthropic:anthropic-java:2.58.0") } application {
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> </dependencies> </project>
api/admin/analytics/connectors Changed · +24 / -24 lines
Returns connector usage metrics for the organization, sorted by connector name. Connector names are normalized from their various sources — for example, "Atlassian MCP server" and "mcp-atlassian" both appear as -"atlassian". Use group_by[] to break usage out per member, per RBAC -group, or per product surface, and filter[] to scope results; the +"atlassian". Use `group_by[]` to break usage out per member, per RBAC +group, or per product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: connector_name, product, rbac_group_id, user_id. Value forms: connector_name matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose connector_name is an opaque connector id the connector's display name (connector_display_name) also matches; product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `connector_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `connector_name` matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose `connector_name` is an opaque connector id the connector's display name (`connector_display_name`) also matches; `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `connector_name: string` - Name of the connector. Some rows carry an opaque connector id here instead of a readable name; connector_display_name holds the resolved name for those rows. + Name of the connector. Some rows carry an opaque connector id here instead of a readable name; `connector_display_name` holds the resolved name for those rows. - `cowork_metrics: object`
- `connector_display_name: optional string or null` - Human-readable display name for rows whose connector_name is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). connector_name remains the row's stable key for sorting and pagination, and filter[]=connector_name:<value> also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable connector_name. Null when connector_name is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `connector_name` is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). `connector_name` remains the row's stable key for sorting and pagination, and `filter[]=connector_name:{value}` also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable `connector_name`. Null when `connector_name` is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. - `individual_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to managed_auth_distinct_user_count, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. + Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to `managed_auth_distinct_user_count`, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. - `managed_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on user_id and rbac_group_id cuts — attributed to the user the credential was provisioned for — but never on a cut that references product (group or filter). Date-range rollup mode (starting_date/ending_date) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. + Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on `user_id` and `rbac_group_id` cuts — attributed to the user the credential was provisioned for — but never on a cut that references `product` (group or filter). Date-range rollup mode (`starting_date`/`ending_date`) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `read_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of read_call_count, write_call_count, or unclassified_call_count, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in unclassified_call_count). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (starting_date/ending_date) applies both rules server-side. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of `read_call_count`, `write_call_count`, or `unclassified_call_count`, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in `unclassified_call_count`). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (`starting_date`/`ending_date`) applies both rules server-side. - `unclassified_call_count: optional number or null` - Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `user_id: optional string or null`
- `write_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `next_page: string or null`
- `connector_name: string` - Name of the connector. Some rows carry an opaque connector id here instead of a readable name; connector_display_name holds the resolved name for those rows. + Name of the connector. Some rows carry an opaque connector id here instead of a readable name; `connector_display_name` holds the resolved name for those rows. - `cowork_metrics: object`
- `connector_display_name: optional string or null` - Human-readable display name for rows whose connector_name is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). connector_name remains the row's stable key for sorting and pagination, and filter[]=connector_name:<value> also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable connector_name. Null when connector_name is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `connector_name` is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). `connector_name` remains the row's stable key for sorting and pagination, and `filter[]=connector_name:{value}` also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable `connector_name`. Null when `connector_name` is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. - `individual_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to managed_auth_distinct_user_count, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. + Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to `managed_auth_distinct_user_count`, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. - `managed_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on user_id and rbac_group_id cuts — attributed to the user the credential was provisioned for — but never on a cut that references product (group or filter). Date-range rollup mode (starting_date/ending_date) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. + Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on `user_id` and `rbac_group_id` cuts — attributed to the user the credential was provisioned for — but never on a cut that references `product` (group or filter). Date-range rollup mode (`starting_date`/`ending_date`) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `read_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of read_call_count, write_call_count, or unclassified_call_count, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in unclassified_call_count). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (starting_date/ending_date) applies both rules server-side. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of `read_call_count`, `write_call_count`, or `unclassified_call_count`, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in `unclassified_call_count`). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (`starting_date`/`ending_date`) applies both rules server-side. - `unclassified_call_count: optional number or null` - Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `user_id: optional string or null`
- `write_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `next_page: string or null`
manage-claude/claude-code-analytics-api Changed · +1 / -1 lines
* **Usage justification:** Provide metrics to justify and expand Claude Code adoption internally <Check> - **Admin API key required.** These endpoints require an Admin API key, which is different from a standard Claude API key. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) to find where to create one for your organization type and which scopes to select. + **Admin API credentials required.** These endpoints are part of the Admin API. You can access them using an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an OAuth token with the `org:admin` scope, or a personal or service account key that isn't scoped to a workspace; workspace API keys don't work. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication) for details. </Check> <Note>
build-with-claude/claude-on-amazon-bedrock-legacy Changed · +2 / -2 lines
<Tab title="Java"> <CodeGroup> ```groovy Gradle - implementation("com.anthropic:anthropic-java-bedrock:2.57.0") + implementation("com.anthropic:anthropic-java-bedrock:2.58.0") ``` ```xml Maven
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-bedrock</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ```
api/admin/analytics/chat_projects Changed · +23 / -19 lines
Get per-project activity for a given day, with cursor-based pagination. Returns activity metrics for each project in the organization, sorted by -project ID. Use group_by[] to break projects out per member or per RBAC -group, and filter[] to scope results; the parameter descriptions list the +project ID. Use `group_by[]` to break projects out per member or per RBAC +group, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `project_id: string` - Tagged project identifier (e.g. claude_proj_...) + Tagged project identifier (e.g. `claude_proj_...`) - `project_name: string`
- `created_at: optional string or null` - Project creation timestamp, RFC 3339. Null if the project was deleted before attribution was recorded. + Project creation timestamp in RFC 3339 format. Null if the project was deleted before attribution was recorded. + format: date-time + - `created_by: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
"message_count": 0, "project_id": "project_id", "project_name": "project_name", - "created_at": "created_at", + "created_at": "2019-12-27T18:11:19.117Z", "created_by": { "id": "id", "email_address": "email_address",
- `project_id: string` - Tagged project identifier (e.g. claude_proj_...) + Tagged project identifier (e.g. `claude_proj_...`) - `project_name: string`
- `created_at: optional string or null` - Project creation timestamp, RFC 3339. Null if the project was deleted before attribution was recorded. + Project creation timestamp in RFC 3339 format. Null if the project was deleted before attribution was recorded. + format: date-time + - `created_by: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
- `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
api/admin/analytics/connectors/list Changed · +16 / -16 lines
Returns connector usage metrics for the organization, sorted by connector name. Connector names are normalized from their various sources — for example, "Atlassian MCP server" and "mcp-atlassian" both appear as -"atlassian". Use group_by[] to break usage out per member, per RBAC -group, or per product surface, and filter[] to scope results; the +"atlassian". Use `group_by[]` to break usage out per member, per RBAC +group, or per product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: connector_name, product, rbac_group_id, user_id. Value forms: connector_name matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose connector_name is an opaque connector id the connector's display name (connector_display_name) also matches; product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `connector_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `connector_name` matches case-insensitively, a display name such as 'GitHub MCP' also matches its normalized stored form ('github'), and for rows whose `connector_name` is an opaque connector id the connector's display name (`connector_display_name`) also matches; `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `connector_name: string` - Name of the connector. Some rows carry an opaque connector id here instead of a readable name; connector_display_name holds the resolved name for those rows. + Name of the connector. Some rows carry an opaque connector id here instead of a readable name; `connector_display_name` holds the resolved name for those rows. - `cowork_metrics: object`
- `connector_display_name: optional string or null` - Human-readable display name for rows whose connector_name is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). connector_name remains the row's stable key for sorting and pagination, and filter[]=connector_name:<value> also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable connector_name. Null when connector_name is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `connector_name` is an opaque connector id rather than a readable name, resolved at request time from the organization's connectors (including connectors that have since been removed). `connector_name` remains the row's stable key for sorting and pagination, and `filter[]=connector_name:{value}` also matches these rows by display name. Display names are not unique, and the same connector's claude.ai usage can appear under a separate row with a readable `connector_name`. Null when `connector_name` is already a readable name, when the id cannot be resolved to one of the organization's connectors, or when display-name resolution is not enabled for this organization. - `individual_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to managed_auth_distinct_user_count, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. + Number of distinct users whose use of this connector on the requested day ran on their own individual credential, connected through their own consent flow. Companion bucket to `managed_auth_distinct_user_count`, which carries the measurement, attribution, and null rules. Users whose requests used no stored credential count in neither bucket. - `managed_auth_distinct_user_count: optional number or null` - Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on user_id and rbac_group_id cuts — attributed to the user the credential was provisioned for — but never on a cut that references product (group or filter). Date-range rollup mode (starting_date/ending_date) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. + Number of distinct users whose use of this connector on the requested day ran on Enterprise Managed Auth (an organization-managed credential provisioned through the organization's identity provider), read from the token record each request used. Null, never 0, when managed-auth reporting is not enabled for the organization, the value cannot be attributed to the row, no credentialed requests and no managed-token mint events (a managed credential being provisioned for a user's use of the connector) were observed that day, or the day predates 2026-07-01, the first day the backing data exists (forward-only data, no backfill). When credentialed requests or mint events were observed and attributed, both managed-auth fields populate, reporting 0 for a bucket with no users; the two counts are independent, not a partition — a user whose requests that day used both kinds of credential counts in both. Mint events carry user but not surface attribution, so they count as observed auth activity on `user_id` and `rbac_group_id` cuts — attributed to the user the credential was provisioned for — but never on a cut that references `product` (group or filter). Date-range rollup mode (`starting_date`/`ending_date`) computes both fields exactly over the window — distinct users with at least one qualifying day — when the whole window starts on or after 2026-07-01, with the null-versus-0 and mint-event rules applying with the window in place of the day; a range starting earlier reports every managed-auth field as null, never a partial-window value. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `read_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of read_call_count, write_call_count, or unclassified_call_count, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in unclassified_call_count). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (starting_date/ending_date) applies both rules server-side. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them read-only. Call count, not distinct users. Every call recorded on a classified surface lands in exactly one of `read_call_count`, `write_call_count`, or `unclassified_call_count`, so the three sum to the day's classified calls. Classification is forward-only per surface: claude.ai from 2026-06-01, Claude Code from 2026-05-30, Claude in Office from 2026-05-29, Cowork from 2026-06-02 (Cowork clients predating annotation forwarding land in `unclassified_call_count`). Null, never 0, when the value cannot be stated: the read/write split is not enabled for this organization, or the day predates 2026-05-29. For a date-range total, sum the per-day values, but treat a window that extends before 2026-05-29 as null rather than summing only its covered days — date-range rollup mode (`starting_date`/`ending_date`) applies both rules server-side. - `unclassified_call_count: optional number or null` - Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day with no trusted read-only annotation — the annotation is optional in the MCP spec and is discarded when connector access controls are active, so unclassified calls are common. This field shows how much of the day's classified activity the read/write split actually covers. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `user_id: optional string or null`
- `write_call_count: optional number or null` - Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see read_call_count for the per-surface data-start dates, null conditions, and date-range guidance. + Number of connector tool calls on the requested day whose trusted read-only annotation marked them not read-only. Call count, not distinct users. One of the three call-classification buckets; see `read_call_count` for the per-surface data-start dates, null conditions, and date-range guidance. - `next_page: string or null`
build-with-claude/skills-guide Changed · +1 / -1 lines
## Managing custom Skills <Warning id="workspace-scoped-access"> - **Custom Skills are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key in the same workspace can read, invoke, and delete every custom Skill uploaded there, and all of your keys share your organization's Default Workspace unless you have assigned them to separate [workspaces](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping). + **Custom Skills are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key with access to a workspace can read, invoke, and delete every custom Skill uploaded to that workspace. Every service account, and every user whose organization role allows API access, can use the Default Workspace in addition to any workspace you add them to, so keep Skills that must stay separate in their own [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping) and access them only with keys scoped to that workspace. If you are building a multi-tenant platform on the Skills API, create a separate [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) for each tenant. The workspace is the isolation boundary for custom Skills, so a workspace per tenant gives each tenant's Skills hard isolation from every other tenant. Each organization can have up to 100 workspaces by default (see [How workspaces work](https://platform.claude.com/docs/en/manage-claude/workspaces#how-workspaces-work)); if you need more for tenant isolation, contact your account team. </Warning>
api/admin/analytics/cost Changed · +59 / -31 lines
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"currency": "USD", "inference_geo": "global", "list_amount": "list_amount", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 0,
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `token_type: "cache_creation.ephemeral_1h_input_tokens" or "cache_creation.ephemeral_5m_input_tokens" or "cache_read_input_tokens" or 2 more or null` - Token type when cost_type=tokens; null otherwise. + Token type when `cost_type` is `tokens`; null otherwise. - `"cache_creation.ephemeral_1h_input_tokens"`
"ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", "list_amount": "51600.000000", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 128,
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `token_type: "cache_creation.ephemeral_1h_input_tokens" or "cache_creation.ephemeral_5m_input_tokens" or "cache_read_input_tokens" or 2 more or null` - Token type when cost_type=tokens; null otherwise. + Token type when `cost_type` is `tokens`; null otherwise. - `"cache_creation.ephemeral_1h_input_tokens"`
api/admin/analytics/cost/list Changed · +24 / -10 lines
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"currency": "USD", "inference_geo": "global", "list_amount": "list_amount", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 0,
api/admin/analytics/cost/list_by_user Changed · +26 / -12 lines
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `token_type: "cache_creation.ephemeral_1h_input_tokens" or "cache_creation.ephemeral_5m_input_tokens" or "cache_read_input_tokens" or 2 more or null` - Token type when cost_type=tokens; null otherwise. + Token type when `cost_type` is `tokens`; null otherwise. - `"cache_creation.ephemeral_1h_input_tokens"`
"ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", "list_amount": "51600.000000", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF", "requests": 128,
api/admin/analytics/plugins Changed · +13 / -13 lines
an aggregate bucket, not a plugin: it collects plugin activity, from either surface, for which the reporting client did not provide a plugin name — so an organization's own plugins can contribute both to their own -named rows and to this bucket. Use group_by[] to break usage out per +named rows and to this bucket. Use `group_by[]` to break usage out per member, per RBAC group, or per product surface (Cowork / Claude Code), -and filter[] to scope results; the parameter descriptions list the +and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Requires an API key with the `read:analytics` scope. `starting_date` / `ending_date` select -range-rollup mode like /skills. +range-rollup mode like `/skills`. ### Query parameters
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: plugin_name, product, rbac_group_id, user_id. Value forms: plugin_name matches case-insensitively; product is claude_code or cowork (the only surfaces with plugin attribution); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `plugin_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `plugin_name` matches case-insensitively; `product` is `claude_code` or `cowork` (the only surfaces with plugin attribution); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. On this endpoint product takes the values claude_code or cowork only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. On this endpoint `product` takes the values `claude_code` or `cowork` only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `plugin_id: optional string or null` - Stable plugin identifier when available (e.g. serena@claude-plugins-official). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. + Stable plugin identifier when available (e.g. `serena@claude-plugins-official`). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
- `plugin_id: optional string or null` - Stable plugin identifier when available (e.g. serena@claude-plugins-official). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. + Stable plugin identifier when available (e.g. `serena@claude-plugins-official`). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
api/admin/analytics/plugins/list Changed · +11 / -11 lines
an aggregate bucket, not a plugin: it collects plugin activity, from either surface, for which the reporting client did not provide a plugin name — so an organization's own plugins can contribute both to their own -named rows and to this bucket. Use group_by[] to break usage out per +named rows and to this bucket. Use `group_by[]` to break usage out per member, per RBAC group, or per product surface (Cowork / Claude Code), -and filter[] to scope results; the parameter descriptions list the +and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Requires an API key with the `read:analytics` scope. `starting_date` / `ending_date` select -range-rollup mode like /skills. +range-rollup mode like `/skills`. ## Query parameters
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: plugin_name, product, rbac_group_id, user_id. Value forms: plugin_name matches case-insensitively; product is claude_code or cowork (the only surfaces with plugin attribution); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `plugin_name`, `product`, `rbac_group_id`, `user_id`. Value forms: `plugin_name` matches case-insensitively; `product` is `claude_code` or `cowork` (the only surfaces with plugin attribution); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. On this endpoint product takes the values claude_code or cowork only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. On this endpoint `product` takes the values `claude_code` or `cowork` only (the surfaces with plugin attribution). Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `plugin_id: optional string or null` - Stable plugin identifier when available (e.g. serena@claude-plugins-official). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. + Stable plugin identifier when available (e.g. `serena@claude-plugins-official`). Null for third-party Claude Code plugins (redacted at the source) and Cowork slash commands that carry only a hashed id. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
cli-sdks-libraries/cli/quickstart Changed · +1 / -1 lines
For Linux environments, download the release binary directly. ```bash - VERSION=1.26.1 + VERSION=1.27.0 OS=$(uname -s | tr '[:upper:]' '[:lower:]') case $(uname -m) in x86_64) ARCH=amd64 ;;
api/admin/analytics/retrieve_summaries Changed · +17 / -12 lines
Get organization-wide activity summaries for a date range. -Returns one entry per day in [starting_date, ending_date). Data is -typically available with a 1-day lag and may be revised by a few percent -over the following days: when ending_date is omitted it defaults to the -most recent available day + 1, so the last entry covers the most recent -available day. The series can be scoped to an RBAC group via -filter[]=rbac_group_id:<id>. Available to organizations on a Claude -Enterprise plan. Requires an API key with the `read:analytics` scope. +Returns one entry per day from `starting_date` (inclusive) to `ending_date` +(exclusive). Data is typically available with a 1-day lag and may be +revised by a few percent over the following days: when `ending_date` is +omitted it defaults to the most recent available day + 1, so the last +entry covers the most recent available day. The series can be scoped to +an RBAC group via `filter[]=rbac_group_id:{id}`. Available to +organizations on a Claude Enterprise plan. Requires an API key with the +`read:analytics` scope. ## Query parameters
- `filter: optional array of string` - Filters as 'dimension:value'. Only rbac_group_id is supported (e.g. filter[]=rbac_group_id:<id>); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. rbac_group_id accepts the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. + Filters as `dimension:value`. Only `rbac_group_id` is supported (e.g. `filter[]=rbac_group_id:{id}`); repeat the param to OR across groups. Scopes the whole day series to members of the matching group(s), re-aggregated from member-level activity — org-wide seat/invite fields and the adoption rates derived from them are null on scoped rows. `rbac_group_id` accepts the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each UTC day (time-of-usage attribution). At most 100 entries. maxItems: 100
- `ending_at: string` - End time in UTC of aggregation period (e.g. 2026-01-16T00:00:00Z) + End of the aggregation period (exclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-16T00:00:00Z`). + format: date-time + - `monthly_active_user_count: number` Number of users with token consumption in the 30-day rolling window
- `starting_at: string` - Start time in UTC of aggregation period (e.g. 2026-01-15T00:00:00Z) + Start of the aggregation period (inclusive), UTC midnight in RFC 3339 format (e.g. `2026-01-15T00:00:00Z`). + format: date-time + - `weekly_active_user_count: number` Number of users with token consumption in the 7-day rolling window
"cowork_weekly_active_user_count": 0, "daily_active_user_count": 0, "daily_adoption_rate": 0, - "ending_at": "ending_at", + "ending_at": "2019-12-27T18:11:19.117Z", "monthly_active_user_count": 0, "monthly_adoption_rate": 0, "pending_invite_count": 0, - "starting_at": "starting_at", + "starting_at": "2019-12-27T18:11:19.117Z", "weekly_active_user_count": 0, "weekly_adoption_rate": 0, "chat_daily_active_user_count": 0,
api/admin/analytics/skills Changed · +41 / -29 lines
Get per-skill usage for a given day, with cursor-based pagination. Returns skill usage metrics for the organization, sorted by skill name. -Use group_by[] to break usage out per member, per RBAC group, or per -product surface, and filter[] to scope results; the parameter +Use `group_by[]` to break usage out per member, per RBAC group, or per +product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: product, rbac_group_id, share_status, skill_name, user_id. Value forms: product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); share_status is one of organization, private, or public; skill_name matches case-insensitively; user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `product`, `rbac_group_id`, `share_status`, `skill_name`, `user_id`. Value forms: `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `share_status` is one of `organization`, `private`, or `public`; `skill_name` matches case-insensitively; `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `attributed_list_price: optional string or null` - List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that INVOLVED the skill, not the skill's incremental cost. Unlike estimated_overage_spend this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does NOT tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on chat product rows and on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as estimated_overage_spend (spend reporting not enabled for this organization, office_agent product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that involved the skill, not the skill's incremental cost. Unlike `estimated_overage_spend` this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does not tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on `chat` product rows and on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as `estimated_overage_spend` (spend reporting not enabled for this organization, `office_agent` product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `currency: optional "USD" or null` - Currency for this row's monetary fields (estimated_overage_spend and attributed_list_price), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. + Currency for this row's monetary fields (`estimated_overage_spend` and `attributed_list_price`), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. - `enable_count: optional number or null` - Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin install_count). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (starting_date/ending_date). + Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin `install_count`). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (`starting_date`/`ending_date`). - `estimated_overage_spend: optional string or null` - Estimated OVERAGE spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see attributed_list_price for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that INVOLVED the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (starting_date/ending_date) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + Estimated overage spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see `attributed_list_price` for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that involved the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (`starting_date`/`ending_date`) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `invocation_count: optional number or null` - Total number of times this skill was invoked on the requested day (the skill analog of plugin invocation_count). Unlike distinct_user_count — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (starting_date/ending_date) returns this sum directly. + Total number of times this skill was invoked on the requested day (the skill analog of plugin `invocation_count`). Unlike `distinct_user_count` — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (`starting_date`/`ending_date`) returns this sum directly. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Resolved RBAC group display name, alongside `rbac_group_id` when name resolution is available. Null if the group has been deleted or its name could not be resolved; `rbac_group_id` remains the stable key. - - `share_status: optional string or null` + - `share_status: optional "organization" or "private" or "public" or null` - Skill share status (claude.ai only): one of 'private', 'organization', or 'public'. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:<value>`. + Skill share status (claude.ai only): one of `private`, `organization`, or `public`. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:{value}`. + - `"organization"` + + - `"private"` + + - `"public"` + - `skill_display_name: optional string or null` - Human-readable display name for rows whose skill_name is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when skill_name is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `skill_name` is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when `skill_name` is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. - `user_id: optional string or null`
"product": "product", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", - "share_status": "share_status", + "share_status": "organization", "skill_display_name": "skill_display_name", "user_id": "user_id" }
- `attributed_list_price: optional string or null` - List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that INVOLVED the skill, not the skill's incremental cost. Unlike estimated_overage_spend this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does NOT tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on chat product rows and on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as estimated_overage_spend (spend reporting not enabled for this organization, office_agent product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that involved the skill, not the skill's incremental cost. Unlike `estimated_overage_spend` this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does not tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on `chat` product rows and on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as `estimated_overage_spend` (spend reporting not enabled for this organization, `office_agent` product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `currency: optional "USD" or null` - Currency for this row's monetary fields (estimated_overage_spend and attributed_list_price), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. + Currency for this row's monetary fields (`estimated_overage_spend` and `attributed_list_price`), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. - `enable_count: optional number or null` - Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin install_count). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (starting_date/ending_date). + Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin `install_count`). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (`starting_date`/`ending_date`). - `estimated_overage_spend: optional string or null` - Estimated OVERAGE spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see attributed_list_price for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that INVOLVED the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (starting_date/ending_date) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + Estimated overage spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see `attributed_list_price` for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that involved the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (`starting_date`/`ending_date`) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `invocation_count: optional number or null` - Total number of times this skill was invoked on the requested day (the skill analog of plugin invocation_count). Unlike distinct_user_count — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (starting_date/ending_date) returns this sum directly. + Total number of times this skill was invoked on the requested day (the skill analog of plugin `invocation_count`). Unlike `distinct_user_count` — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (`starting_date`/`ending_date`) returns this sum directly. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Resolved RBAC group display name, alongside `rbac_group_id` when name resolution is available. Null if the group has been deleted or its name could not be resolved; `rbac_group_id` remains the stable key. - - `share_status: optional string or null` + - `share_status: optional "organization" or "private" or "public" or null` - Skill share status (claude.ai only): one of 'private', 'organization', or 'public'. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:<value>`. + Skill share status (claude.ai only): one of `private`, `organization`, or `public`. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:{value}`. + - `"organization"` + + - `"private"` + + - `"public"` + - `skill_display_name: optional string or null` - Human-readable display name for rows whose skill_name is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when skill_name is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `skill_name` is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when `skill_name` is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. - `user_id: optional string or null`
api/admin/analytics/skills/list Changed · +25 / -19 lines
Get per-skill usage for a given day, with cursor-based pagination. Returns skill usage metrics for the organization, sorted by skill name. -Use group_by[] to break usage out per member, per RBAC group, or per -product surface, and filter[] to scope results; the parameter +Use `group_by[]` to break usage out per member, per RBAC group, or per +product surface, and `filter[]` to scope results; the parameter descriptions list the supported dimensions. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: product, rbac_group_id, share_status, skill_name, user_id. Value forms: product is one of chat, claude_code, cowork, or office_agent; rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); share_status is one of organization, private, or public; skill_name matches case-insensitively; user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `product`, `rbac_group_id`, `share_status`, `skill_name`, `user_id`. Value forms: `product` is one of `chat`, `claude_code`, `cowork`, or `office_agent`; `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `share_status` is one of `organization`, `private`, or `public`; `skill_name` matches case-insensitively; `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "product" or "rbac_group_id" or "user_id"` - Dimensions to break results out by (e.g. group_by[]=user_id). Supported on this endpoint: product, rbac_group_id, user_id. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=user_id`). Supported on this endpoint: `product`, `rbac_group_id`, `user_id`. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
- `attributed_list_price: optional string or null` - List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that INVOLVED the skill, not the skill's incremental cost. Unlike estimated_overage_spend this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does NOT tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on chat product rows and on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as estimated_overage_spend (spend reporting not enabled for this organization, office_agent product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + List-price (rate-card) value of the member requests attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD), from Claude Code, Cowork, and Office Agent request-level attribution — the value of requests that involved the skill, not the skill's incremental cost. Unlike `estimated_overage_spend` this reflects usage value regardless of how it was funded — seat-covered usage counts — but it is undiscounted and does not tie to billed spend or the organization's spend reporting. claude.ai chat usage carries no request-level attribution and contributes nothing: the field is null on `chat` product rows and on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start), and on ungrouped rows it covers the Claude Code + Cowork + Office Agent share only (null when no attributable usage exists). Also null under the same conditions as `estimated_overage_spend` (spend reporting not enabled for this organization, `office_agent` product cuts before the 2026-06-18 data-start). "0" means attributable usage existed but none was attributed to this skill. Addable across days: date-range rollup mode returns the window's sum. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `currency: optional "USD" or null` - Currency for this row's monetary fields (estimated_overage_spend and attributed_list_price), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. + Currency for this row's monetary fields (`estimated_overage_spend` and `attributed_list_price`), as an uppercase ISO-4217 code. Always "USD" when either amount is populated; null whenever both amounts are null. - `enable_count: optional number or null` - Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin install_count). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (starting_date/ending_date). + Distinct accounts that enabled this skill on the requested day (claude.ai only — the skill analog of plugin `install_count`). The count is org-wide: null when enable reporting is not enabled for this organization, or when the request scopes to `user_id` / `rbac_group_id` / `product` via `group_by[]` or `filter[]` (an org-wide count would be misleading on per-cut rows). A distinct count, not an event count: summing across days double-counts members who enable the skill on more than one day, so it is also null in date-range rollup mode (`starting_date`/`ending_date`). - `estimated_overage_spend: optional string or null` - Estimated OVERAGE spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see attributed_list_price for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that INVOLVED the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on office_agent product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (starting_date/ending_date) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. + Estimated overage spend attributed to this skill, as a decimal string in the minor unit of `currency` (cents for USD; "1250" is $12.50, fractional cents possible) — an allocation of each member's daily post-discount, pre-credit metered overage spend (the same cost basis as the organization's spend reporting and the Cost & Usage API, so per-skill figures are directly comparable; spend with no skill attribution — including any member-day without skill invocations — is not represented, so skill rows sum to at most those totals) across the skills the member used. Overage only: usage covered by included seat allowances bills nothing and allocates $0 here — see `attributed_list_price` for the funding-independent usage-value companion. Claude Code, Cowork, and Office Agent spend use request-level skill attribution; claude.ai chat spend is approximated proportionally to skill-invoking messages. An estimate, not a billing number — and the cost of the requests/messages that involved the skill, not the skill's incremental cost (the same request would still have cost something without the skill active). "0" means no overage spend was attributed; null when spend reporting is not enabled for this organization, on `office_agent` product cuts dated before 2026-06-18 (the Office Agent attribution data-start). Addable across days: date-range rollup mode (`starting_date`/`ending_date`) returns the window's sum. With `group_by[]=user_id` each row carries the user's own attributed spend. On `group_by[]` and `filter[]` shapes both amounts can total below the ungrouped value for the same skill over the same date or range: spend attributed to a member–skill pair with no counted usage on that day is excluded from those cuts. - `invocation_count: optional number or null` - Total number of times this skill was invoked on the requested day (the skill analog of plugin invocation_count). Unlike distinct_user_count — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (starting_date/ending_date) returns this sum directly. + Total number of times this skill was invoked on the requested day (the skill analog of plugin `invocation_count`). Unlike `distinct_user_count` — which answers '\# of users' — this is the true '# of uses'. A skill counts as used only when it is explicitly activated — the model (or the user, via the skill's slash command) invokes it, reading its instructions into context as part of that activation. Skills that are merely installed or listed as available, or whose content reaches the context without an activation (preloaded, hook-injected, or read as a plain file), are not counted. Null when invocation reporting is not enabled for this organization. Sum across a date range for total uses in the window — date-range rollup mode (`starting_date`/`ending_date`) returns this sum directly. - `product: optional string or null` - Product that produced this row's activity: one of chat, claude_code, cowork, or office_agent (the canonical Cost & Usage product naming; an office_agent row's per-surface breakdown is in its office_metrics). On /plugins only cowork and claude_code occur (the only surfaces with plugin attribution); /artifacts and /apps/chat/projects do not support the product dimension (a product `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by product. + Product that produced this row's activity: one of `chat`, `claude_code`, `cowork`, or `office_agent` (the canonical Cost & Usage product naming; an `office_agent` row's per-surface breakdown is in its `office_metrics`). On `/plugins` only `cowork` and `claude_code` occur (the only surfaces with plugin attribution); on `/artifacts` only `chat`, `claude_code`, and `cowork` occur (the surfaces that create artifacts); `/apps/chat/projects` does not support the product dimension (a `product` entry in `group_by[]` or `filter[]` there is rejected). Present only when the request grouped by `product`. - `rbac_group_id: optional string or null`
Resolved RBAC group display name, alongside `rbac_group_id` when name resolution is available. Null if the group has been deleted or its name could not be resolved; `rbac_group_id` remains the stable key. - - `share_status: optional string or null` + - `share_status: optional "organization" or "private" or "public" or null` - Skill share status (claude.ai only): one of 'private', 'organization', or 'public'. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:<value>`. + Skill share status (claude.ai only): one of `private`, `organization`, or `public`. Null for skills used only in Claude Code or Office (no per-skill share-status concept) and when share-status reporting is not yet available for the organization. Filterable via `filter[]=share_status:{value}`. + - `"organization"` + + - `"private"` + + - `"public"` + - `skill_display_name: optional string or null` - Human-readable display name for rows whose skill_name is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when skill_name is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. + Human-readable display name for rows whose `skill_name` is an opaque skill id (user/organization skill types — user-defined names are withheld from the analytics pipeline). Only organization-shared skills resolve; the literal 'unknown' bucket row also gets a fixed 'Unknown skill' label. Null for private (user-defined) skills — their names are not disclosed to analytics-key holders — and null when `skill_name` is already a display name, when the skill was deleted, or when display-name resolution is not enabled for this organization. - `user_id: optional string or null`
"product": "product", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", - "share_status": "share_status", + "share_status": "organization", "skill_display_name": "skill_display_name", "user_id": "user_id" }
api/admin/analytics/usage Changed · +59 / -31 lines
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"cache_read_input_tokens": 0, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 0, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `total_tokens: number` - Total token count across all token types. This is the value the default order_by='total_tokens' sorts on. + Total token count across all token types. This is the value the default `order_by` (`total_tokens`) sorts on. - `uncached_input_tokens: number`
"context_window": "0-200k", "ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 891000, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `total_tokens: number` - Total token count across all token types. This is the value the default order_by='total_tokens' sorts on. + Total token count across all token types. This is the value the default `order_by` (`total_tokens`) sorts on. - `uncached_input_tokens: number`
api/admin/analytics/usage/list Changed · +24 / -10 lines
- `limit: optional number` - 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). + 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). minimum: 1
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. Use `group_by[]=product` to break out per-product values. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
"cache_read_input_tokens": 0, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 0, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
api/admin/analytics/usage/list_by_user Changed · +26 / -12 lines
Opaque cursor from a previous response's `next_page` field. -- `products: optional array of string` +- `products: optional array of "chat" or "claude-tag" or "claude_code" or 4 more` - Product surfaces to include. Defaults to all products. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. + Product surfaces to include. Defaults to all products. maxItems: 100 + - `"chat"` + + - `"claude-tag"` + + - `"claude_code"` + + - `"claude_design"` + + - `"claude_in_chrome"` + + - `"cowork"` + + - `"office_agent"` + - `rbac_group_ids: optional array of string` 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.
- `deleted: boolean` - True when the user is no longer a member of the organization or its associated organizations: either their membership was removed (for example, deprovisioned via your identity provider) or the account itself has been deleted. The flag reflects organization membership, not account status. `name` and `email` stay populated for removed members; `name` is `"Deleted User"` and `email` null when the account has been deleted. The `user_id` is still populated for reconciliation. + True when the account has been deleted, or when the user is no longer a member of the organization or its associated organizations (for example, their membership was removed or they were deprovisioned via your identity provider). `email` stays populated for removed users and is null when the account has been deleted. `name` follows the rules described on that field. The `user_id` is still populated for reconciliation. - `email: string or null`
- `name: string or null` - The user's current name, including for users who are no longer members of the organization or its associated organizations. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. + The user's full name. Null when the user has not set a name. Returns `"Deleted User"` when the account itself has been deleted, or when the user is no longer a member of the organization or its associated organizations and the organization has chosen to hide the names of removed users. Otherwise, the name stays populated for removed users. Rows for system-minted service accounts render the service name (for example, `"Claude Security"` for usage by Anthropic's security-patching service) or null. - `type: "user_actor"`
- `model: string or null` - Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-4-6`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. + Model that produced the usage or cost, as a model name in the form the `models[]` filter accepts (for example, `claude-opus-5`). Null unless `model` is in `group_by[]`; it can also be null on grouped rows whose usage or cost is not attributed to a specific model, such as code execution. - `output_tokens: number`
- `product: string or null` - Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include "chat", "claude_code", "cowork", "office_agent", "claude_in_chrome", "claude_design", and "claude-in-slack". "claude-in-slack" (with hyphens) is Claude Tag, the Claude product in Slack. A similarly spelled legacy value (underscores instead of hyphens) identifies the retiring v1 Slack chat bot and appears only for organizations that used it. Some unattributed usage is reported as "other". + Product surface that produced the usage or cost. Null unless product is in `group_by[]`; it can also be null on grouped rows whose usage cannot be attributed to a known surface. Values include `chat`, `claude_code`, `cowork`, `office_agent`, `claude_in_chrome`, `claude_design`, and `claude-tag`. `claude-tag` is Claude Tag, the Claude product in Slack. Some unattributed usage is reported as "other". - `rbac_group_id: string or null` - RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has ONE id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query with no group_by. + RBAC group (team) the usage is attributed to, in the public tagged `rbac_group_...` spelling — the same spelling the activity resources use for this key, so the same team has one id across resources and it round-trips as an `rbac_group_ids[]` filter value. Populated only when `rbac_group_id` is in `group_by[]`. Any-membership semantics: a user in several groups contributes their full usage to each of those groups' rows, so the named-group rows overlap and their sum can exceed the org total. A null value is the single unassigned row: users in no group on that (UTC) day. For the true org total, run the same query without `group_by[]`. - `requests: number or null`
- `total_tokens: number` - Total token count across all token types. This is the value the default order_by='total_tokens' sorts on. + Total token count across all token types. This is the value the default `order_by` (`total_tokens`) sorts on. - `uncached_input_tokens: number`
"context_window": "0-200k", "ending_at": "2019-12-27T18:11:19.117Z", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 891000, "product": "chat", "rbac_group_id": "rbac_group_012rppKaSVsmTo6NqRDXQXNF",
api/admin/analytics/users Changed · +36 / -14 lines
Get per-user activity for a given day, with cursor-based pagination. Returns activity metrics for each user in the organization, sorted by email -address. Use group_by[] for per-RBAC-group aggregates, or filter[] to +address. Use `group_by[]` for per-RBAC-group aggregates, or `filter[]` to scope results to specific members, groups, or a chat project. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with group_by[] or an rbac_group_id filter); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with `group_by[]` or an `rbac_group_id` filter); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id"` - Dimensions to break results out by (e.g. group_by[]=rbac_group_id). Supported on this endpoint: rbac_group_id. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=rbac_group_id`). Supported on this endpoint: `rbac_group_id`. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
Core Claude Code activity metrics for a single user on a given day. + - `artifacts_created_count: number` + + Number of artifacts created in Claude Code sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `commit_count: number` Number of commits made via Claude Code
Number of tool actions completed in Cowork sessions + - `artifacts_created_count: number` + + Number of artifacts created in Cowork sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `connectors_used_count: number` Total number of connector invocations in Cowork sessions
- `last_activity_date: optional string or null` - Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested date in single-day mode, and to the latest active day in [starting_date, ending_date) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id` it is the last day the user was active while a member of that group, consistent with the row's other metrics. Null on grouped (`group_by[]`) rows. Omitted from the response while last-activity reporting is not enabled for this organization. + Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested `date` in single-day mode, and to the latest active day from `starting_date` (inclusive) to `ending_date` (exclusive) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id:{id}` it is the last day the user was active while a member of that group, consistent with the row's other metrics. On grouped (`group_by[]`) rows it is the latest day any member of the group was active (the requested `date` in single-day mode). Omitted from the response while last-activity reporting is not enabled for this organization. + format: date + - `rbac_group_id: optional string or null` Tagged RBAC group identifier (`rbac_group_...`), matching the spend-limits API spelling. Present only when the request grouped by `rbac_group_id`.
- `user: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
}, "claude_code_metrics": { "core_metrics": { + "artifacts_created_count": 0, "commit_count": 0, "distinct_session_count": 0, "lines_of_code": {
}, "cowork_metrics": { "action_count": 0, + "artifacts_created_count": 0, "connectors_used_count": 0, "dispatch_turn_count": 0, "distinct_connectors_used_count": 0,
}, "web_search_count": 0, "distinct_user_count": 0, - "last_activity_date": "last_activity_date", + "last_activity_date": "2019-12-27", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", "user": {
Core Claude Code activity metrics for a single user on a given day. + - `artifacts_created_count: number` + + Number of artifacts created in Claude Code sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `commit_count: number` Number of commits made via Claude Code
Number of tool actions completed in Cowork sessions + - `artifacts_created_count: number` + + Number of artifacts created in Cowork sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `connectors_used_count: number` Total number of connector invocations in Cowork sessions
- `last_activity_date: optional string or null` - Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested date in single-day mode, and to the latest active day in [starting_date, ending_date) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id` it is the last day the user was active while a member of that group, consistent with the row's other metrics. Null on grouped (`group_by[]`) rows. Omitted from the response while last-activity reporting is not enabled for this organization. + Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested `date` in single-day mode, and to the latest active day from `starting_date` (inclusive) to `ending_date` (exclusive) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id:{id}` it is the last day the user was active while a member of that group, consistent with the row's other metrics. On grouped (`group_by[]`) rows it is the latest day any member of the group was active (the requested `date` in single-day mode). Omitted from the response while last-activity reporting is not enabled for this organization. + format: date + - `rbac_group_id: optional string or null` Tagged RBAC group identifier (`rbac_group_...`), matching the spend-limits API spelling. Present only when the request grouped by `rbac_group_id`.
- `user: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
api/admin/analytics/users/list Changed · +23 / -11 lines
Get per-user activity for a given day, with cursor-based pagination. Returns activity metrics for each user in the organization, sorted by email -address. Use group_by[] for per-RBAC-group aggregates, or filter[] to +address. Use `group_by[]` for per-RBAC-group aggregates, or `filter[]` to scope results to specific members, groups, or a chat project. Available to organizations on a Claude Enterprise plan. Requires an API key with the `read:analytics` scope.
- `ending_date: optional string` - UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with starting_date. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after starting_date. + UTC date in YYYY-MM-DD format. End of the date range (exclusive); only valid with `starting_date`. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day), so this can be at most today — which is also the default when omitted, resolved once when the first page is served and reused for the rest of the pagination sequence. At most 366 days after `starting_date`. format: date - `filter: optional array of string` - Filters as 'dimension:value', e.g. filter[]=rbac_group_id:<id>. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: project_id, rbac_group_id, user_id. Value forms: project_id takes a tagged project id (claude_proj_...) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with group_by[] or an rbac_group_id filter); rbac_group_id takes the tagged id (rbac_group_..., as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); user_id takes a tagged user id (user_...), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. + Filters as `dimension:value`, e.g. `filter[]=rbac_group_id:{id}`. Repeat the param for OR within a dimension and across dimensions for AND. Supported dimensions on this endpoint: `project_id`, `rbac_group_id`, `user_id`. Value forms: `project_id` takes a tagged project id (`claude_proj_...`) and scopes each member's row to their claude.ai chat activity within that project (it cannot be combined with `group_by[]` or an `rbac_group_id` filter); `rbac_group_id` takes the tagged id (`rbac_group_...`, as emitted in responses and by the spend-limits API) or a bare group UUID, and matches users who held the group at any point during each covered UTC day (time-of-usage attribution); `user_id` takes a tagged user id (`user_...`), as emitted in responses. An unsupported dimension returns 400. At most 100 entries. maxItems: 100 - `group_by: optional array of "rbac_group_id"` - Dimensions to break results out by (e.g. group_by[]=rbac_group_id). Supported on this endpoint: rbac_group_id. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via next_page; an unsupported dimension returns 400. rbac_group_id attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. + Dimensions to break results out by (e.g. `group_by[]=rbac_group_id`). Supported on this endpoint: `rbac_group_id`. Rows are already per-member, so the one supported grouping aggregates them per RBAC group instead. Grouped rows carry the requested dimension values as additional fields and paginate like ungrouped responses via `next_page`; an unsupported dimension returns 400. `rbac_group_id` attributes a user to every group they held at any point during each covered UTC day, so grouped rows are not an exclusive partition and can sum above org-level totals. At most 100 entries. maxItems: 100
- `order: optional "asc" or "desc"` - Sort direction: 'asc' or 'desc'. Defaults to 'asc' for the endpoint's sort column and to 'desc' when order_by names a metric (a top-N ranking). Applies to order_by, or to the endpoint's default sort field when order_by is omitted. + Sort direction: `asc` or `desc`. Defaults to `asc` for the endpoint's sort column and to `desc` when `order_by` names a metric (a top-N ranking). Applies to `order_by`, or to the endpoint's default sort field when `order_by` is omitted. - `"asc"`
- `page: optional string` - Opaque cursor from a previous response's next_page field. + Opaque cursor from a previous response's `next_page` field. - `starting_date: optional string` - UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either date or starting_date, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. + UTC date in YYYY-MM-DD format. Start of a date range (inclusive). Enables rollup mode: one row per entity aggregated over the whole range — addable counters are summed across days, and a distinct count is never summed where summing could double-count (a field's range value is recomputed exactly over the window, approximate via HLL with typical error under 2%, null, or — for the creation-event counts, whose per-day values cannot overlap — a per-day sum that is itself exact; each field's own description says which). Use either `date` or `starting_date`, not both. Data is typically available with a 1-day lag (varies by query; the error for a too-recent date names the latest available day) and may be revised by a few percent over the following days. No earlier than 2026-01-01. format: date
Core Claude Code activity metrics for a single user on a given day. + - `artifacts_created_count: number` + + Number of artifacts created in Claude Code sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `commit_count: number` Number of commits made via Claude Code
Number of tool actions completed in Cowork sessions + - `artifacts_created_count: number` + + Number of artifacts created in Cowork sessions: an artifact counts once, on the day a session first saves it. Counted from 2026-08-17; 0 on earlier days. Exact in date-range mode: a creation belongs to exactly one day, so the per-day counts never overlap and their sum over the window is the exact count of distinct creations in it. + - `connectors_used_count: number` Total number of connector invocations in Cowork sessions
- `last_activity_date: optional string or null` - Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested date in single-day mode, and to the latest active day in [starting_date, ending_date) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id` it is the last day the user was active while a member of that group, consistent with the row's other metrics. Null on grouped (`group_by[]`) rows. Omitted from the response while last-activity reporting is not enabled for this organization. + Most recent UTC day (YYYY-MM-DD) on which the user had any counted activity, within the requested window: equal to the requested `date` in single-day mode, and to the latest active day from `starting_date` (inclusive) to `ending_date` (exclusive) in date-range rollup mode — never a day earlier than the window start. On filtered requests (`filter[]`) only days matching the filter count: with `filter[]=rbac_group_id:{id}` it is the last day the user was active while a member of that group, consistent with the row's other metrics. On grouped (`group_by[]`) rows it is the latest day any member of the group was active (the requested `date` in single-day mode). Omitted from the response while last-activity reporting is not enabled for this organization. + format: date + - `rbac_group_id: optional string or null` Tagged RBAC group identifier (`rbac_group_...`), matching the spend-limits API spelling. Present only when the request grouped by `rbac_group_id`.
- `user: optional AnalyticsUser or null` - User identifier. + A user in the organization, identified by tagged id and email address. - `id: string`
Email address of the user - - `type: optional "user"` + - `type: "user"` Object type. Always `user`.
}, "claude_code_metrics": { "core_metrics": { + "artifacts_created_count": 0, "commit_count": 0, "distinct_session_count": 0, "lines_of_code": {
}, "cowork_metrics": { "action_count": 0, + "artifacts_created_count": 0, "connectors_used_count": 0, "dispatch_turn_count": 0, "distinct_connectors_used_count": 0,
}, "web_search_count": 0, "distinct_user_count": 0, - "last_activity_date": "last_activity_date", + "last_activity_date": "2019-12-27", "rbac_group_id": "rbac_group_id", "rbac_group_name": "rbac_group_name", "user": {
api/admin/api_keys Changed · +195 / -57 lines
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + ### Example ```bash
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" + }, "status": "active", "type": "api_key", "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + - `first_id: string or null` First ID in the `data` list. Can be used as the `before_id` for the previous page.
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" + }, "status": "active", "type": "api_key", "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + ### Example ```bash
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
api/admin/api_keys/list Changed · +65 / -19 lines
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + - `first_id: string or null` First ID in the `data` list. Can be used as the `before_id` for the previous page.
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
api/admin/api_keys/retrieve Changed · +58 / -12 lines
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + ## Example ```bash
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
api/admin/api_keys/update Changed · +58 / -12 lines
ID of the actor that created the object. - - `type: string` + - `type: "service_account" or "user"` Type of the actor that created the object. + - `"service_account"` + + - `"user"` + - `expires_at: string or null` RFC 3339 datetime string indicating when the API Key expires, or `null` if it never expires.
Partially redacted hint for the API key. - - `principal: object or null` + - `principal: object or object or null` - The ID and type of the principal the API key acts as, or `null` if the key is not bound to a principal. + The principal the API key acts as (a User or a Service Account), or `null` if the API key is not bound to a principal. - - `id: string` + - `UserActor object` - ID of the principal the API key acts as: a User ID (`user_...`) when the type is `user`, or a Service Account ID (`svac_...`) when the type is `service_account`. + - `type: "user_actor"` - - `type: "service_account" or "user"` + Principal type. Always `"user_actor"` for a User. - Type of the principal the API key acts as. + default: user_actor - - `"service_account"` + - `user_id: string` - - `"user"` + ID of the User the API key acts as. + - `ServiceAccountActor object` + + - `service_account_id: string` + + ID of the Service Account the API key acts as. + + - `type: "service_account_actor"` + + Principal type. Always `"service_account_actor"` for a Service Account. + + default: service_account_actor + + - `scope: object or object` + + Where the API key belongs: its Workspace (`{"type": "workspace", "workspace_id": "wrkspc_..."}`, with the Workspace's real ID even when it is the organization's default Workspace), or the organization (`{"type": "organization"}`) for a principal-bound API key that has no Workspace. + + - `Organization object` + + - `type: "organization"` + + Scope type. Always `"organization"`: the API key has no Workspace. Only a principal-bound API key can have this scope. + + default: organization + + - `Workspace object` + + - `type: "workspace"` + + Scope type. Always `"workspace"`: the API key belongs to one Workspace. + + default: workspace + + - `workspace_id: string` + + ID of the Workspace the API key belongs to. Unlike the deprecated top-level `workspace_id`, this is the Workspace's real ID even for the organization's default Workspace. + - `status: "active" or "archived" or "expired" or "inactive"` Status of the API key.
- `workspace_id: string or null` - ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. + **Deprecated**: Use `scope` instead. `workspace_id` is `null` both for an API key in the default Workspace and for a principal-bound API key that has no Workspace. + Deprecated: use `scope` instead. ID of the Workspace associated with the API key, or `null` if the API key belongs to the default Workspace. Also `null` for a principal-bound API key that has no Workspace; `scope` tells the two apart. + ## Example ```bash
"name": "Developer Key", "partial_key_hint": "sk-ant-api03-R2D...igAA", "principal": { - "id": "user_01WCz1FkmYMm4gnmykNKUu3Q", - "type": "user" + "type": "user_actor", + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" + }, + "scope": { + "type": "workspace", + "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }, "status": "active", "type": "api_key",
api/admin/cost_report Changed · +10 / -2 lines
End of the time bucket (exclusive) in RFC 3339 format. + format: date-time + - `results: array of object` List of cost items for this time bucket. There may be multiple items if one or more `group_by[]` parameters are specified.
Start of the time bucket (inclusive) in RFC 3339 format. + format: date-time + - `has_more: boolean` Indicates if there are more results.
"context_window": "0-200k", "cost_type": "tokens", "currency": "USD", - "description": "Claude Sonnet 4 Usage - Input Tokens", + "description": "Claude Opus 5 Usage - Input Tokens", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "service_tier": "standard", "token_type": "uncached_input_tokens", "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
End of the time bucket (exclusive) in RFC 3339 format. + format: date-time + - `results: array of object` List of cost items for this time bucket. There may be multiple items if one or more `group_by[]` parameters are specified.
- `starting_at: string` Start of the time bucket (inclusive) in RFC 3339 format. + + format: date-time - `has_more: boolean`
api/admin/cost_report/retrieve Changed · +6 / -2 lines
End of the time bucket (exclusive) in RFC 3339 format. + format: date-time + - `results: array of object` List of cost items for this time bucket. There may be multiple items if one or more `group_by[]` parameters are specified.
Start of the time bucket (inclusive) in RFC 3339 format. + format: date-time + - `has_more: boolean` Indicates if there are more results.
"context_window": "0-200k", "cost_type": "tokens", "currency": "USD", - "description": "Claude Sonnet 4 Usage - Input Tokens", + "description": "Claude Opus 5 Usage - Input Tokens", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "service_tier": "standard", "token_type": "uncached_input_tokens", "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
api/admin/external_keys Changed · +20 / -20 lines
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
api/admin/external_keys/create Changed · +4 / -4 lines
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
api/admin/external_keys/update Changed · +4 / -4 lines
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
- `region: optional string or null` - AWS region. Derived from kms_arn if omitted. + AWS region. Derived from `kms_arn` if omitted. - `role_arn: optional string or null`
- `vault_uri: string` - Key Vault data-plane URI — https://<vault-name>.vault.azure.net or https://<hsm-name>.managedhsm.azure.net. + Key Vault data-plane URI — `https://{vault-name}.vault.azure.net` or `https://{hsm-name}.managedhsm.azure.net`. - `client_id: optional string or null`
api/admin/invites Changed · +11 / -11 lines
**POST** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Invite a user to join the organization by email. On plans that draw members from a finite pool of purchased seats, the invite automatically consumes a seat from the lowest tier with availability; there is no seat-tier parameter. When no seat is free the request fails with a 400 error rather than purchasing a seat.
Role for the invited User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
- `rbac_group_ids: optional array of string` - RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups (beta), and requires the key to carry the `write:rbac_groups` scope. + RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups, and requires the key to carry the `write:rbac_groups` scope. maxItems: 100
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**GET** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve an invite by ID. ### Path parameters
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**GET** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's invites. ### Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. - `statuses: optional array of "accepted" or "expired" or "pending"`
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
**DELETE** `/v1/organizations/invites/{invite_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Delete a pending invite. ### Path parameters
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
api/admin/invites/create Changed · +4 / -4 lines
**POST** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Invite a user to join the organization by email. On plans that draw members from a finite pool of purchased seats, the invite automatically consumes a seat from the lowest tier with availability; there is no seat-tier parameter. When no seat is free the request fails with a 400 error rather than purchasing a seat.
Role for the invited User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
- `rbac_group_ids: optional array of string` - RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups (beta), and requires the key to carry the `write:rbac_groups` scope. + RBAC group IDs to assign to the User when the Invite is accepted. A non-empty array is accepted only for a Claude Enterprise organization with RBAC groups, and requires the key to carry the `write:rbac_groups` scope. maxItems: 100
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
api/admin/invites/list Changed · +3 / -3 lines
**GET** `/v1/organizations/invites` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's invites. ## Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. - `statuses: optional array of "accepted" or "expired" or "pending"`
- `rbac_group_ids: array of string` - RBAC group IDs recorded on the Invite (beta, Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. + RBAC group IDs recorded on the Invite (Claude Enterprise organizations), to be assigned to the User when the Invite is accepted. `[]` when none. - `role: "admin" or "billing" or "claude_code_user" or 6 more`
api/admin/rbac_groups Changed · +8 / -72 lines
### Headers ### Headers ### Headers ### Headers ### Headers #### Headers #### Headers #### Headers
List RBAC Groups in the Claude Enterprise tenant. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Query parameters
Optionally set to the `next_page` token from the previous response. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `data: array of RbacGroup`
Retrieve an RBAC Group by ID. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
ID of the RBAC Group. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `RbacGroup object`
Create an RBAC Group in the Claude Enterprise tenant. Groups created via the API have source type `"direct"`. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Body parameters - `name: string`
Update an RBAC Group's name. Groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
ID of the RBAC Group. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Body parameters - `name: optional string or null`
Delete an RBAC Group. Groups provisioned by an identity provider (source type `"scim"`) cannot be deleted via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
ID of the RBAC Group. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `RbacGroupDeleted object`
List members of an RBAC Group. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters
Optionally set to the `next_page` token from the previous response. -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - #### Returns - `data: array of RbacGroupMember`
Add a User to an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters
ID of the RBAC Group. -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - #### Body parameters - `user_id: string`
Remove a User from an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. #### Path parameters
- `user_id: string` ID of the User. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
api/admin/rbac_groups/create Changed · +1 / -9 lines
## Headers
Create an RBAC Group in the Claude Enterprise tenant. Groups created via the API have source type `"direct"`. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Body parameters
api/admin/rbac_groups/delete Changed · +1 / -9 lines
## Headers
Delete an RBAC Group. Groups provisioned by an identity provider (source type `"scim"`) cannot be deleted via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `group_id: string` ID of the RBAC Group. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_groups/list Changed · +1 / -9 lines
## Headers
List RBAC Groups in the Claude Enterprise tenant. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Query parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_groups/members Changed · +3 / -27 lines
### Headers ### Headers ### Headers
List members of an RBAC Group. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
Optionally set to the `next_page` token from the previous response. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `data: array of RbacGroupMember`
Add a User to an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
ID of the RBAC Group. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Body parameters - `user_id: string`
Remove a User from an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ### Path parameters
- `user_id: string` ID of the User. - -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ### Returns
api/admin/rbac_groups/members/create Changed · +1 / -9 lines
## Headers
Add a User to an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `group_id: string` ID of the RBAC Group. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Body parameters
api/admin/rbac_groups/members/delete Changed · +1 / -9 lines
## Headers
Remove a User from an RBAC Group. Membership of groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `user_id: string` ID of the User. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_groups/members/list Changed · +1 / -9 lines
## Headers
List members of an RBAC Group. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_groups/retrieve Changed · +1 / -9 lines
## Headers
Retrieve an RBAC Group by ID. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `group_id: string` ID of the RBAC Group. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_groups/update Changed · +1 / -9 lines
## Headers
Update an RBAC Group's name. Groups provisioned by an identity provider (source type `"scim"`) cannot be modified via the API. -The RBAC Groups API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Groups API is available to Claude Enterprise organizations only. ## Path parameters
- `group_id: string` ID of the RBAC Group. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Body parameters
api/admin/rbac_roles Changed · +3 / -27 lines
### Headers ### Headers #### Headers
List RBAC Roles in the organization. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ### Query parameters
Optionally set to the `next_page` token from the previous response. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `data: array of RbacRole`
Retrieve an RBAC Role by ID. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ### Path parameters
ID of the RBAC Role. -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. - ### Returns - `RbacRole object`
List the permissions an RBAC Role grants. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. #### Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -#### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. #### Returns
api/admin/rbac_roles/list Changed · +1 / -9 lines
## Headers
List RBAC Roles in the organization. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ## Query parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_roles/permissions Changed · +1 / -9 lines
### Headers
List the permissions an RBAC Role grants. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ### Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -### Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ### Returns
api/admin/rbac_roles/permissions/list Changed · +1 / -9 lines
## Headers
List the permissions an RBAC Role grants. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ## Path parameters
- `page: optional string` Optionally set to the `next_page` token from the previous response. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/rbac_roles/retrieve Changed · +1 / -9 lines
## Headers
Retrieve an RBAC Role by ID. -The RBAC Roles API is in beta and available to Claude Enterprise organizations only. Requests must send the `ce-user-management-2026-07-13` value in the `anthropic-beta` header. +The RBAC Roles API is available to Claude Enterprise organizations only. ## Path parameters
- `role_id: string` ID of the RBAC Role. - -## Headers - -- `"anthropic-beta": optional array of string` - - Optional header to specify the beta version(s) you want to use. - - To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta. ## Returns
api/admin/service_accounts/workspaces Changed · +4 / -4 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/spend_limits Changed · +369 / -33 lines
The two sides of this change are too far apart to line up, so this is the differ's own diff of it.
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `period: optional "daily" or "monthly" or "weekly"` - `"daily"`
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + + RFC 3339 datetime at which the spend limit was last modified. format: date-time
"amount": "50000", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "period": "monthly" }'
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + + RFC 3339 datetime at which the spend limit was last modified. format: date-time
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
- `limit: optional number` + Maximum number of members per page. A member's period rows never split across pages, so a page may carry more rows than this. Defaults to `20`. + default: 20, maximum: 1000, minimum: 1 - `page: optional string` -- `period: optional array of string` + Opaque cursor from a previous response's `next_page` field. + +- `period: optional array of "daily" or "monthly" or "weekly"` + + Restrict the report to these limit periods. Omit to return one row per period each member resolves a spend limit for. maxItems: 3 + - `"daily"` + + - `"monthly"` + + - `"weekly"` + - `user_ids: optional array of string` + + Restrict the report to these members, by tagged user ID (`user_...`). At most 100 entries. maxItems: 100
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" }
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time ### Spend Summary - `SpendSummary object` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_limit: SpendLimit` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies. - `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time - `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit": { "id": "id",
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + + Tagged ID of the user. - `created_at: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
api/admin/spend_limits/create Changed · +28 / -2 lines
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `period: optional "daily" or "monthly" or "weekly"` - `"daily"`
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies.
- `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time ## Example
"amount": "50000", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "period": "monthly" }'
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
api/admin/spend_limits/increase_requests Changed · +343 / -27 lines
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_limit: SpendLimit` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies.
- `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time - `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit": { "id": "id",
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_limit: SpendLimit` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies.
- `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time - `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + + Tagged ID of the member the spend limit applies to. - `SeatTier object`
api/admin/spend_limits/increase_requests/approve Changed · +73 / -7 lines
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_limit: SpendLimit` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies.
- `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time - `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit": { "id": "id",
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
api/admin/spend_limits/increase_requests/deny Changed · +52 / -6 lines
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
api/admin/spend_limits/increase_requests/list Changed · +52 / -6 lines
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
api/admin/spend_limits/increase_requests/retrieve Changed · +52 / -6 lines
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `created_at: string` format: date-time
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `ScopedAPIKeyActor object` A scoped Admin API key acting on behalf of the organization.
- `spend_summary: SpendSummary or null` - Per-member effective-limit report row (GET /spend_limits/effective). + Per-member effective-limit report row (`GET /spend_limits/effective`). - `actor: object`
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "created_at": "2019-12-27T18:11:19.117Z", "period": "monthly",
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_summary": { "actor": {
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" },
api/admin/spend_limits/list_effective Changed · +44 / -4 lines
- `limit: optional number` + Maximum number of members per page. A member's period rows never split across pages, so a page may carry more rows than this. Defaults to `20`. + default: 20, maximum: 1000, minimum: 1 - `page: optional string` -- `period: optional array of string` + Opaque cursor from a previous response's `next_page` field. +- `period: optional array of "daily" or "monthly" or "weekly"` + + Restrict the report to these limit periods. Omit to return one row per period each member resolves a spend limit for. + maxItems: 3 + - `"daily"` + + - `"monthly"` + + - `"weekly"` + - `user_ids: optional array of string` + Restrict the report to these members, by tagged user ID (`user_...`). At most 100 entries. + maxItems: 100 ## Returns
- `deleted: boolean` + True only when the underlying account has been deleted. + default: false - `email_address: string or null` + The user's email address. Null when the account is unavailable or has been deleted. + - `name: string or null` + The user's current display name. Null when the account is unavailable, has been deleted, or has no name set. + - `type: "user_actor"` + Actor type. Always `user_actor`. + default: user_actor - `user_id: string` + Tagged ID of the user. + - `amount: string or null` Effective limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD). `null` means no limit applies for this row's `period` — each period resolves independently, so another period may still cap this member.
- `period: "daily" or "monthly" or "weekly"` + Period this row's effective limit and spend are reported for. + - `"daily"` - `"monthly"`
- `scope: object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `source: object or object or object or 2 more` + Scope selecting a single member of the organization. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
"email_address": "email_address", "name": "name", "type": "user_actor", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "amount": "50000", "currency": "USD",
"period_to_date_spend": "12050.5", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "source": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "spend_limit_id": "spend_limit_id" }
api/admin/spend_limits/retrieve Changed · +21 / -1 lines
- `SpendLimit object` + A configured spend limit: a cap on metered spend for one scope and period. + - `id: string` + Unique tagged ID of the spend limit (`spl_...`). + - `amount: string or null` Limit amount as a non-negative integer decimal string in the minor unit of `currency` (cents for USD): "50000" is $500.00. `null` means no numeric cap is configured at this scope — see the effective report for whether a limit applies.
- `created_at: string` + RFC 3339 datetime at which the spend limit was created. + format: date-time - `currency: string`
- `period: "daily" or "monthly" or "weekly"` + Length of the window the limit resets over. `amount` caps spend within each period. + - `"daily"` - `"monthly"`
- `scope: object or object or object or 2 more` + What the limit applies to. A tagged union on `type`; each variant carries the identifier for its scope. + - `User object` + Scope selecting a single member of the organization. + - `type: "user"` + Scope type. Always `user` for this scope. + default: user - `user_id: string` + Tagged ID of the member the spend limit applies to. + - `SeatTier object` - `seat_tier: string`
- `type: "spend_limit"` + Object type. Always `spend_limit`. + default: spend_limit - `updated_at: string` + RFC 3339 datetime at which the spend limit was last modified. + format: date-time ## Example
"period": "monthly", "scope": { "type": "user", - "user_id": "user_id" + "user_id": "user_01WCz1FkmYMm4gnmykNKUu3Q" }, "type": "spend_limit", "updated_at": "2019-12-27T18:11:19.117Z"
api/admin/usage_report Changed · +3 / -3 lines
"cache_read_input_tokens": 200, "context_window": "0-200k", "inference_geo": "global", - "model": "claude-opus-4-6", + "model": "claude-opus-5", "output_tokens": 500, "server_tool_use": { "web_search_requests": 10
UTC date in YYYY-MM-DD format. Returns metrics for this single day only. - pattern: ^\d{4}-\d{2}-\d{2}$ + pattern: ^\d{4}-\d{2}-\d{2}$, format: date - `limit: optional number`
"amount": 186, "currency": "USD" }, - "model": "claude-opus-4-8", + "model": "claude-opus-5", "tokens": { "cache_creation": 2340, "cache_read": 8790,
api/admin/users Changed · +6 / -6 lines
**GET** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Retrieve a member of the organization by user ID. ### Path parameters
**GET** `/v1/organizations/users` -For Claude Enterprise organizations, this endpoint's availability is in beta. +List the organization's members. ### Query parameters
Filter to items whose `role` equals one of the supplied values. Repeatable; values are OR'ed together. - Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations (beta) accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. + Accepted values depend on the organization type: Console and API organizations accept `user`, `developer`, `billing`, `admin`, and `claude_code_user`; Claude Enterprise organizations accept `user`, `owner`, `primary_owner`, `membership_admin`, and `managed`. ### Returns
**POST** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Update a member's organization role. ### Path parameters
New role for the User. - The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations (beta) accept `user` and `managed`. + The accepted values depend on the organization type. Console and API organizations accept `user`, `developer`, `billing`, and `claude_code_user`; `admin` cannot be assigned through the API. Claude Enterprise organizations accept `user` and `managed`. - `"billing"`
**DELETE** `/v1/organizations/users/{user_id}` -For Claude Enterprise organizations, this endpoint's availability is in beta. +Remove a member from the organization. ### Path parameters
api/admin/workspaces Changed · +8 / -8 lines
- `data_residency: optional object or null` - Data residency configuration for the workspace. If omitted, defaults to workspace_geo=`"us"`, allowed_inference_geos=`"unrestricted"`, and default_inference_geo=`"global"`. + Data residency configuration for the workspace. If omitted, defaults to `workspace_geo: "us"`, `allowed_inference_geos: "unrestricted"`, and `default_inference_geo: "global"`. - `allowed_inference_geos: optional array of "global" or "us" or "unrestricted" or null`
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Defaults to 'global' if omitted. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
- `default_inference_geo: optional "global" or "us" or null` - Default inference geo applied when requests omit the parameter. Must be a member of allowed_inference_geos unless allowed_inference_geos is `"unrestricted"`. + Default inference geo applied when requests omit the parameter. Must be a member of `allowed_inference_geos` unless `allowed_inference_geos` is `"unrestricted"`. - `"global"`
- `workspace_role: "workspace_admin" or "workspace_developer" or "workspace_restricted_developer" or "workspace_user"` - Role of the new Workspace Member. Cannot be "workspace_billing". + Role of the new Workspace Member. Cannot be `workspace_billing`. - `"workspace_admin"`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/admin/workspaces/service_accounts Changed · +8 / -8 lines
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
- `implicit: boolean or null` - True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role workspace_user and cannot be removed. + True when this is the implicit default-workspace membership every service account has when no explicit membership exists. Implicit memberships have role `workspace_user` and cannot be removed. - `service_account_id: string`
api/claude-platform-on-aws-iam-actions Changed · +27 / -8 lines
### Encryption keys
## Actions -The service defines 66 actions. Actions follow the AWS `VerbNoun` convention and use verb discipline so that `Get*` and `List*` wildcards produce a clean read-only boundary. +The service defines 71 actions. Actions follow the AWS `VerbNoun` convention and use verb discipline so that `Get*` and `List*` wildcards produce a clean read-only boundary. ### Inference
Workspaces support only archive, not hard delete. A policy that denies `aws-external-anthropic:Delete*` does not block `ArchiveWorkspace`. Deny `ArchiveWorkspace`, `UpdateWorkspace`, and `CreateWorkspace` if you need to prevent any workspace mutation. </Note> +### Encryption keys + +| Action | Routes authorized | +| ------------- | --------------------------------------------- | +| `RegisterKey` | `POST /v1/organizations/external_keys` | +| `GetKey` | `GET /v1/organizations/external_keys/{id}` | +| `ListKeys` | `GET /v1/organizations/external_keys` | +| `UpdateKey` | `POST /v1/organizations/external_keys/{id}` | +| `DisableKey` | `DELETE /v1/organizations/external_keys/{id}` | + +<Note> + These actions manage your organization's [customer-managed encryption key (CMEK)](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws) registrations, the record of which AWS KMS key ARNs are registered. They do not create, change, or disable the keys in AWS KMS. `DisableKey` removes a registration and is rejected while any workspace still uses the key. `RegisterKey` and `DisableKey` are not matched by `Create*`, `Update*`, or `Delete*` wildcards; deny `RegisterKey`, `UpdateKey`, and `DisableKey` if you need to prevent any change to key registrations. In these routes, `{id}` is the URL-encoded KMS key ARN. Attaching a registered key to a workspace is a workspace operation, authorized by `CreateWorkspace` or `UpdateWorkspace`; the principal that attaches a key also needs `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on that key (see the [prerequisites](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws)). External key actions are account-scoped: specifying a workspace ARN on them has no effect; use `Resource: "*"`. +</Note> + ### Compliance | Action | Routes authorized |
## Route-to-action mapping -The following table lists every route on Claude Platform on AWS and the IAM action required to call it. Each IAM action also authorizes requests that use the `anthropic-beta` header; beta variants of a route do not require a separate IAM action. CloudTrail classifies each action as either a Data event (high-volume, data-plane operations) or a Management event (control-plane operations). Vault and webhook actions are classified as Management events because they hold secrets (vault credentials and webhook signing secrets) and benefit from default-on audit logging. Workspace and compliance actions are also classified as Management events because they are organization-scoped control-plane operations. All other actions, including inference, batch, model, file, skill, user profile, and the remaining Claude Managed Agents actions, are classified as Data events. +The following table lists every route on Claude Platform on AWS and the IAM action required to call it. Each IAM action also authorizes requests that use the `anthropic-beta` header; beta variants of a route do not require a separate IAM action. CloudTrail classifies each action as either a Data event (high-volume, data-plane operations) or a Management event (control-plane operations). Vault and webhook actions are classified as Management events because they hold secrets (vault credentials and webhook signing secrets) and benefit from default-on audit logging. Workspace, external key, and compliance actions are also classified as Management events because they are organization-scoped control-plane operations. All other actions, including inference, batch, model, file, skill, user profile, and the remaining Claude Managed Agents actions, are classified as Data events. | Method | Route | IAM action | CloudTrail event type | | -------- | ---------------------------------------------------- | -------------------------- | --------------------- |
| `GET` | `/v1/organizations/workspaces/{id}` | `GetWorkspace` | Management | | `POST` | `/v1/organizations/workspaces/{id}` | `UpdateWorkspace` | Management | | `POST` | `/v1/organizations/workspaces/{id}/archive` | `ArchiveWorkspace` | Management | +| `POST` | `/v1/organizations/external_keys` | `RegisterKey` | Management | +| `GET` | `/v1/organizations/external_keys` | `ListKeys` | Management | +| `GET` | `/v1/organizations/external_keys/{id}` | `GetKey` | Management | +| `POST` | `/v1/organizations/external_keys/{id}` | `UpdateKey` | Management | +| `DELETE` | `/v1/organizations/external_keys/{id}` | `DisableKey` | Management | | `GET` | `/v1/compliance/activities` | `ListComplianceActivities` | Management | | `POST` | `/v1/agents` | `CreateAgent` | Data | | `GET` | `/v1/agents` | `ListAgents` | Data |
Routes not in this table are not available on Claude Platform on AWS. The gateway denies any route not listed here by default. <Note> - Workspace routes are the only Admin API routes available on Claude Platform on AWS. You can also create, update, or archive workspaces in the AWS Console or, with the Admin role, in the Claude Console. + Workspace and external key routes are the only Admin API routes available on Claude Platform on AWS. You can also create, update, or archive workspaces in the AWS Console or, with the Admin role, in the Claude Console. Encryption keys can also be registered and attached in the Claude Console. </Note> ## Managed policies
| `AnthropicLimitedAccess` | All `AnthropicInferenceAccess` actions, plus all Claude Managed Agents actions (agents, sessions, environments, vaults, memory stores, webhooks, and self-hosted environment work) | | `AnthropicSelfHostedEnvironmentAccess` | `GetEnvironment`, `ProcessEnvironmentWork`, `GetSession`, `UpdateSession`, `GetSkill`, `CallWithBearerToken` | -`AnthropicInferenceAccess` is the narrowest managed policy sufficient to run inference. It covers both synchronous and batch inference and, through the `Get*` and `List*` wildcards, grants read access to every API resource in the namespace, including Claude Managed Agents (CMA) resources (agents, sessions, environments, vaults, memory stores, and webhooks). This includes file content download through `GetFile` (see the [Files](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#files) note), skill content download through `GetSkill` (see the [Skills](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#skills) note), and memory contents through `GetMemoryStore`. Vault credential secrets and webhook signing secrets are not exposed: those fields are write-only and are never returned by `GetVault` or `GetWebhook` (see [Authenticate with vaults](https://platform.claude.com/docs/en/managed-agents/vaults)). `AnthropicInferenceAccess` does not grant file creation or deletion, skill management, user profile management, workspace mutation, or any Claude Managed Agents write action (create, update, archive, delete, process, or rotate). To exclude CMA reads, replace `AnthropicInferenceAccess` with a custom policy that enumerates only the specific non-CMA actions you need. +`AnthropicInferenceAccess` is the narrowest managed policy sufficient to run inference. It covers both synchronous and batch inference and, through the `Get*` and `List*` wildcards, grants read access to every API resource in the namespace, including Claude Managed Agents (CMA) resources (agents, sessions, environments, vaults, memory stores, and webhooks). This includes file content download through `GetFile` (see the [Files](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#files) note), skill content download through `GetSkill` (see the [Skills](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#skills) note), and memory contents through `GetMemoryStore`. Vault credential secrets and webhook signing secrets are not exposed: those fields are write-only and are never returned by `GetVault` or `GetWebhook` (see [Authenticate with vaults](https://platform.claude.com/docs/en/managed-agents/vaults)). `AnthropicInferenceAccess` does not grant file creation or deletion, skill management, user profile management, workspace mutation, encryption key management, or any Claude Managed Agents write action (create, update, archive, delete, process, or rotate). To exclude CMA reads, replace `AnthropicInferenceAccess` with a custom policy that enumerates only the specific non-CMA actions you need. <Note> - `AnthropicReadOnlyAccess`, `AnthropicInferenceAccess`, and `AnthropicLimitedAccess` all carry the `Get*` and `List*` wildcards, which grant read access to all content in the workspace: file bytes, skill content, batch results, session conversation history, and memory contents. The `List*` wildcard also grants `ListComplianceActivities`, which reads the organization's compliance [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) once the Compliance API is enabled for the organization (see [Compliance](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#compliance)). Vault credential secrets and webhook signing secrets are not exposed; those fields are write-only and are never returned by `GetVault` or `GetWebhook`. If your principal should not read existing content, use a custom policy that enumerates only the actions you need. + `AnthropicReadOnlyAccess`, `AnthropicInferenceAccess`, and `AnthropicLimitedAccess` all carry the `Get*` and `List*` wildcards, which grant read access to all content in the workspace: file bytes, skill content, batch results, session conversation history, and memory contents. The wildcards also grant `GetKey` and `ListKeys`, which read the organization's registered encryption key configurations (key ARNs and metadata, never key material). The `List*` wildcard also grants `ListComplianceActivities`, which reads the organization's compliance [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) once the Compliance API is enabled for the organization (see [Compliance](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#compliance)). Vault credential secrets and webhook signing secrets are not exposed; those fields are write-only and are never returned by `GetVault` or `GetWebhook`. If your principal should not read existing content, use a custom policy that enumerates only the actions you need. </Note> `AnthropicLimitedAccess` includes all Claude Managed Agents actions in addition to inference actions.
``` <Note> - The `aws-external-anthropic:*` wildcard in the first statement includes account-scoped actions (`CreateWorkspace`, `ListWorkspaces`, `ListComplianceActivities`) that the workspace ARN constraint silently filters out. This is consistent with the "isolation" intent (the role cannot create workspaces, enumerate workspaces, or read the compliance Activity Feed), but the policy contains permissions that have no effect. See [Provisioning automation](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#provisioning-automation) for the account-scoped pattern. + The `aws-external-anthropic:*` wildcard in the first statement includes account-scoped actions (`CreateWorkspace`, `ListWorkspaces`, `ListComplianceActivities`, and the external key actions) that the workspace ARN constraint silently filters out. This is consistent with the "isolation" intent (the role cannot create workspaces, enumerate workspaces, manage encryption key registrations, or read the compliance Activity Feed; it can still attach an already-registered key to its own workspace through `UpdateWorkspace`), but the policy contains permissions that have no effect. See [Provisioning automation](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#provisioning-automation) for the account-scoped pattern. `CallWithBearerToken` and `AssumeConsole` are route-less actions that do not bind to a workspace ARN. The second statement grants them on `Resource: "*"` so the role can authenticate with an API key and open the Claude Console. Omit this statement if the role uses SigV4 only and does not need Claude Console access. </Note>
api/overview Changed · +10 / -9 lines
## Authentication -For details on both authentication methods and when to use each, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). All requests to the Claude API must include these headers: +For details on each authentication method and when to use it, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). Requests to the Claude API include these headers: -| Header | Value | Required | -| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| `x-api-key` | Your API key from Console | One of `x-api-key` or `Authorization` | -| `Authorization` | `Bearer <token>`, where `<token>` is a short-lived access token obtained from `POST /v1/oauth/token` through [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) | One of `x-api-key` or `Authorization` | -| `anthropic-version` | API version (for example, `2023-06-01`) | Yes | -| `content-type` | `application/json` | Yes | +| Header | Value | Required | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `x-api-key` | Your API key from Console | One of `x-api-key` or `Authorization` | +| `Authorization` | `Bearer <token>`, where `<token>` is a short-lived access token obtained from `POST /v1/oauth/token` through [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) | One of `x-api-key` or `Authorization` | +| `anthropic-workspace-id` | ID of the [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) the request runs in (for example, `wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ`). See [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace). | Required with a multi-workspace API key. Optional for other API keys. Not used with Workload Identity Federation tokens, which select a workspace at token exchange. | +| `anthropic-version` | API version (for example, `2023-06-01`) | Yes | +| `content-type` | `application/json` | Yes | -If you are using the [Client SDKs](https://platform.claude.com/docs/en/api/overview#client-sdks), the SDK will send these headers automatically. For API versioning details, see [API versions](https://platform.claude.com/docs/en/api/versioning). +If you are using the [Client SDKs](https://platform.claude.com/docs/en/api/overview#client-sdks), the SDK sends the authentication, version, and content-type headers automatically; you pass `anthropic-workspace-id` yourself when your key needs it. For API versioning details, see [API versions](https://platform.claude.com/docs/en/api/versioning). When accessing Claude through a [cloud platform](https://platform.claude.com/docs/en/api/overview#claude-api-vs-cloud-platforms), authentication is integrated with the cloud provider's IAM system. See the platform-specific documentation for supported credential types, required headers, and authentication options. ### Getting API keys -The API is made available through the web [Console](https://platform.claude.com/). You can use [playground](https://platform.claude.com/playground) to try out the API in the browser and then generate API keys in [Account Settings](https://platform.claude.com/settings/keys). You choose each key's [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create it. Use [workspaces](https://platform.claude.com/settings/workspaces) to segment your API keys and [control spend](https://platform.claude.com/docs/en/api/rate-limits) by use case. +The API is made available through the web [Console](https://platform.claude.com/). You can use [playground](https://platform.claude.com/playground) to try out the API in the browser and then generate API keys in [Account Settings](https://platform.claude.com/settings/keys). You choose each key's type (see [Key types](https://platform.claude.com/docs/en/manage-claude/authentication#key-types)) and its [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create it. Use [workspaces](https://platform.claude.com/settings/workspaces) to separate environments and [control spend](https://platform.claude.com/docs/en/api/rate-limits) by use case. ## Client SDKs
build-with-claude/batch-processing Changed · +3 / -3 lines
* A Message Batch is limited to either 100,000 Message requests or 256 MB in size, whichever is reached first. * The system processes each batch as fast as possible, with most batches completing within 1 hour. You can access batch results when all messages have completed or after 24 hours, whichever comes first. Batches expire if processing does not complete within 24 hours. * Batch results are available for 29 days after creation. After that, you may still view the Batch, but its results will no longer be available for download. -* Batches are scoped to a [Workspace](https://platform.claude.com/settings/workspaces). You may view all batches (and their results) that were created within the Workspace that your API key belongs to. +* Batches are scoped to a [Workspace](https://platform.claude.com/settings/workspaces). You may view all batches (and their results) that were created within the Workspace your request runs in. * Rate limits apply to both Batches API HTTP requests and the number of requests within a batch waiting to be processed. See [Message Batches API rate limits](https://platform.claude.com/docs/en/api/rate-limits#message-batches-api). Additionally, processing may be slowed down based on current demand and your request volume. In that case, you may see more requests expiring after 24 hours. * Because of high throughput and concurrent processing, batches may go slightly over your Workspace's configured [spend limit](https://platform.claude.com/settings/billing). * Each batched request must have `max_tokens` of at least `1`. `max_tokens: 0` ([cache pre-warming](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pre-warming-the-cache)) is not supported inside a batch, because an ephemeral cache entry written during batch processing would likely expire before the follow-up request runs.
## Batch storage and privacy -* **Workspace isolation**: Batches are isolated within the Workspace they are created in. They can only be accessed by API keys associated with that Workspace, or users with permission to view Workspace batches in the Console. +* **Workspace isolation**: Batches are isolated within the Workspace they are created in. They can only be accessed by API requests in that same Workspace, or users with permission to view Workspace batches in the Console. * **Result availability**: Batch results are available for 29 days after the batch is created, allowing ample time for retrieval and processing.
<Accordion title="How does the Message Batches API handle privacy and data separation?"> The Message Batches API is designed with strong privacy and data separation measures: - 1. Batches and their results are isolated within the Workspace in which they were created. This means they can only be accessed by API keys from that same Workspace. + 1. Batches and their results are isolated within the Workspace in which they were created. This means they can only be accessed by API requests in that same Workspace. 2. Each request within a batch is processed independently, with no data leakage between requests. 3. Results are only available for a limited time (29 days), and follow Anthropic's [data retention policy](https://support.claude.com/en/articles/7996866-how-long-do-you-store-personal-data). 4. Downloading batch results in the Console can be disabled on the organization-level or on a per-workspace basis.
build-with-claude/claude-on-vertex-ai Changed · +4 / -4 lines
<Tab title="Java"> <CodeGroup exclude="shell, python, typescript, csharp, go, php, ruby"> ```groovy Gradle - implementation("com.anthropic:anthropic-java:2.57.0") - implementation("com.anthropic:anthropic-java-vertex:2.57.0") + implementation("com.anthropic:anthropic-java:2.58.0") + implementation("com.anthropic:anthropic-java-vertex:2.58.0") ``` ```xml Maven
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> <dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-vertex</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ```
build-with-claude/claude-platform-on-aws Changed · +25 / -24 lines
<Tab title="Java"> ```kotlin Gradle - implementation("com.anthropic:anthropic-java-aws:2.57.0") + implementation("com.anthropic:anthropic-java-aws:2.58.0") ``` ```xml Maven
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-aws</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ``` </Tab>
* **Batch processing:** Submit batch requests for high-throughput workloads. * **Prompt caching:** Cache tools, system prompts, and message history to reduce latency and cost. All prompt caching capabilities (5-minute TTL, 1-hour TTL, and automatic caching) are available. * **Files API:** Upload and reference files across requests. -* **Customer-managed encryption keys (CMEK):** [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek) is available with [AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms) keys only. Google Cloud KMS and Azure Key Vault keys cannot be registered. Create and attach keys in the [Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console). There is no separate validation step: the key is implicitly validated when you attach it to a workspace (the attach call performs an encrypt/decrypt round), so a key policy problem surfaces at attach time rather than at registration. The `external_keys` Admin API endpoints are not currently available. The key must be in the same AWS region as the workspace it is attached to. +* **Customer-managed encryption keys (CMEK):** [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek) is available with [AWS KMS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms) keys only. Google Cloud KMS and Azure Key Vault keys cannot be registered. The key must be a single-region KMS key in the same AWS account and region as the workspace it is attached to, and its key policy must grant access to the `aws-external-anthropic.amazonaws.com` service principal; see [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws). Register and attach keys in the [Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console); the external key endpoints are also available, authorized through [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys). There is no separate validation step: the key is implicitly validated when you attach it to a workspace (the attach call performs an encrypt/decrypt round), so a key policy problem surfaces at attach time rather than at registration. * **Compliance API:** The [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) is available. Access is authorized through the AWS IAM [`ListComplianceActivities` action](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#compliance). See the [comparison table](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#claude-platform-on-aws-vs-amazon-bedrock) for feature-availability differences from Amazon Bedrock.
* **HIPAA readiness:** Anthropic's HIPAA-ready program is not available. See [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention). * **Computer use and browser use toolsets:** `computer_toolset_20260801` and `browser_toolset_20260801` are not currently available on Claude Platform on AWS. The beta [computer use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool#earlier-tool-versions) tool versions remain available. -- **Admin API:** Workspace endpoints (create, get, list, update, and archive on `/v1/organizations/workspaces`) are available. Other Admin API endpoints (organization members, workspace members, invites, API keys, usage reports, cost reports, rate limit reports, and external keys) are not currently available. Manage [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek) keys in the Claude Console instead. View usage and cost data in the [Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console) instead. AWS IAM manages organization membership. +- **Admin API:** Workspace endpoints (create, get, list, update, and archive on `/v1/organizations/workspaces`) and external key endpoints (register, get, list, update, and delete on `/v1/organizations/external_keys`, for [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek); keys are validated when attached to a workspace rather than through a validate endpoint) are available. Other Admin API endpoints (organization members, workspace members, invites, API keys, usage reports, cost reports, and rate limit reports) are not currently available. View usage and cost data in the [Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console) instead. AWS IAM manages organization membership. - **Workspace member management:** Adding or removing users from individual workspaces is not available. AWS IAM policies on workspace ARNs control access. - **Claude Code workspace and Analytics API:** The Claude Code workspace with automatic rate limits is not available. Claude Code usage appears in the general usage view rather than a dedicated screen. - **OAuth authentication:** Not supported. Use SigV4 or API key authentication.
The **Through AWS gateway** column indicates whether the page reads and writes data through the AWS gateway (and is therefore governed by [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions)). Pages marked **No** read organization-level metadata directly from Anthropic and bypass IAM action checks. -| Page | Available | Through AWS gateway | Notes | -| --------------------- | ------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Usage** | Yes | No | View token usage by model, workspace, and dimension. Data can take a few minutes to appear after a request. | -| **Cost** | Yes | No | View cost breakdowns by model and workspace. AWS Cost Explorer shows the aggregated [Claude Consumption Unit (CCU)](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#billing) line item. | -| **Rate limits** | Yes | No | View rate limits (read-only). Tier increases go through your Anthropic account representative; see [Rate limits and quotas](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#rate-limits-and-quotas). | -| **Workspaces** | Yes | Yes (except spend limits) | View per-region workspaces. With the Admin role, you can also create, rename, and archive workspaces, and set per-workspace [spend limits](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#spend-limits). | -| **Files** | Yes | Yes | View and manage uploaded files. | -| **Skills** | Yes | Yes | View and manage Agent Skills. | -| **Batches** | Yes | Yes | View and manage batch processing jobs. | -| **Agents** | Yes | Yes | View and manage agent definitions. | -| **Sessions** | Yes | Yes | View agent sessions and event history. | -| **Environments** | Yes | Yes | View and manage cloud sandbox configurations for sessions. | -| **Credential vaults** | Yes | Yes | View and manage credential vaults for session authentication. | -| **Memory stores** | Yes | Yes | View and manage persistent agent memory. | -| **Webhooks** | Yes | Yes | View and manage webhook endpoints under **Settings → Webhooks**. | -| **API keys** | No | N/A | Manage API keys in the AWS Console (**Claude Platform on AWS → API keys**). See [API key authentication](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#api-key-authentication). | -| **Members** | No | N/A | Not applicable. AWS IAM manages access. | -| **Billing** | Yes (limited) | No | Set an organization monthly spend limit; see [Spend limits](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#spend-limits). AWS Marketplace manages invoicing. View cost breakdowns on the Cost page. | -| **Claude Code** | No | N/A | View Claude Code usage on the Usage page. | +| Page | Available | Through AWS gateway | Notes | +| --------------------- | ------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Usage** | Yes | No | View token usage by model, workspace, and dimension. Data can take a few minutes to appear after a request. | +| **Cost** | Yes | No | View cost breakdowns by model and workspace. AWS Cost Explorer shows the aggregated [Claude Consumption Unit (CCU)](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#billing) line item. | +| **Rate limits** | Yes | No | View rate limits (read-only). Tier increases go through your Anthropic account representative; see [Rate limits and quotas](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#rate-limits-and-quotas). | +| **Workspaces** | Yes | Yes (except spend limits) | View per-region workspaces. With the Admin role, you can also create, rename, and archive workspaces, and set per-workspace [spend limits](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#spend-limits). | +| **Encryption keys** | Yes | Yes | Under **Settings → Encryption keys**, register AWS KMS keys for [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws) (Admin role). Attach a registered key to a workspace from that workspace's **Security** settings. | +| **Files** | Yes | Yes | View and manage uploaded files. | +| **Skills** | Yes | Yes | View and manage Agent Skills. | +| **Batches** | Yes | Yes | View and manage batch processing jobs. | +| **Agents** | Yes | Yes | View and manage agent definitions. | +| **Sessions** | Yes | Yes | View agent sessions and event history. | +| **Environments** | Yes | Yes | View and manage cloud sandbox configurations for sessions. | +| **Credential vaults** | Yes | Yes | View and manage credential vaults for session authentication. | +| **Memory stores** | Yes | Yes | View and manage persistent agent memory. | +| **Webhooks** | Yes | Yes | View and manage webhook endpoints under **Settings → Webhooks**. | +| **API keys** | No | N/A | Manage API keys in the AWS Console (**Claude Platform on AWS → API keys**). See [API key authentication](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#api-key-authentication). | +| **Members** | No | N/A | Not applicable. AWS IAM manages access. | +| **Billing** | Yes (limited) | No | Set an organization monthly spend limit; see [Spend limits](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#spend-limits). AWS Marketplace manages invoicing. View cost breakdowns on the Cost page. | +| **Claude Code** | No | N/A | View Claude Code usage on the Usage page. | ### Switching organizations
## Monitoring and logging -AWS CloudTrail can capture all requests to Claude Platform on AWS. Workspace, compliance, vault, and webhook operations are logged as Management events by default. Inference, batch, file, skill, model, user profile, and Claude Managed Agents operations (other than vaults and webhooks) are classified as Data events and require explicit data event logging configuration, which incurs additional CloudTrail charges. See the [IAM actions reference](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#route-to-action-mapping) for the full event type classification and the [AWS CloudTrail documentation](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/) for configuration details. +AWS CloudTrail can capture all requests to Claude Platform on AWS. Workspace, external key, compliance, vault, and webhook operations are logged as Management events by default. Inference, batch, file, skill, model, user profile, and Claude Managed Agents operations (other than vaults and webhooks) are classified as Data events and require explicit data event logging configuration, which incurs additional CloudTrail charges. See the [IAM actions reference](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#route-to-action-mapping) for the full event type classification and the [AWS CloudTrail documentation](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/) for configuration details. ### Request IDs
cli-sdks-libraries/cli/authentication Changed · +11 / -1 lines
To override the key for a single invocation, pass `--api-key`. To point at a different API host, set `ANTHROPIC_BASE_URL` or pass `--base-url`. +If you are using an API key scoped to multiple workspaces, such as a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types), you must [specify the workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) to run your command in. Do this by setting an `ANTHROPIC_WORKSPACE_ID` environment variable, which the CLI reads automatically, or by using the [`--workspace-id` flag](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/using#global-flags). The value must be a `wrkspc_...` ID; the literal `default` that the SDKs accept in `ANTHROPIC_WORKSPACE_ID` for [federated token exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#environment-variables) isn't valid here. + +```bash CLI +ant messages create \ + --workspace-id wrkspc_01... \ + --model claude-opus-5 \ + --max-tokens 1024 \ + --message '{role: user, content: "Hello, Claude"}' +``` + ## Check authentication status `ant auth status` prints the credential source the CLI selected (API key environment variable, OAuth login, federation, or profile), the active profile, the workspace the active token is bound to, and the configuration directory paths. Use it to diagnose why a workload picked the wrong credential or workspace.
Run [`ant auth status`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/authentication#check-authentication-status) to confirm which profile and workspace are active. <Note> - Profiles are only consulted when no API key is set. If `ANTHROPIC_API_KEY` is present in your environment, it overrides every profile and these commands all use whatever workspace that key is scoped to. Unset it before switching profiles. + Profiles are only consulted when no API key is set. If `ANTHROPIC_API_KEY` is present in your environment, it overrides every profile and these commands all use that key's workspace (or, for a multi-workspace key, the workspace set with `ANTHROPIC_WORKSPACE_ID` or `--workspace-id`). Unset it before switching profiles. </Note> ## Manage profiles
cli-sdks-libraries/cli/using Changed · +10 / -9 lines
### Global flags -| Flag | Description | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--profile` | Named profile to use for this invocation (equivalent to setting `ANTHROPIC_PROFILE`). See [Switch between workspaces](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/authentication#switch-between-workspaces). | -| `--format` | Output format: `auto`, `json`, `jsonl`, `yaml`, `pretty`, `raw`, `explore` | -| `--transform` | Filter or reshape the response with a [GJSON path](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/using#transform-output-with-gjson) | -| `-r`, `--raw-output` | Print string results without surrounding quotes, like `jq -r` | -| `--base-url` | Override the API base URL | -| `--debug` | Print full HTTP request and response to stderr | -| `--format-error`, `--transform-error` | Same as `--format` and `--transform` but applied to [error responses](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/scripting#inspect-errors) | +| Flag | Description | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `--profile` | Named profile to use for this invocation (equivalent to setting `ANTHROPIC_PROFILE`). See [Switch between workspaces](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/authentication#switch-between-workspaces). | +| `--format` | Output format: `auto`, `json`, `jsonl`, `yaml`, `pretty`, `raw`, `explore` | +| `--transform` | Filter or reshape the response with a [GJSON path](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/using#transform-output-with-gjson) | +| `-r`, `--raw-output` | Print string results without surrounding quotes, like `jq -r` | +| `--base-url` | Override the API base URL | +| `--workspace-id` | Optional. Workspace ID (`wrkspc_...`) to send as the `anthropic-workspace-id` header, for API keys with access to multiple workspaces (equivalent to setting `ANTHROPIC_WORKSPACE_ID`). See [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace). [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) commands take their own `--workspace-id`, which names the workspace they manage instead. | +| `--debug` | Print full HTTP request and response to stderr | +| `--format-error`, `--transform-error` | Same as `--format` and `--transform` but applied to [error responses](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/scripting#inspect-errors) | ## Output formats
cli-sdks-libraries/sdks/java Changed · +3 / -3 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java:2.57.0") + implementation("com.anthropic:anthropic-java:2.58.0") ``` </Tab>
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ``` </Tab>
.build(); ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ### Configuration options
get-api-key Changed · +12 / -4 lines
## Choose a key type
API keys for the Claude API (also called Anthropic API keys) live in the Claude Console. To view your existing keys or create a new one, go to [Settings → API keys](https://platform.claude.com/settings/keys). +## Choose a key type + +When you create a key, you choose its type, which determines what the key can do, where it works, and when it stops working. A **personal key** acts as you, and stops working if you leave an organization. A **service account key** represents a [service account](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#service-accounts) which can be used by workloads such as CI pipelines, production services, or agents. Use a personal key for your own development, and a service account key for anything shared. + +You can also create a **workspace key**, a legacy key without an owner: it belongs to the workspace you create it in and keeps working after its creator leaves. It is preferable to use a personal or service account key, as these stop working automatically when their associated account is removed from the organization. + ## Create an API key <Steps>
</Step> <Step title="Create a key"> - Click **Create key**, then give the key a name. You can also choose a [workspace](https://platform.claude.com/settings/workspaces) to scope the key to, and an expiration. + Click **Create key**, name the key, choose an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration), and set **Linked account** to yourself or a service account. You can also choose a [workspace](https://platform.claude.com/settings/workspaces) to scope the key to. </Step> <Step title="Copy and store the key">
</Step> </Steps> -If the **Create key** button is disabled, you may not have permission to create keys in that workspace. Ask an organization admin to grant you access or to create a key for you. +If the **Create key** button on the API keys page is disabled, your role may not allow you to create keys there. Ask an organization admin to change your role, or to create a service account key for your workload. ## Use your API key
export ANTHROPIC_API_KEY="sk-ant-api03-..." ``` -The [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) read `ANTHROPIC_API_KEY` automatically. Direct HTTP requests send the key in the `x-api-key` header. To make your first request, follow the [Quickstart](https://platform.claude.com/docs/en/get-started), and see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication) for the full picture, including short-lived credentials with Workload Identity Federation. +The [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) read `ANTHROPIC_API_KEY` automatically. Direct HTTP requests send the key in the `x-api-key` header. If your API key works on multiple workspaces, you must also send the `anthropic-workspace-id` header on each Claude API request, as shown in [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace). For the Admin API, see [API keys and the Admin API](https://platform.claude.com/docs/en/get-api-key#api-keys-and-the-admin-api). +To make your first request, follow the [Quickstart](https://platform.claude.com/docs/en/get-started), and see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication) for the full picture, including short-lived credentials with Workload Identity Federation. + ## API keys and the Admin API -The [Admin API](https://platform.claude.com/docs/en/api/admin) includes endpoints for managing your organization's API keys programmatically, such as [Retrieve API Key](https://platform.claude.com/docs/en/api/admin/api_keys/retrieve) and [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list). These endpoints are for organization admins automating key management. They require a separate [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), and they never return a key's secret value, only a partially redacted hint. +The [Admin API](https://platform.claude.com/docs/en/api/admin) includes endpoints for managing your organization's API keys programmatically, such as [Retrieve API Key](https://platform.claude.com/docs/en/api/admin/api_keys/retrieve) and [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list). These endpoints are for organization admins automating key management. They accept an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an OAuth token with the `org:admin` scope, or a personal or service account key that isn't scoped to a specific workspace; workspace keys don't work there. They never return a key's secret value, only a partially redacted hint. <Note> The Admin API can't recover a lost key or give you a key to call the Claude API with. To get a usable API key, create one in [Settings → API keys](https://platform.claude.com/settings/keys) in the Claude Console.
manage-claude/admin-api Changed · +12 / -9 lines
--- title: Admin API url: https://platform.claude.com/docs/en/manage-claude/admin-api -description: Manage organization members, workspaces, invites, and API keys programmatically with the Admin API, using an Admin API key or an `org:admin` OAuth token. +description: Manage organization members, workspaces, invites, and API keys programmatically with the Admin API, using an Admin API key, an `org:admin` OAuth token, or a personal or service account key. --- <Tip>
<Check> **The Admin API requires special access** - The Admin API accepts two credentials: + The Admin API accepts three credentials: * An **Admin API key** (starting with `sk-ant-admin...`) sent in the `x-api-key` header. Only organization members with the admin role can provision one. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys). * An **OAuth bearer token** with the `org:admin` scope sent in the `authorization: Bearer` header. Only members with the admin, owner, or primary owner role can obtain one. See [Obtain an OAuth bearer token](https://platform.claude.com/docs/en/manage-claude/admin-api#oauth-bearer-token). + * A **personal key** or **service account key** that isn't scoped to a specific workspace, sent in the `x-api-key` header. The key has the same permissions as the linked account. See [Key types](https://platform.claude.com/docs/en/manage-claude/authentication#key-types). </Check> <Note>
</Note> <Note> - **Claude Platform on AWS:** Only the workspace endpoints (create, get, list, update, and archive on `/v1/organizations/workspaces`) are available on Claude Platform on AWS. Organization members, workspace members, invites, API keys, and the usage, cost, and rate limit reports aren't. See [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws). + **Claude Platform on AWS:** Only the workspace endpoints (create, get, list, update, and archive on `/v1/organizations/workspaces`) and the external key endpoints (register, get, list, update, and delete on `/v1/organizations/external_keys`, for [CMEK](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws); there is no validate endpoint, because keys are validated when attached to a workspace) are available on Claude Platform on AWS. Organization members, workspace members, invites, API keys, and the usage, cost, and rate limit reports aren't. See [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws). </Note> ## Authentication -Authenticate with either credential. An Admin API key covers most endpoints. The service-account, federation-issuer, and federation-rule endpoints accept only an `org:admin` OAuth token. The following examples call the [organization info endpoint](https://platform.claude.com/docs/en/manage-claude/admin-api#accessing-organization-info) both ways. +Authenticate with any of the three credentials. An Admin API key covers most endpoints. The service-account, federation-issuer, and federation-rule endpoints accept only an `org:admin` OAuth token. Send a personal key or service account key in the `x-api-key` header, as you would an Admin API key. The following examples call the [organization info endpoint](https://platform.claude.com/docs/en/manage-claude/admin-api#accessing-organization-info) with an OAuth token and with an Admin API key. The Python, TypeScript, C#, Go, Java, PHP, and Ruby SDKs expose the Admin API under `client.beta.organization`, and the `ant` CLI under `ant beta:organization`. The examples on this page use the default client, which reads an Admin API key from `ANTHROPIC_API_KEY` or an OAuth bearer token from `ANTHROPIC_AUTH_TOKEN`. SDK list methods in Python, TypeScript, C#, Go, and Java return an iterator that fetches more pages on demand, so `limit` sets the page size, not the total. The PHP, Ruby, and curl examples return one page. In the CLI, `--limit` caps the results on the member, invite, workspace, workspace-member, and API-key lists. For each endpoint's parameters and responses, see the [Admin API reference](https://platform.claude.com/docs/en/api/admin).
## How the Admin API works -Authenticate with either credential from [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication), then manage the following resources: +Authenticate with any credential from [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication), then manage the following resources: * Organization members and their roles * Organization invites
### API keys -Monitor and manage [API keys](https://platform.claude.com/docs/en/api/admin/api_keys/list). Each key in the response includes its `expires_at` timestamp (`null` for keys without an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration)): +Monitor and manage [API keys](https://platform.claude.com/docs/en/api/admin/api_keys/list). Each key in the response includes its `expires_at` timestamp (`null` for keys without an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration)) and `principal`, the identity it acts as (see [Key types](https://platform.claude.com/docs/en/manage-claude/authentication#key-types)). For a personal key, `principal` is `{"type": "user_actor", "user_id": "user_..."}`; for a service account key, `{"type": "service_account_actor", "service_account_id": "svac_..."}`; and for a workspace key, `null`. Each key also has a `scope` object: `{"type": "workspace", "workspace_id": "wrkspc_..."}` for a key bound to one workspace, or `{"type": "organization"}` for a key that can work across any workspace the account has access to. The top-level `workspace_id` field is deprecated and is `null` both for keys bound to the Default Workspace and for keys without a workspace scope; use `scope` to tell them apart. Filtering the list by `workspace_id` with the Default Workspace's ID returns only keys bound to the Default Workspace; keys without a workspace scope aren't returned under any `workspace_id` filter. List the active API keys in a workspace:
### Service accounts -Create and manage service accounts (`svac_...`), the non-human identities that [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) tokens act as. These endpoints, like the federation-issuer and federation-rule endpoints, require an `org:admin` OAuth token. See [Manage WIF with the Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#service-accounts). +Create and manage service accounts (`svac_...`), the non-human identities that [service account keys](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) and [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) tokens act as. These endpoints, like the federation-issuer and federation-rule endpoints, require an `org:admin` OAuth token. See [Manage WIF with the Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#service-accounts). ### Federation issuers
<AccordionGroup> <Accordion title="What permissions are needed to use the Admin API?"> - The Admin API accepts either an Admin API key (starting with `sk-ant-admin`) or an OAuth bearer token with the `org:admin` scope. Only organization members with the admin role can provision Admin API keys, and only members with the admin, owner, or primary owner role can obtain `org:admin` tokens. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication). + The Admin API accepts an Admin API key (starting with `sk-ant-admin`), an OAuth bearer token with the `org:admin` scope, or a personal key or service account key that isn't scoped to a specific workspace. Only organization members with the admin role can provision Admin API keys, and only members with the admin, owner, or primary owner role can obtain `org:admin` tokens. A personal key or service account key has the same permissions as the linked account. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication). </Accordion> <Accordion title="Can I create new API keys through the Admin API?">
</Accordion> <Accordion title="What happens to API keys when removing a user?"> - They're unaffected. API keys belong to the organization, not to individual users. + Behavior depends on the [key type](https://platform.claude.com/docs/en/manage-claude/authentication#key-types). + + Personal keys stop working when their user is removed from the organization. Service account keys stop working if their service account is archived, but continue to work even if the user that created them is removed. Workspace API keys continue to work. In the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), each key is bound to the member who created it and stops working when that member is removed. </Accordion> <Accordion title="Can organization admins be removed through the API?">
manage-claude/authentication Changed · +245 / -8 lines
### Key types ### Create and use a key ### Select a workspace ### Replacing workspace API keys
| Method | Credential | Best for | | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| [API key](https://platform.claude.com/docs/en/manage-claude/authentication#api-keys) | Static `sk-ant-api...` secret in the `x-api-key` header | Local development, prototyping, scripts, and single-tenant servers where you control secret storage | +| [API key](https://platform.claude.com/docs/en/manage-claude/authentication#api-keys) | Static `sk-ant-api...` secret in the `x-api-key` header | Local development, prototyping, scripts, and servers where you control secret storage | | [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/authentication#workload-identity-federation) | Short-lived bearer token exchanged from your identity provider's identity token | Production workloads on cloud platforms (AWS, Google Cloud, Azure), CI/CD pipelines, and Kubernetes, where you want to eliminate static secrets | | [App Attest](https://platform.claude.com/docs/en/manage-claude/authentication#app-attest) | Short-lived access token issued to a genuine, attested installation of your registered iOS or macOS app | iOS and macOS apps distributed to end users, where the app calls the Claude API directly with no back end or proxy | -API keys and Workload Identity Federation grant the same access to Claude API endpoints. Choose API keys to get started quickly, and move to Workload Identity Federation when your workload already has a platform-issued identity you can federate. Use App Attest for iOS and macOS apps you distribute to end users. +API keys and Workload Identity Federation grant the same access to Claude API endpoints. Choose API keys to get started quickly: a personal key for your own development, or a service account key for anything shared. Move to Workload Identity Federation when your workload already has a platform-issued identity you can federate. Use App Attest for iOS and macOS apps you distribute to end users. ## API keys -API keys are static secrets that you generate in the Claude Console and pass on every request. +API keys are static secrets that you generate in the Claude Console and send on every request in the `x-api-key` header. -* **Create a key:** Go to [Settings → API keys](https://platform.claude.com/settings/keys) in the Claude Console. You choose an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) as part of creation. Use [workspaces](https://platform.claude.com/settings/workspaces) to scope keys by project or environment. -* **Send the key:** Set the `x-api-key` header on direct HTTP requests, or set the `ANTHROPIC_API_KEY` environment variable and the [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) pick it up automatically. +### Key types +When you create a key, you choose its type, which determines what the key can do, where it works, and when it stops working: + +| Key type | Acts as | Works in | Stops working when | +| -------------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Personal key** | You, the user, with your roles and permissions | Either a single workspace or the workspaces where your role allows API use, chosen when the key is created | You lose access to the organization or, for a single-workspace key, to that workspace. Personal keys are archived when you are removed from the organization. If you are re-invited, create new keys; archived keys are not restored | +| **Service account key** | A [service account](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#service-accounts) | Either a single workspace or anything the service account has access to, chosen when the key is created. A service account has access to the Default Workspace and to workspaces it has been added to | The service account is archived or, for a single-workspace key, is removed from that workspace | +| **Workspace key** (legacy) | No one: it belongs to the workspace it was created in | That workspace | It expires, is disabled or deleted, or its workspace is archived, regardless of whether its creator leaves the organization | + +Personal keys and service account keys are identity-backed: each belongs to a user or service account your organization already manages, and every request acts as that identity. When that identity is removed from the organization, the key stops working. This means that keys won't accidentally outlive the people or workloads that own them. Prefer them over workspace keys for new integrations. + +Use a personal key for your own development and scripts. A shared personal key acts as one person and breaks when they leave. For shared or automated workloads (CI, production services), have an organization admin create a service account so the workload has its own identity. + +Workspace API keys still work but should be considered legacy; identity-backed keys or [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) are preferred. To migrate, see [Replacing workspace API keys](https://platform.claude.com/docs/en/manage-claude/authentication#replacing-workspace-api-keys). + +### Create and use a key + +* **Create a key:** Go to [Settings → API keys](https://platform.claude.com/settings/keys) in the Claude Console and click **Create key**. Name the key and choose an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration). Set **Linked account** to yourself for a personal key, or to a service account for a key shared across multiple users. You can also scope the key to a specific workspace, which lets you skip setting a workspace ID manually in future requests. +* **Use the key:** Set the `x-api-key` header on direct HTTP requests, or set the `ANTHROPIC_API_KEY` environment variable and the [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) pick it up automatically. + ```http POST /v1/messages x-api-key: YOUR_API_KEY
content-type: application/json ``` -Store API keys in a secrets manager, rotate them periodically, and revoke any key you suspect has leaked. You can also set an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create a key to limit how long a leaked credential stays usable. +Store API keys in a secrets manager, rotate them periodically, and disable or delete any key you suspect has leaked. On the [API keys page](https://platform.claude.com/settings/keys), **Disable** is reversible (the Admin API reports the key's `status` as `"inactive"`, and **Re-enable** returns it to `"active"`), while **Delete** is permanent: the key is archived and still appears in [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list) with `status: "archived"`. Expired keys can only be deleted. You can also set an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create a key to limit how long a leaked credential stays usable. <CodeGroup> ```bash cURL
``` </CodeGroup> +### Select a workspace + +API keys that are created for a specific workspace only work in that workspace, and API requests using these keys can omit the workspace ID. + +If your API key isn't scoped to a workspace, you must specify the workspace ID in the `anthropic-workspace-id` header for each request. See the following example for how to set this header in a request or in SDKs. + +The [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) accepts a personal key or service account key only if the key isn't scoped to a specific workspace. + +You can find a workspace's ID in the **ID** column of [Settings → Workspaces](https://platform.claude.com/settings/workspaces) in the Claude Console, or by calling the [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) endpoint. Neither lists the Default Workspace's ID: read it from the `anthropic-workspace-id` [response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response) of any request that runs there (for example, one made with a workspace key from the Default Workspace), or from `scope.workspace_id` on such a key in [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list). + +<CodeGroup> + ```bash cURL + # Required on every request for a multi-workspace key. + # Omit the anthropic-workspace-id header for a single-workspace key. + curl https://api.anthropic.com/v1/messages \ + -H "x-api-key: $ANTHROPIC_API_KEY" \ + -H "anthropic-version: 2023-06-01" \ + -H "anthropic-workspace-id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" \ + -H "content-type: application/json" \ + -d '{ + "model": "claude-opus-5", + "max_tokens": 1024, + "messages": [{"role": "user", "content": "Hello, Claude"}] + }' + ``` + + ```bash CLI + # Required on every command for a multi-workspace key. + # Omit --workspace-id for a single-workspace key. + ant messages create \ + --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \ + --model claude-opus-5 \ + --max-tokens 1024 \ + --message '{role: user, content: "Hello, Claude"}' + ``` + + ```python Python + client = Anthropic() # reads ANTHROPIC_API_KEY + + # Required on every request for a multi-workspace key. + # Omit extra_headers for a single-workspace key. + message = client.messages.create( + model="claude-opus-5", + max_tokens=1024, + messages=[{"role": "user", "content": "Hello, Claude"}], + extra_headers={"anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"}, + ) + print(message.content) + + # Or set it once for every request from this client: + workspace_client = Anthropic( + default_headers={"anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"}, + ) + ``` + + ```typescript TypeScript + const client = new Anthropic(); // reads ANTHROPIC_API_KEY + + // Required on every request for a multi-workspace key. + // Omit the second argument for a single-workspace key. + const message = await client.messages.create( + { + model: "claude-opus-5", + max_tokens: 1024, + messages: [{ role: "user", content: "Hello, Claude" }] + }, + { headers: { "anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" } } + ); + console.log(message.content); + + // Or set it once for every request from this client: + const workspaceClient = new Anthropic({ + defaultHeaders: { "anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" } + }); + ``` + + ```csharp C# + AnthropicClient client = new(); // reads ANTHROPIC_API_KEY + + MessageCreateParams parameters = new() + { + Model = Model.ClaudeOpus5, + MaxTokens = 1024, + Messages = [new() { Role = Role.User, Content = "Hello, Claude" }], + }; + + // Required on every request for a multi-workspace key. + // Call client.Messages.Create(parameters) directly for a single-workspace key. + var message = await client + .WithOptions(options => + options with + { + ExtraHeaders = new Dictionary<string, string> + { + ["anthropic-workspace-id"] = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ", + }, + } + ) + .Messages.Create(parameters); + Console.WriteLine(message); + + // Or set it once for every request from this client: + AnthropicClient workspaceClient = new(new ClientOptions + { + ExtraHeaders = new Dictionary<string, string> + { + ["anthropic-workspace-id"] = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ", + }, + }); + ``` + + ```go Go + client := anthropic.NewClient() // reads ANTHROPIC_API_KEY + + // Required on every request for a multi-workspace key. + // Omit the option for a single-workspace key. + message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ + Model: anthropic.ModelClaudeOpus5, + MaxTokens: 1024, + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")), + }, + }, option.WithHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")) + if err != nil { + log.Fatal(err) + } + fmt.Println(message.Content) + + // Or set it once for every request from this client: + workspaceClient := anthropic.NewClient( + option.WithHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"), + ) + ``` + + ```java Java + AnthropicClient client = AnthropicOkHttpClient.fromEnv(); // reads ANTHROPIC_API_KEY + + // Required on every request for a multi-workspace key. + // Omit putAdditionalHeader for a single-workspace key. + Message message = client.messages().create(MessageCreateParams.builder() + .model(Model.CLAUDE_OPUS_5) + .maxTokens(1024) + .addUserMessage("Hello, Claude") + .putAdditionalHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ") + .build()); + + IO.println(message.content()); + + // Or set it once for every request from this client: + AnthropicClient workspaceClient = AnthropicOkHttpClient.builder() + .fromEnv() + .putHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ") + .build(); + ``` + + ```php PHP + $client = new Client(); // reads ANTHROPIC_API_KEY + + // Required on every request for a multi-workspace key. + // Omit requestOptions for a single-workspace key. + $message = $client->messages->create( + model: Model::CLAUDE_OPUS_5, + maxTokens: 1024, + messages: [['role' => 'user', 'content' => 'Hello, Claude']], + requestOptions: [ + 'extraHeaders' => ['anthropic-workspace-id' => 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ'], + ], + ); + + echo json_encode($message->content), PHP_EOL; + ``` + + ```ruby Ruby + client = Anthropic::Client.new # reads ANTHROPIC_API_KEY + + # Required on every request for a multi-workspace key. + # Omit request_options for a single-workspace key. + message = client.messages.create( + model: Anthropic::Model::CLAUDE_OPUS_5, + max_tokens: 1024, + messages: [{role: "user", content: "Hello, Claude"}], + request_options: {extra_headers: {"anthropic-workspace-id" => "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"}} + ) + + puts message.content + ``` +</CodeGroup> + +If a request made with a key that isn't scoped to a workspace omits the header, the API returns a 400 `invalid_request_error`: + +```json JSON +{ + "type": "error", + "error": { + "type": "invalid_request_error", + "message": "anthropic-workspace-id is required when authenticating with an identity-linked API key; send the id of the workspace this request acts in." + }, + "request_id": "req_011CSHoEeqs5C35K2UUqR7Fy" +} +``` + +A header value that isn't a valid workspace ID returns a 400 `invalid_request_error` with the message `anthropic-workspace-id header must be a valid workspace ID.` If the workspace doesn't exist, or the key's user or service account doesn't have access to it, the API returns a 404 `not_found_error` with the message ``Workspace `<id>` not found.``, the same response as for any unknown workspace. + +Workload Identity Federation selects a workspace at token exchange instead; see the [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference) for details. + ### Key expiration When you create an API key from the [API keys page](https://platform.claude.com/settings/keys) in the Claude Console, you choose an expiration: a preset (3 hours, 1 day, 7 days, or 30 days), a custom duration, or **Never** for keys you store in a secrets manager and rotate yourself. If your organization has a maximum expiration policy, the Console limits presets and custom durations to the policy maximum, and **Never** is unavailable. Existing keys keep their current behavior; expiration is set at creation time and cannot be changed afterward. The same expiration choice applies when you [create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) in the Claude Console.
The Console API keys table shows each key's expiration, and the Admin API reports each key's `expires_at` timestamp on the [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list) and [Retrieve API Key](https://platform.claude.com/docs/en/api/admin/api_keys/retrieve) endpoints, so you can audit and rotate keys before they expire. The field is `null` for keys without an expiration. -Expiration limits the lifetime of a leaked credential, but it is not a substitute for secret hygiene. Regardless of expiration, store keys in a secrets manager and revoke any key you suspect has leaked. +Expiration limits the lifetime of a leaked credential, but it is not a substitute for secret hygiene. Regardless of expiration, store keys in a secrets manager and disable or delete any key you suspect has leaked. + +### Replacing workspace API keys + +If you have a workspace key, you may want to replace it with [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/wif-reference) or a personal or service account key. This provides better security and observability. + +See [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/wif-reference) for details on configuring Workload Identity Federation, which is preferred over long-lived keys. + +To replace a workspace key with a personal or service account key: + +1. **Decide the key type.** Your own tooling should use a personal key. A shared or unattended workload should use a service account key. +2. **Create a service account** if necessary. You may have to ask an organization admin to create one in [Settings → Service accounts](https://platform.claude.com/settings/service-accounts) and add it to the relevant workspace. +3. **Create the new key.** Create it specifically for the integration's workspace unless multiple workspaces are needed. +4. **Deploy the new key.** Replace the old key wherever the integration reads it, typically the `ANTHROPIC_API_KEY` environment variable or a secrets manager entry. For a multi-workspace key, also send the `anthropic-workspace-id` header as shown in [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace). +5. **Delete the old key.** Confirm that requests succeed, then delete the workspace key on the [API keys page](https://platform.claude.com/settings/keys). ## Workload Identity Federation
manage-claude/cmek Changed · +8 / -10 lines
Enabling CMEK is permanent. Anthropic keeps no copy of your key, so misconfiguration or key loss can permanently destroy your CMEK-protected data. If you are uncertain about any step, contact your Anthropic representative before applying changes. * **Permanent data loss:** If your encryption key is deleted, scheduled for deletion, or has its key material destroyed, Anthropic cannot recover your data. - * **Identifier verification is mandatory:** Granting key access to an incorrect or spoofed principal can expose your data to an unauthorized party. Always verify the Anthropic identifier against the published production identities in each configuration guide. Never trust an identifier provided over email, chat, or any onboarding channel. + * **Identifier verification is mandatory:** Granting key access to an incorrect or spoofed principal can expose your data to an unauthorized party. Always verify the Anthropic identifier against the published production identities in each configuration guide. On Claude Platform on AWS, that identity is the AWS service principal published in the [AWS KMS guide](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws). Never trust an identifier provided over email, chat, or any onboarding channel. </Warning> ## How it works -Only Organization Admins (on Claude Platform) or Owners and the Primary Owner (on Claude Enterprise) can configure CMEK. On Claude Platform, CMEK is scoped per workspace and configured with the Admin API. On Claude Enterprise, CMEK is scoped per organization and configured in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls). On either product, CMEK protects data written after your key takes effect. Existing data (prior chats, files, and sessions) remains encrypted with Anthropic-managed keys and is not re-encrypted under your key. +Only Organization Admins (on Claude Platform; the Admin role on Claude Platform on AWS) or Owners and the Primary Owner (on Claude Enterprise) can configure CMEK. On Claude Platform, CMEK is scoped per workspace and configured with the Admin API (on Claude Platform on AWS, in the Claude Console or through the IAM-authorized external key and workspace endpoints). On Claude Enterprise, CMEK is scoped per organization and configured in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls). On either product, CMEK protects data written after your key takes effect. Existing data (prior chats, files, and sessions) remains encrypted with Anthropic-managed keys and is not re-encrypted under your key. On Claude Platform, Anthropic recommends attaching your key to a new workspace before you send any requests to that workspace. If you attach a key to a workspace that already receives requests, your key can take up to a day to take effect. Data written before then, like existing data, is encrypted with Anthropic-managed keys and is not re-encrypted. CMEK configuration events appear in the [Compliance API Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed). The key operations Anthropic performs against your key (such as wrapping and unwrapping data keys) do not appear in the Compliance API; they appear in your cloud provider's audit logs. -Anthropic calls your key management service from its standard public IP range. If you restrict access to your key management service by IP, allow the addresses listed in [IP addresses](https://platform.claude.com/docs/en/api/ip-addresses). +Anthropic calls your key management service from its standard public IP range. If you restrict access to your key management service by IP, allow the addresses listed in [IP addresses](https://platform.claude.com/docs/en/api/ip-addresses). On Claude Platform on AWS, don't rely on IP-based restrictions for your key; scope access with the key policy described in the [AWS KMS guide](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws) instead. ## Prerequisites * Permissions to create encryption keys and manage key access in the account, project, or subscription that will host the encryption key. -* An Organization Admin role in the Claude Console on Claude Platform, or an Owner or Primary Owner role on Claude Enterprise. +* An Organization Admin role in the Claude Console on Claude Platform (the Admin role on Claude Platform on AWS), or an Owner or Primary Owner role on Claude Enterprise. * Data retention configuration: CMEK is allowed with [Zero data retention (ZDR)](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) for both Claude Platform and Claude Enterprise. ## Availability and regions -CMEK is currently available in US regions only, and all encryption operations are processed in US regions. +Except on Claude Platform on AWS (covered at the end of this section), CMEK is currently available in US regions only, and all encryption operations are processed in US regions. For minimal latency, choose a region close to Anthropic's US infrastructure: -On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), CMEK is available with AWS KMS keys only; Google Cloud KMS and Azure Key Vault keys cannot be registered. Create and attach keys in the Claude Console; the `external_keys` API endpoints are not currently available on Claude Platform on AWS. There is no separate validation step: the key is implicitly validated when you attach it to a workspace (the attach call performs an encrypt/decrypt round), so a key policy problem surfaces at attach time rather than at registration. The key must be in the same AWS region as the workspace it is attached to. - -For minimal latency, choose a region close to Anthropic's US infrastructure: - | Provider | Recommended regions | | ------------ | --------------------------- | | AWS | `us-east-2` |
| Google Cloud | `us-central1`, `us-east5` | | Azure | `northcentralus`, `eastus2` | +On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), CMEK is available with AWS KMS keys only; Google Cloud KMS and Azure Key Vault keys cannot be registered. These region recommendations do not apply there: the key must be a single-region KMS key in the same AWS account and region as the workspace it is attached to, and its key policy must grant access to an AWS service principal rather than Anthropic's IAM role; see [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws). Register and attach keys in the Claude Console; the external key endpoints are also available on Claude Platform on AWS, authorized through [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys). There is no separate validation step: the key is implicitly validated when you attach it to a workspace (the attach call performs an encrypt/decrypt round), so a key policy problem surfaces at attach time rather than at registration. + ## What CMEK protects What CMEK covers depends on which product you use.
<CardGroup cols={3}> <Card href="https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms" title="AWS KMS"> - Create an AWS KMS key with a cross-account key policy, then register and validate it. + Create an AWS KMS key with a key policy that grants Anthropic access, then register it. </Card> <Card href="https://platform.claude.com/docs/en/manage-claude/cmek-google-cloud-kms" title="Google Cloud KMS">
manage-claude/cmek-aws-kms Changed · +113 / -5 lines
## Set up CMEK on Claude Platform on AWS ### Prerequisites ### Create the KMS key ### Register and attach the key
Enabling CMEK is permanent. If your KMS key is deleted or disabled, Anthropic cannot recover the data encrypted under it. Review the [warnings and limitations](https://platform.claude.com/docs/en/manage-claude/cmek) before you begin. </Warning> +<Note> + **Claude Platform on AWS:** On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), your key policy grants access to an AWS service principal instead of Anthropic's IAM role, there is no separate validation step, and you register and attach the key in the Claude Console. Follow [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws) on this page instead of the steps in the next sections. +</Note> + ## Prerequisites * An AWS account with permissions to create KMS keys and set key policies (`kms:CreateKey` and `kms:PutKeyPolicy`).
<Tabs> <Tab title="Claude Platform"> <Note> - **Finding your compartment ID:** Each workspace has a compartment ID that scopes its CMEK data. Find it in the Claude Console under **Workspace > Security > Encryption keys** (the **Compartment ID** field), or read the `compartment_id` field returned by the [Get Workspace](https://platform.claude.com/docs/en/api/admin-api/workspaces/get-workspace) endpoint. Substitute that value for `<compartment-uuid>` in the preceding key policy. + **Claude Platform on AWS:** The principal, key policy, and registration flow differ, and there is no separate validation step. Follow [Set up CMEK on Claude Platform on AWS](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#claude-platform-on-aws) instead of this tab. + </Note> + <Note> + **Finding your compartment ID:** Each workspace has a compartment ID that scopes its CMEK data. Find it in the Claude Console under **Workspace > Security**, under **Encryption key** (the **Compartment ID** field), or read the `compartment_id` field returned by the [Get Workspace](https://platform.claude.com/docs/en/api/admin-api/workspaces/get-workspace) endpoint. Substitute that value for `<compartment-uuid>` in the preceding key policy. + Key validation always sends the all-zeros compartment UUID (`00000000-0000-0000-0000-000000000000`) as the encryption context, because validation runs before the key is attached to any workspace. Live traffic sends the compartment ID of each attached workspace. Any `EncryptionContext` condition must allow the all-zeros value plus the compartment ID of every workspace the key is attached to. Validation also runs again whenever key setup is re-run, so keep the all-zeros entry in place permanently.
<Step title="Register the key with Anthropic"> Create an external key configuration through the Admin API. - <Note> - For organizations on [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), the external key endpoints are not yet available. Register and attach your key in the Claude Console instead. There is no separate validation step: the key is implicitly validated when you attach it to a workspace (the attach call performs an encrypt/decrypt round), so a key policy problem surfaces at attach time rather than at registration. - </Note> - <CodeGroup> ```bash cURL curl -sS "https://api.anthropic.com/v1/organizations/external_keys" \
On Claude Enterprise, CMEK applies to the whole organization, so there is no separate workspace attach step, and an organization can have only one key. </Tab> </Tabs> + +## Set up CMEK on Claude Platform on AWS + +On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), CMEK uses AWS KMS keys only, and setup differs from the preceding sections in these ways: + +* **Principal:** Your key policy grants access to the AWS service principal `aws-external-anthropic.amazonaws.com`. Anthropic's IAM role and account ID are not used, so the [ARN for Anthropic](https://platform.claude.com/docs/en/manage-claude/cmek-aws-kms#amazon-resource-name-arn-for-anthropic) does not apply. +* **Key requirements:** The key must be a symmetric KMS key with encrypt and decrypt usage, single-region, and in the same AWS account and region as the workspace you attach it to. Multi-region keys (key IDs that begin with `mrk-`) and alias ARNs are rejected; use the key ARN. +* **No separate validation step:** The key is validated when you attach it to a workspace. The attach call performs an encrypt/decrypt round against the key with that workspace's compartment ID as the encryption context, so a key policy problem surfaces at attach time rather than at registration. Unlike the Claude Platform policy earlier on this page, an `EncryptionContext` condition therefore needs no all-zeros entry. +* **Where you manage keys:** Register and attach keys in the Claude Console, signed in through AWS with the Admin role. The external key endpoints are also available on Claude Platform on AWS, authorized through [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys); there, a key is identified by its KMS key ARN rather than an `ekey_` ID. + +<Warning> + Use only this published service principal name. Never trust an identifier provided over email, chat, or any onboarding channel. +</Warning> + +### Prerequisites + +* The AWS account that hosts your Claude Platform on AWS organization, with permissions to create KMS keys and set key policies (`kms:CreateKey` and `kms:PutKeyPolicy`). +* The **Admin** role in the Claude Console for Claude Platform on AWS. See [Using the Claude Console](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws#using-the-claude-console). +* For the IAM principal you sign in to the Claude Console with: besides `aws-external-anthropic:AssumeConsole`, the [IAM actions](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#encryption-keys) for the operations you perform there, because the Encryption keys page and key attachment go through the AWS gateway. Registering a key is `RegisterKey` (with `ListKeys` and `GetKey` to view registrations), and attaching one is `UpdateWorkspace` or `CreateWorkspace`. The external key actions (and `CreateWorkspace`) are account-scoped, so grant them on `Resource: "*"`; a policy limited to workspace ARNs does not include them. +* For the IAM principal that attaches the key to a workspace (the identity you signed in to the Claude Console with): `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key. Your principal's access to the key is checked when you attach it, in addition to the service principal's. +* Optional, for the key picker in the Claude Console: `kms:ListKeys` and `kms:DescribeKey` for the principal you sign in with. Without them, paste the key ARN instead. + +### Create the KMS key + +The key policy has three statements: your account's root admin statement; a statement that lets the Claude Platform on AWS service principal encrypt, decrypt, and generate data keys; and a separate statement for `kms:DescribeKey`. Both service-principal statements carry a recommended `aws:SourceArn` condition: the service calls your key on behalf of a specific workspace and passes that [workspace's ARN](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions#service-details) as the source ARN, so the pattern shown limits the grant to workspaces in your own AWS account. `DescribeKey` is granted separately because it has no `EncryptionContext` parameter, so an `EncryptionContext` condition on that action would always deny. + +If you plan to use the optional `EncryptionContext` condition shown here, create the workspace first (without a key) and copy its compartment ID from the Claude Console under **Workspace > Security**, under **Encryption key** (the **Compartment ID** field), or from the `compartment_id` field returned by the [Get Workspace](https://platform.claude.com/docs/en/api/admin-api/workspaces/get-workspace) endpoint. Substitute it for `<compartment-uuid>`. Otherwise, delete the `StringEquals` entry from that statement's `Condition` block and keep the `ArnLike` entry. + +```bash +export YOUR_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) + +aws kms create-key \ + --region <workspace-region> \ + --description "Anthropic CMEK (Claude Platform on AWS)" \ + --key-usage ENCRYPT_DECRYPT \ + --policy "{ + \"Version\": \"2012-10-17\", + \"Statement\": [ + { + \"Sid\": \"AccountRootAdmin\", + \"Effect\": \"Allow\", + \"Principal\": {\"AWS\": \"arn:aws:iam::${YOUR_ACCOUNT}:root\"}, + \"Action\": \"kms:*\", + \"Resource\": \"*\" + }, + { + \"Sid\": \"AllowClaudePlatformOnAWSCrypto\", + \"Effect\": \"Allow\", + \"Principal\": {\"Service\": \"aws-external-anthropic.amazonaws.com\"}, + \"Action\": [\"kms:Encrypt\", \"kms:Decrypt\", \"kms:GenerateDataKey\"], + \"Resource\": \"*\", + \"Condition\": { + \"ArnLike\": { + \"aws:SourceArn\": \"arn:aws:aws-external-anthropic:*:${YOUR_ACCOUNT}:workspace/*\" + }, + \"StringEquals\": { + \"kms:EncryptionContext:anthropic:compartment_uuid\": [ + \"<compartment-uuid>\" + ] + } + } + }, + { + \"Sid\": \"AllowClaudePlatformOnAWSDescribe\", + \"Effect\": \"Allow\", + \"Principal\": {\"Service\": \"aws-external-anthropic.amazonaws.com\"}, + \"Action\": \"kms:DescribeKey\", + \"Resource\": \"*\", + \"Condition\": { + \"ArnLike\": { + \"aws:SourceArn\": \"arn:aws:aws-external-anthropic:*:${YOUR_ACCOUNT}:workspace/*\" + } + } + } + ] + }" +``` + +Capture `KeyMetadata.Arn` from the output. You need it when you register the key. + +Both conditions are optional hardening, and they compose. The `aws:SourceArn` condition can be written before any workspace exists; to pin the key to particular workspaces instead of your whole account, list their full workspace ARNs in place of the wildcard pattern, and to start without it, delete the `ArnLike` entry from both service-principal statements (removing a `Condition` block that this leaves empty). The `EncryptionContext` condition is also optional. Every encrypt, decrypt, and data-key call made for a workspace, including the attach-time check, carries that workspace's compartment ID as `anthropic:compartment_uuid`, so the condition lists the compartment ID of each workspace you attach the key to and needs no all-zeros entry. Adding it binds the key to the workspaces you list at the IAM layer as well. Because a compartment ID exists only once its workspace exists, the order is: create the workspace, put its compartment ID in the condition (at key creation, or later with `kms:PutKeyPolicy`), then attach the key. Before attaching the key to each additional workspace, add that workspace's compartment ID the same way. To start without it, delete the `StringEquals` entry from the `AllowClaudePlatformOnAWSCrypto` statement's `Condition` block; if you add it later, include the compartment ID of every workspace the key is already attached to. + +You can also create the key from the AWS Console: choose a symmetric key with the encrypt and decrypt key usage, a single-region key, and KMS key material origin, in the workspace's region. Leave key usage permissions empty in the Create-key wizard, then open the key's **Key policy** tab and replace the JSON with the policy shown here. + +### Register and attach the key + +<Steps> + <Step title="Register the key"> + In the Claude Console, open **Settings > Encryption keys** and click **Add key**. Enter a display name, then choose the key from the key picker or choose **Enter ARN manually** and paste the key ARN, and click **Add**. The picker lists the enabled, customer-managed, symmetric, single-region keys in your account in one of your organization's regions; for a key the picker doesn't list, enter the ARN. It lists keys only if the principal you signed in with can call `kms:ListKeys` and `kms:DescribeKey`. + </Step> + + <Step title="Attach the key to a workspace"> + Attach the key to a new workspace before you send any requests to that workspace. For a workspace that already receives requests, the key can take [up to a day to take effect](https://platform.claude.com/docs/en/manage-claude/cmek#how-it-works). In the Claude Console, open the workspace and, under **Security**, select the key in **Encryption key**, save, and confirm. You can also select a key when you create a workspace in the Claude Console, but only if your key policy does not yet name specific workspaces (no `EncryptionContext` condition, and the account-wide `aws:SourceArn` pattern rather than individual workspace ARNs), because the workspace's ID and compartment ID are assigned at creation. Once attached, a workspace's key can't be changed. + + This is when the key is validated: the attach call checks your principal's access to the key and performs an encrypt/decrypt round against it with the workspace's compartment ID as the encryption context, so a problem with either the key policy or your principal's permissions surfaces as an error on that call. If the attach fails with a KMS access error, check the following: + + * The key policy names the `aws-external-anthropic.amazonaws.com` service principal and grants `kms:Encrypt`, `kms:Decrypt`, and `kms:GenerateDataKey`, plus `kms:DescribeKey` in a separate statement that has no `EncryptionContext` condition. + * The `aws:SourceArn` condition matches this workspace's ARN (your account ID, and the workspace if you listed specific ARNs), and any `EncryptionContext` condition includes this workspace's compartment ID. + * The key is enabled, single-region, and in the same AWS account and region as the workspace. + * The principal you are signed in as has `kms:DescribeKey`, `kms:Encrypt`, and `kms:Decrypt` on the key. + * No service control policy or resource control policy in your AWS organization prevents the service principal or your principal from using the key. + * If the policy looks right and the attach still fails, find the denied `kms:` event in CloudTrail in the key's account (it shows the calling principal and, for cryptographic calls, the encryption context), then retry with the `aws:SourceArn` condition temporarily removed to tell a source-ARN mismatch apart from an encryption-context mismatch. + </Step> +</Steps> ## Terraform
agents-and-tools/mcp-tunnels/overview Changed · +1 / -1 lines
### Messages API -Pass the upstream MCP server's URL in the `mcp_servers` array, the same way as any other remote MCP server. The request body and `anthropic-beta` header follow the standard [MCP connector](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector) format; only the `url` is tunnel-specific. The following example uses the MCP connector's `mcp-client` beta header, which is separate from the `mcp-tunnels` beta used by the [Tunnels API](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/reference). Use an API key for the workspace the tunnel was created in (Console **Settings > API keys**). +Pass the upstream MCP server's URL in the `mcp_servers` array, the same way as any other remote MCP server. The request body and `anthropic-beta` header follow the standard [MCP connector](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector) format; only the `url` is tunnel-specific. The following example uses the MCP connector's `mcp-client` beta header, which is separate from the `mcp-tunnels` beta used by the [Tunnels API](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/reference). Make the request in the workspace the tunnel was created in by using an API key for that workspace or, if your key has access to multiple workspaces, by setting the [`anthropic-workspace-id` header](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) to that workspace. The URL's host is `<subdomain>.<your-tunnel-domain>`. The path depends on your upstream MCP server, not the tunnel: FastMCP's `streamable-http` transport serves at `/mcp`, and other servers may use `/` or a custom path (check the server's documentation). The proxy forwards the path untouched.
manage-claude/spend-limits-api Changed · +37 / -4 lines
### Temporarily raise a member's spend limit during an incident
For complete parameter details and response schemas, see [List spend limit increase requests](https://platform.claude.com/docs/en/api/admin/spend_limits/increase_requests/list) in the API reference. ```bash cURL -curl "https://api.anthropic.com/v1/organizations/spend_limit_increase_requests?status[]=pending&limit=50" \ +curl --globoff "https://api.anthropic.com/v1/organizations/spend_limit_increase_requests?status[]=pending&limit=50" \ --header "x-api-key: $ANTHROPIC_ADMIN_KEY" ```
## Example workflows -These workflows combine the Spend Limits API with the [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api) cost endpoints. The Analytics cost endpoints are designed for organization-wide spend reporting across a date range. `GET /spend_limits/effective` returns the cap that currently applies to each member. Start a sweep with Analytics to discover which members to look at, then read their current caps with `/effective`. +Some of these workflows combine the Spend Limits API with the [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api) cost endpoints. The Analytics cost endpoints are designed for organization-wide spend reporting across a date range. `GET /spend_limits/effective` returns the cap that currently applies to each member. Start a sweep with Analytics to discover which members to look at, then read their current caps with `/effective`. Spend Limits endpoints require the `spend_limits` scopes and Analytics cost endpoints require `read:analytics`; see [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api) for how to provision access. All monetary values on both are decimal strings in minor units (cents). Both APIs paginate with an opaque cursor. Set an explicit `limit` and page through `next_page` until it's `null` to cover the whole organization.
1. List pending requests: ```bash cURL - curl "https://api.anthropic.com/v1/organizations/spend_limit_increase_requests?status[]=pending&limit=100" \ + curl --globoff "https://api.anthropic.com/v1/organizations/spend_limit_increase_requests?status[]=pending&limit=100" \ --header "x-api-key: $ANTHROPIC_ADMIN_KEY" ```
2. For the top spenders (or everyone above a dollar threshold), fetch effective caps in batches: ```bash cURL - curl "https://api.anthropic.com/v1/organizations/spend_limits/effective?user_ids[]=user_01Ab...&user_ids[]=user_01Cd...&limit=100" \ + curl --globoff "https://api.anthropic.com/v1/organizations/spend_limits/effective?user_ids[]=user_01Ab...&user_ids[]=user_01Cd...&limit=100" \ --header "x-api-key: $ANTHROPIC_ADMIN_KEY" ```
2. Group rows by `actor.user_id`. For each member, sum the most recent seven days and the prior seven days. Flag members whose recent week exceeds the prior week by your chosen multiple (for example, three). Recent-day cost is provisional and can be revised upward; for repeatable comparisons, set `ending_at` at or before a previously returned `data_refreshed_at` (see [Data availability and freshness](https://platform.claude.com/docs/en/manage-claude/analytics-api#data-availability-and-freshness)). 3. Act on flagged members: adjust the cap with `POST /v1/organizations/spend_limits`, or reach out. + +### Temporarily raise a member's spend limit during an incident + +Give an incident responder room to work while an incident is open: raise their spend cap when the incident starts, and roll it back after the incident closes. Gate the raise on your incident management system, for example by requiring a live incident ID with the member assigned to it. + +1. Read the member's current cap, and record it for the rollback: + + ```bash cURL + curl --globoff "https://api.anthropic.com/v1/organizations/spend_limits/effective?user_ids[]=user_01AbCdEfGh&period[]=monthly" \ + --header "x-api-key: $ANTHROPIC_ADMIN_KEY" + ``` + +2. Raise the cap: + + ```bash cURL + curl --request POST "https://api.anthropic.com/v1/organizations/spend_limits" \ + --header "content-type: application/json" \ + --header "x-api-key: $ANTHROPIC_ADMIN_KEY" \ + --data '{"scope": {"type": "user", "user_id": "user_01AbCdEfGh"}, "amount": "500000", "period": "monthly"}' + ``` + +3. If responders need broader access during an incident, pre-provision an incident-responders group whose [custom role](https://platform.claude.com/docs/en/manage-claude/user-management#custom-roles) grants it, and add the member for the duration: + + ```bash cURL + curl --request POST "https://api.anthropic.com/v1/organizations/rbac_groups/rbac_group_01UvWxYzAbCdEfGhIjKlMn/members" \ + --header "content-type: application/json" \ + --header "x-api-key: $ANTHROPIC_ADMIN_KEY" \ + --data '{"user_id": "user_01AbCdEfGh"}' + ``` + + See [User management](https://platform.claude.com/docs/en/manage-claude/user-management#groups) for the group endpoints. + +4. When your incident system marks the incident closed, roll both changes back: restore the spend limit you recorded in step 1 (or delete the override with `DELETE /v1/organizations/spend_limits/{spend_limit_id}` if the member had none), and remove the member from the group with `DELETE /v1/organizations/rbac_groups/{group_id}/members/{user_id}`. ## Frequently asked questions
manage-claude/usage-cost-api Changed · +5 / -5 lines
* **Advanced analysis:** Perform deeper data analysis than what's available in Console <Check> - **Admin API key required.** These endpoints require an Admin API key, which is different from a standard Claude API key. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) to find where to create one for your organization type and which scopes to select. + **Admin API credentials required.** These endpoints are part of the Admin API. You can access them using an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an OAuth token with the `org:admin` scope, or a personal or service account key that isn't scoped to a workspace; workspace API keys don't work. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication) for details. </Check> Claude Enterprise organizations use an Analytics API key with a different API instead; see [Which API do you need?](https://platform.claude.com/docs/en/manage-claude/usage-cost-api#which-api-do-you-need).
Anthropic provides cost and usage reporting through two APIs, depending on which Claude product your organization manages: -| Your organization | API | Key type | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| Claude Console (Claude Platform) | The Usage and Cost Admin API described on this page | Admin API key (`sk-ant-admin01-...`) | -| Claude Enterprise (claude.ai) | The [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/api/admin/analytics) cost and usage endpoints | Analytics API key | +| Your organization | API | Key type | +| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| Claude Console (Claude Platform) | The Usage and Cost Admin API described on this page | Admin API key (`sk-ant-admin01-...`) or another [Admin API credential](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication) | +| Claude Enterprise (claude.ai) | The [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/api/admin/analytics) cost and usage endpoints | Analytics API key | Claude Enterprise parent organizations do not appear in Claude Console and carry no Admin API keys, so for them the Analytics API key is the only path to this data. See [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api) for how to create each key type and which plans the Claude Enterprise cost data applies to.
manage-claude/wif-reference Changed · +17 / -14 lines
The `oauth_scope` you set on a federation rule determines which Claude API endpoints the minted access token can call. -| Scope | Grants access to | -| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `workspace:developer` | All non-administrative Claude API endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models-list), [Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) and their sessions, [Files](https://platform.claude.com/docs/en/build-with-claude/files), and [Skills](https://platform.claude.com/docs/en/build-with-claude/skills-guide). This matches the access an API key issued for the same workspace has. | -| `workspace:inference` | The inference endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models-list), and the [OpenAI-compatible chat endpoint](https://platform.claude.com/docs/en/cli-sdks-libraries/libraries/openai-sdk). Use this for workloads that only need to call Claude and never need to manage Files, Skills, or other resources. | -| `workspace:manage_tunnels` | The [MCP tunnels API](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/reference#tunnels-api): create, list, and get tunnels, register and archive CA certificates, reveal and rotate the tunnel token, and archive tunnels. The Console's create-tunnel modal window locks this scope when you create a rule from it. | -| `org:admin` | Full access to the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) (organization members, invites, workspaces, API keys, and the rest). An OAuth `org:admin` token can only create or modify rules scoped to `workspace:developer` or `workspace:inference`, and cannot update an issuer that backs a rule with any other scope; see the [constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). | +| Scope | Grants access to | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `workspace:developer` | All non-administrative Claude API endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models-list), [Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) and their sessions, [Files](https://platform.claude.com/docs/en/build-with-claude/files), and [Skills](https://platform.claude.com/docs/en/build-with-claude/skills-guide). This matches the access a workspace API key in the same workspace has. | +| `workspace:inference` | The inference endpoints in the rule's workspace: [Messages](https://platform.claude.com/docs/en/api/messages) (including streaming and token counting), [Models](https://platform.claude.com/docs/en/api/models-list), and the [OpenAI-compatible chat endpoint](https://platform.claude.com/docs/en/cli-sdks-libraries/libraries/openai-sdk). Use this for workloads that only need to call Claude and never need to manage Files, Skills, or other resources. | +| `workspace:manage_tunnels` | The [MCP tunnels API](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/reference#tunnels-api): create, list, and get tunnels, register and archive CA certificates, reveal and rotate the tunnel token, and archive tunnels. The Console's create-tunnel modal window locks this scope when you create a rule from it. | +| `org:admin` | Full access to the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) (organization members, invites, workspaces, API keys, and the rest). An OAuth `org:admin` token can only create or modify rules scoped to `workspace:developer` or `workspace:inference`, and cannot update an issuer that backs a rule with any other scope; see the [constraints](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#permissions-and-constraints). | A request to an endpoint outside the token's scope returns HTTP 403. Finer-grained scopes (per resource, or read versus write) are not currently available.
### JWT verification -| Constraint | Detail | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Maximum size | The `assertion` JWT must be at most 16 KiB. | -| Signing algorithm | Only asymmetric algorithms (RSA and ECDSA families: ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512) are accepted. HMAC (`HS256`, `HS384`, `HS512`) and `none` are rejected. | -| Key ID | The JWT header must carry a `kid` that matches a key in the issuer's JWKS. Tokens without `kid` are rejected. | -| Required claims | `sub` must be present. `iat` must be present and not in the future. `exp` must be present and in the future. | -| Maximum lifetime | The token's lifetime (`exp` minus `iat`) must not exceed the issuer's configured maximum (1 hour by default, configurable for each issuer in the Claude Console). | -| Clock skew | A 30-second leeway is applied to `exp`, `nbf`, and `iat`. | +| Constraint | Detail | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Maximum size | The `assertion` JWT must be at most 16 KiB. | +| Signing algorithm | Only asymmetric algorithms (RSA and ECDSA families: ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512) are accepted. HMAC (`HS256`, `HS384`, `HS512`) and `none` are rejected. | +| Key ID | The JWT header must carry a `kid` that matches a key in the issuer's JWKS. Tokens without `kid` are rejected. | +| Required claims | `sub` must be present. `iat` must be present and not in the future. `exp` must be present and in the future. | +| Single use | An assertion that carries a `jti` claim can be exchanged only once per issuer: repeating an exchange with the same `jti` is rejected as a replay. The issuer's `check_jti` field (enabled by default) controls this check; assertions without a `jti` claim are not subject to it. See the [Federation issuers API reference](https://platform.claude.com/docs/en/api/admin/federation_issuers). | +| Maximum lifetime | The token's lifetime (`exp` minus `iat`) must not exceed the issuer's configured maximum (1 hour by default, configurable for each issuer in the Claude Console). | +| Clock skew | A 30-second leeway is applied to `exp`, `nbf`, and `iat`. | ## Rule matching semantics
<Tip> Start with the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console. Recent exchange attempts surface the issuer and rule that were evaluated, the JWT claims that were inspected, and which validation step failed, which usually short-circuits the following checks. </Tip> + +One common opaque failure is a replayed assertion: an assertion that carries a `jti` claim can be [exchanged only once](https://platform.claude.com/docs/en/manage-claude/wif-reference#jwt-verification), so a workload that re-sends the same JWT (a retry loop, or a refresh that re-reads an unrotated token) is rejected on the second exchange. The authentication history page shows these attempts with the reason `jti_reused`; the fix is to mint a fresh assertion for each exchange. If you still need to debug from the JWT itself, work through these checks in order:
manage-claude/workload-identity-federation Changed · +7 / -5 lines
### Service accounts -A **service account** (`svac_...`) is a named, non-human identity inside your Anthropic organization. It is the principal that a federated token acts as. Service accounts live at the organization level and become active in a workspace when you add them as members of that workspace. At exchange time, Anthropic checks that the federation rule's workspace matches one of the service account's workspace memberships; the minted token then follows that workspace's rate limits and usage attribution, the same as an API key. Unlike a human user, a service account has no email, no password, and no Console login. Every service account is implicitly a member of your organization's default workspace; add explicit memberships for any other workspace it should act in. +A **service account** (`svac_...`) is a named, non-human identity inside your Anthropic organization. It is the principal that a [service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) or a federated token acts as. Service accounts live at the organization level and become active in a workspace when you add them as members of that workspace. At exchange time, Anthropic checks that the federation rule's workspace matches one of the service account's workspace memberships; the minted token then follows that workspace's rate limits and usage attribution, the same as an API key. Unlike a human user, a service account has no email, no password, and no Console login. Every service account is implicitly a member of your organization's default workspace; add explicit memberships for any other workspace it should act in. To let an all-workspaces service account key act in a workspace, add the service account to that workspace. -The key distinction from an API key: an API key *is* a credential, while a service account *has* credentials minted for it on demand. You can audit which workloads acted as which service account. +The key distinction versus a workspace API key: a workspace API key *is* a credential, while a service account *has* credentials. You can more easily audit which workloads acted as which service account. ### Federation issuers
* **Match:** The conditions an incoming JWT must satisfy. You can match on a `subject_prefix` (for example, `system:serviceaccount:prod:worker`, or with a trailing `*` for a prefix match), an exact `audience`, a map of exact claim values, a [CEL](https://cel.dev/) `condition` expression for complex logic, or any combination. At least one of `subject_prefix`, `claims`, or `condition` must be set, and all configured matchers must pass for the JWT to be accepted. * **Target:** The service account the matched JWT maps to. -* **Authorization:** The OAuth `scope` granted on the minted token. The default is `workspace:developer`, which grants the same access as an API key issued for that workspace. Some products lock the scope when you create a rule from their flow; for example, the [MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview) create-tunnel modal creates rules scoped to `workspace:manage_tunnels`. See [OAuth scopes](https://platform.claude.com/docs/en/manage-claude/wif-reference#oauth-scopes). The rule also sets `token_lifetime_seconds` (60 to 86400, default 3600). +* **Authorization:** The OAuth `scope` granted on the minted token. The default is `workspace:developer`, which grants the same access as a workspace API key. Some products lock the scope when you create a rule from their flow; for example, the [MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview) create-tunnel modal creates rules scoped to `workspace:manage_tunnels`. See [OAuth scopes](https://platform.claude.com/docs/en/manage-claude/wif-reference#oauth-scopes). The rule also sets `token_lifetime_seconds` (60 to 86400, default 3600). A single issuer can have many rules: one per team, namespace, or permission level. Rules are evaluated by ID: the client specifies which rule to use in the exchange request, and Anthropic verifies the JWT satisfies that rule's match criteria. There is no implicit rule search.
1. **Configure federation in parallel.** Complete the [setup walkthrough](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#set-up-federation) and confirm the federation rule matches your workload's token. Leave the existing `ANTHROPIC_API_KEY` in place for now. 2. **Smoke-test which credential wins.** Run `ant auth status` from inside the workload (or inspect SDK debug logs). Because `ANTHROPIC_API_KEY` sits above the federation tiers in the precedence chain, the API key still wins at this stage. 3. **Unset `ANTHROPIC_API_KEY` everywhere it is injected.** Remove it from CI secrets, container environment, and shell profiles (see the preceding warning). Re-run `ant auth status` and confirm the federation source is now selected. -4. **Revoke the API key.** Once the workload is running on the federated token, delete the key in the Claude Console under **Settings → API keys**. +4. **Delete the API key.** Once the workload is running on the federated token, delete the key in the Claude Console under **Settings → API keys**. ## Token lifetime and refresh
* **Mandatory refresh** at expiry minus 30 seconds. A failed exchange at this point raises an error. The cached token is too close to expiry to be safe. Because the SDK re-reads `ANTHROPIC_IDENTITY_TOKEN_FILE` on every exchange, it transparently picks up rotated projected tokens (Kubernetes service-account tokens, for example, rotate well before their `exp`). + +By default, identity tokens that carry a `jti` claim are single-use: each exchange must present a JWT that has not been exchanged before, and re-presenting one fails with the reason `jti_reused` on the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history). If your workload fetches its own tokens from your identity provider, mint a fresh JWT for each exchange instead of reusing a cached one (retry loops are the common culprit). The same applies to a token read from `ANTHROPIC_IDENTITY_TOKEN_FILE`: the SDK re-reads the file on every exchange, so the file must hold a new token before each refresh. A refresh that re-reads an unrotated token, or a restarted process that re-presents a token it already exchanged, is rejected the same way. Rotating the token well within the minted token's lifetime keeps the file ahead of the refresh schedule; if your token source cannot rotate that often, you can disable `check_jti` for that issuer as a last resort (this removes replay protection for every rule on the issuer). See [JWT verification](https://platform.claude.com/docs/en/manage-claude/wif-reference#jwt-verification) for details. ## Identity providers
manage-claude/workspaces Changed · +23 / -15 lines
## How workspaces work -Every organization has a **Default Workspace** that cannot be renamed, archived, or deleted. When you create additional workspaces, you can assign API keys, members, and resource limits to each one. +Every organization has a **Default Workspace** that cannot be renamed, archived, or deleted. When you create additional workspaces, you can assign members, service accounts, API keys, and resource limits to each one. Key characteristics: * **Workspace identifiers** use the `wrkspc_` prefix (for example, `wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ`) * **Maximum 100 workspaces** per organization by default (archived workspaces don't count); contact your account team if you need more -* **Default Workspace** has a `wrkspc_` ID like any other workspace (returned in the [`anthropic-workspace-id` response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response) and accepted by [Get Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/retrieve)), but it doesn't appear in [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) results, and API keys, usage reports, and cost reports show `null` for its `workspace_id` -* **API keys** are scoped to a single workspace and can only access resources within that workspace +* **Default Workspace** has a `wrkspc_` ID like any other workspace (returned in the [`anthropic-workspace-id` response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response) and accepted by [Get Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/retrieve)), but it doesn't appear in [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) results, and API keys, usage reports, and cost reports show `null` for its `workspace_id`, as do all-workspaces API keys (an API key's `scope` field tells them apart; for a key bound to the Default Workspace it carries the real ID) +* **API keys** can be scoped to a single workspace. In this case, they can only access resources within that workspace. Some API keys can be granted permissions across multiple workspaces, and provide a [workspace ID header](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) to access resources within that workspace ### Claude Code workspace
The Claude Code workspace keeps Claude Code traffic separate from your other API workloads: * Claude Code mints a per-user API key in this workspace at sign-in. You cannot create keys in it manually from the Console. -* A Claude Code key stops working if its owner is removed from the workspace or organization, unlike standard workspace keys. +* A Claude Code key stops working if its owner is removed from the workspace or organization, unlike a workspace key. * Claude Code usage is rate-limited separately, and admins can cap its share of the organization's limits under [Settings > Workspaces](https://platform.claude.com/settings/workspaces). * It is the only workspace that supports per-user monthly spend limits.
* **Organization admins** automatically receive Workspace Admin access to all workspaces * **Organization billing members** automatically receive Workspace Billing access to all workspaces * **Organization users and developers** must be explicitly added to each workspace +* **Service accounts** are added to workspaces from the service account's page in [Settings → Service accounts](https://platform.claude.com/settings/service-accounts) or from the workspace's **Service accounts** tab <Note> The Workspace Billing role cannot be manually assigned. It's inherited from having the organization billing role.
To archive a workspace, click the ellipsis menu (**...**) and select **Archive**. Archiving: * Preserves historical data for reporting -* Deactivates the workspace and all associated API keys +* Deactivates the workspace and archives every API key created for it * Cannot be undone <Warning> - Archiving a workspace immediately revokes all API keys in that workspace. This action cannot be undone. If you archive the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), members of your organization can no longer sign in to Claude Code through Console billing. + Archiving a workspace archives every API key created for that workspace within seconds (they remain listed in the Admin API as archived), and multi-workspace keys can no longer act in it. This action cannot be undone. If you archive the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), members of your organization can no longer sign in to Claude Code through Console billing. </Warning> ### Using the Admin API
Programmatically manage workspaces using the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api). <Note> - Admin API endpoints require an Admin API key (starting with `sk-ant-admin...`) that differs from standard API keys. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) for how to provision one. + Admin API endpoints accept an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys), an `org:admin` OAuth token, or a personal or service account key that isn't scoped to a specific workspace. Workspace keys don't work there. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication). </Note> The following SDK and CLI examples construct the default client, which reads the Admin API key from the `ANTHROPIC_API_KEY` environment variable; the SDKs expose these endpoints under `client.beta.organization.workspaces`. SDK list methods fetch further pages on demand, so `limit` sets the page size; the PHP, Ruby, and curl examples return one page.
## API keys and resource scoping -API keys are scoped to a specific workspace. When you create an API key in a workspace, it can only access resources within that workspace. +Every request runs in exactly one workspace and can only access resources within that workspace. Which workspace depends on the [key type](https://platform.claude.com/docs/en/manage-claude/authentication#key-types): +* A **workspace key** (a legacy key without an owner) belongs to the workspace it was created in and always runs there. +* A **personal key** or **service account key** acts as its user or service account. A single-workspace key always runs in the workspace chosen when it was created. A multi-workspace key runs in the workspace named by each request's `anthropic-workspace-id` header. Accounts must have access to the workspace to use it. + Resources scoped to workspaces include: * **Files** created through the [Files API](https://platform.claude.com/docs/en/build-with-claude/files)
* **Message Batches** created through the [Batch API](https://platform.claude.com/docs/en/build-with-claude/batch-processing) * **Skills** created through the [Skills API](https://platform.claude.com/docs/en/build-with-claude/skills-guide) -Some resources cannot be managed with a workspace API key: +Some resources are managed differently: -* **[MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview)** are managed with a `workspace:manage_tunnels` OAuth token obtained through [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation), not a workspace API key. Tunnels are created in a workspace, and the Console **MCP tunnels** list and the Managed Agent server picker show tunnels in the current workspace only; the cap of 10 active tunnels applies organization-wide. Tunnel management requires a role with tunnel management permissions; organization developers can view but not change them. -* **Workspaces** themselves and **organization members** are managed at the organization level through the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api), which requires an Admin API key. +* **[MCP tunnels](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview)** are managed with a `workspace:manage_tunnels` OAuth token obtained through [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation), not an API key. Tunnels are created in a workspace, and the Console **MCP tunnels** list and the Managed Agent server picker show tunnels in the current workspace only; the cap of 10 active tunnels applies organization-wide. Tunnel management requires a role with tunnel management permissions; organization developers can view but not change them. +* **Workspaces** themselves and **organization members** are managed at the organization level through the [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api), using an Admin API key, an `org:admin` OAuth token, or a personal or service account key that isn't scoped to a specific workspace. To look up your organization's workspace IDs, call the [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) endpoint or find them in the [Claude Console](https://platform.claude.com/settings/workspaces).
With the workspace ID from a response, you can: * Confirm which workspace's usage, cost, and [rate limits](https://platform.claude.com/docs/en/api/rate-limits) the request counted toward -* Match it against the `workspace_id` field in [Usage and Cost API](https://platform.claude.com/docs/en/manage-claude/usage-cost-api) reports and on [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) objects such as API keys (both report `null` for the Default Workspace) +* Match it against the `workspace_id` field in [Usage and Cost API](https://platform.claude.com/docs/en/manage-claude/usage-cost-api) reports and on [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) objects such as API keys (both report `null` for the Default Workspace, as API keys also do for all-workspaces keys; an API key's `scope` field tells the two apart and, for a key bound to one workspace, carries that workspace's real ID) * Check whether it's your Default Workspace's ID by passing it to [Get Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/retrieve) with an [Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys): the Default Workspace comes back with `"name": "Default"`, even though [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) omits it * Open that workspace in the [Console](https://platform.claude.com/settings/workspaces) to find the request's resources, such as sessions, files, message batches, and skills
<AccordionGroup> <Accordion title="What's the Default Workspace?"> - Every organization has a "Default Workspace" that cannot be renamed, archived, or deleted. Like every workspace, it has a `wrkspc_` ID: the API returns it in the [`anthropic-workspace-id` response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response), and you can pass it to [Get Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/retrieve) and [Update Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/update). It has no member list of its own, because access to it follows each member's organization role. It doesn't appear in [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) results, and API keys, usage reports, and cost reports that belong to it show `null` for `workspace_id`. + Every organization has a "Default Workspace" that cannot be renamed, archived, or deleted. Like every workspace, it has a `wrkspc_` ID: the API returns it in the [`anthropic-workspace-id` response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response), and you can pass it to [Get Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/retrieve) and [Update Workspace](https://platform.claude.com/docs/en/api/admin/workspaces/update). It has no member list of its own, because access to it follows each member's organization role. It doesn't appear in [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) results, and API keys, usage reports, and cost reports that belong to it show `null` for `workspace_id`, as do all-workspaces API keys; an API key's `scope` field tells the two apart and, for a key that belongs to the Default Workspace, carries its real ID. </Accordion> <Accordion title="What's the Claude Code workspace?">
</Accordion> <Accordion title="What happens to API keys when a user is removed from a workspace?"> - API keys persist in their current state as they are scoped to the organization and workspace, not to individual users. The exception is the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), where each key is bound to the member who created it and stops working when that member is removed. + Behavior depends on the [key type](https://platform.claude.com/docs/en/manage-claude/authentication#key-types). + + A personal or service account key stops working in a workspace shortly after its user or service account is removed from it. A service account key keeps working even if the user who created it is removed. Workspace API keys continue to work. In the [Claude Code workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#claude-code-workspace), each key is bound to the member who created it and stops working when that member is removed. + + Personal keys are archived when their user is removed from the organization. If the user is re-invited, they need to create new keys; archived keys are not restored. </Accordion> </AccordionGroup>
release-notes/overview Changed · +4 / -0 lines
### August 27, 2026
For updates to Claude Code, see the [complete CHANGELOG.md](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) in the `claude-code` repository. </Tip> +### August 27, 2026 + +* You can now create **personal keys** and **service account keys** in the Claude Console. They act as you or as a [service account](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#service-accounts), with the same permissions, and stop working when the linked account is removed from an organization. This lets organization admins more easily track usage for each account, and ensure key usage is legitimate. These API keys can be scoped to a specific workspace or [work on admin endpoints and across any workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) the account has access to. Workspace API keys remain supported as a legacy option. See [API keys](https://platform.claude.com/docs/en/manage-claude/authentication#api-keys) for more information. + ### August 26, 2026 * The [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) session endpoints are out of beta for Cowork and Claude Code sessions. See [Retrieve session transcripts](https://platform.claude.com/docs/en/manage-claude/compliance-sessions).
agents-and-tools/mcp-connector Changed · +2 / -2 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java-mcp:2.57.0") + implementation("com.anthropic:anthropic-java-mcp:2.58.0") ``` </Tab>
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java-mcp</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ``` </Tab>