Claude apps gateway spend limits changedclaude-apps-gateway-spend-limits
Nearest release: v2.1.308, published 3 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 22 Oct 2026 00:33 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 23 Oct 2026 19:07 UTC.
Upstream edited
Recorded here
Lines+21added
Lines−21removed
From line
2
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits12to this page, all time
The whole hunk
from line 2, old and new numbered
/
from line 2
22
33> Cap each developer's spend through the Claude apps gateway by day, week, or month. Set limits with an Admin API and the gateway enforces them live on every request.
44
5Spend limits cap how much each developer can spend through your [Claude apps gateway](/docs/en/claude-apps-gateway) in a given day, week, or month. When a developer passes their cap, the gateway returns `429` on their next request and blocks them until the period resets or an admin raises the cap. Use spend limits to give each developer, group, or the whole organization a ceiling on a credential everyone shares.
5Spend limits cap how much each developer can spend through your [Claude apps gateway](https://code.claude.com/docs/en/claude-apps-gateway) in a given day, week, or month. When a developer passes their cap, the gateway returns `429` on their next request and blocks them until the period resets or an admin raises the cap. Use spend limits to give each developer, group, or the whole organization a ceiling on a credential everyone shares.
66
7By default, a Claude apps gateway forwards all inference through one shared upstream credential, so your provider's bill attributes everything to that credential, not to individual developers. On Amazon Bedrock, [per-developer AWS cost attribution](/docs/en/claude-apps-gateway-config.md#per-developer-aws-cost-attribution) changes this. Without per-developer limits, one runaway agent fleet can spend the organization's entire commitment. Spend limits are the gateway's per-developer view and circuit breaker on top of that shared bill.
7By default, a Claude apps gateway forwards all inference through one shared upstream credential, so your provider's bill attributes everything to that credential, not to individual developers. On Amazon Bedrock, [per-developer AWS cost attribution](https://code.claude.com/docs/en/claude-apps-gateway-config.md#per-developer-aws-cost-attribution) changes this. Without per-developer limits, one runaway agent fleet can spend the organization's entire commitment. Spend limits are the gateway's per-developer view and circuit breaker on top of that shared bill.
88
99## Set a cap
1010
11With the [`admin:`](/docs/en/claude-apps-gateway-config#admin) block configured in `gateway.yaml`, the gateway serves an admin API at `/v1/organizations/spend_limits` and enforces caps live on every inference request. Caps themselves are set through that API, not in `gateway.yaml`; each `POST /v1/organizations/spend_limits` request creates or replaces one cap from `{scope, amount, period}`. The API mirrors the wire shapes of Anthropic's public [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) spend-limits endpoints, so an HTTP client written against that contract can target the gateway by changing its base URL.
11With the [`admin:`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin) block configured in `gateway.yaml`, the gateway serves an admin API at `/v1/organizations/spend_limits` and enforces caps live on every inference request. Caps themselves are set through that API, not in `gateway.yaml`; each `POST /v1/organizations/spend_limits` request creates or replaces one cap from `{scope, amount, period}`. The API mirrors the wire shapes of Anthropic's public [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) spend-limits endpoints, so an HTTP client written against that contract can target the gateway by changing its base URL.
1212
1313This request sets an org-wide default of \$500 per month for every developer:
1414
from line 30
3030
3131| Field | Values | Description |
3232| - | - | - |
33| `scope.type` | `user`, `rbac_group`, `organization` | `user` targets one developer by their OpenID Connect (OIDC) `sub`, the stable user ID your identity provider assigns; pass it as `scope.user_id`. `rbac_group` targets an [IdP group](/docs/en/claude-apps-gateway-config.md#managed) by name; pass it as `scope.rbac_group_id`. `organization` is the org-wide default. The gateway accepts all three; Anthropic's public `POST` is user-only today. |
33| `scope.type` | `user`, `rbac_group`, `organization` | `user` targets one developer by their OpenID Connect (OIDC) `sub`, the stable user ID your identity provider assigns; pass it as `scope.user_id`. `rbac_group` targets an [IdP group](https://code.claude.com/docs/en/claude-apps-gateway-config.md#managed) by name; pass it as `scope.rbac_group_id`. `organization` is the org-wide default. The gateway accepts all three; Anthropic's public `POST` is user-only today. |
3434| `amount` | Whole-number string of USD cents, or `null` | `null` is unlimited. `"0"` is a zero cap, which blocks every request. |
3535| `period` | `daily`, `weekly`, `monthly` | A scope can hold one cap per period, and each enforces independently: a developer is blocked if over any of them. |
3636
37A group or organization cap is a per-seat default that each member inherits, not a shared pool. Per period, a developer's effective cap resolves in this order: a per-user override, then the most restrictive of their group caps, then the org default, then unlimited. [`admin.group_limit_mode: max`](/docs/en/claude-apps-gateway-config#admin) flips the multi-group tie-break to least-restrictive instead.
37A group or organization cap is a per-seat default that each member inherits, not a shared pool. Per period, a developer's effective cap resolves in this order: a per-user override, then the most restrictive of their group caps, then the org default, then unlimited. [`admin.group_limit_mode: max`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin) flips the multi-group tie-break to least-restrictive instead.
3838
3939### Authenticate to the admin API
4040
4141Send one of:
4242
43* An `x-api-key` header matching a key in [`admin.write_keys`](/docs/en/claude-apps-gateway-config#admin) for full access, or `admin.read_keys` for `GET`-only access. Each key carries an `id` that appears in the audit log as `admin-key:<id>`, so give Terraform, CI, and each automation its own.
44* A gateway bearer token whose `groups` claim includes one of [`admin.admin_groups`](/docs/en/claude-apps-gateway-config#admin). This is full access and audits as `oidc:<sub>`, so prefer it for human admins.
43* An `x-api-key` header matching a key in [`admin.write_keys`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin) for full access, or `admin.read_keys` for `GET`-only access. Each key carries an `id` that appears in the audit log as `admin-key:<id>`, so give Terraform, CI, and each automation its own.
44* A gateway bearer token whose `groups` claim includes one of [`admin.admin_groups`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin). This is full access and audits as `oidc:<sub>`, so prefer it for human admins.
4545
4646## How enforcement works
4747
4848On each `/v1/messages` request, the gateway looks up the developer's caps and period-to-date spend in one Postgres query. A developer over any cap gets a `429` with `error.type: billing_error` and header `x-should-retry: false`.
4949
50The message names the period and reset time, such as `spend limit reached (daily; resets 2026-08-08 00:00 UTC)`, followed by your [`admin.blocked_message`](/docs/en/claude-apps-gateway-config#admin) if set. When a developer exceeds several caps at once, the message names the cap that resets last. The response also carries a `retry-after` header with the seconds remaining until that reset. Before v2.1.225 on the gateway server, the message was `spend limit reached` with no period, reset time, or `retry-after` header.
50The message names the period and reset time, such as `spend limit reached (daily; resets 2026-08-08 00:00 UTC)`, followed by your [`admin.blocked_message`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin) if set. When a developer exceeds several caps at once, the message names the cap that resets last. The response also carries a `retry-after` header with the seconds remaining until that reset. Before v2.1.225 on the gateway server, the message was `spend limit reached` with no period, reset time, or `retry-after` header.
5151
5252On v2.1.227 or later, the protocol reference at `<public_url>/protocol` also lists the exact usage-limit response headers and `429` body.
5353
from line 59
5959
6060The meter picks each request's rates in this order:
6161
621. A matching [`pricing.overrides`](/docs/en/claude-apps-gateway-config#pricing) row for the upstream that served the request. Requires v2.1.227 or later.
621. A matching [`pricing.overrides`](https://code.claude.com/docs/en/claude-apps-gateway-config#pricing) row for the upstream that served the request. Requires v2.1.227 or later.
63632. List price for the upstream model ID, the string the gateway sends to the provider, when the Claude Code cost table recognizes it. The table accepts Anthropic, Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry ID forms.
643. List price for the [`models[].id`](/docs/en/claude-apps-gateway-config#models) you mapped to that upstream ID, for upstream strings that carry no model name, such as an Amazon Bedrock application-inference-profile ARN or a Microsoft Foundry deployment name. Requires v2.1.218 or later.
643. List price for the [`models[].id`](https://code.claude.com/docs/en/claude-apps-gateway-config#models) you mapped to that upstream ID, for upstream strings that carry no model name, such as an Amazon Bedrock application-inference-profile ARN or a Microsoft Foundry deployment name. Requires v2.1.218 or later.
65654. The unknown-model tier of \$5/\$25 per million input/output tokens, so an ID the meter can't place is never free. The gateway warns at boot and once per ID at runtime when it uses this tier.
6666
67Whichever rate applies, the meter then multiplies the amount by [`pricing.multiplier`](/docs/en/claude-apps-gateway-config#pricing), default `1`.
67Whichever rate applies, the meter then multiplies the amount by [`pricing.multiplier`](https://code.claude.com/docs/en/claude-apps-gateway-config#pricing), default `1`.
6868
6969Client aborts are billed too. When a stream ends without the upstream's final usage frame, the meter bills a floor estimate of about four characters per output token for the text already sent to the client, so aborting requests early doesn't evade a cap.
7070
7171#### Long-prompt rates
7272
73The list price for [Claude Haiku 5.5](https://platform.claude.com/docs/en/models/haiku-5-5/overview) has a [higher rate for prompts over a token threshold](/docs/en/model-config.md#haiku-5-5-context-window-and-pricing). When Haiku 5.5 serves a request whose prompt exceeds the threshold, a gateway server running Claude Code v2.1.293 or later prices the whole request at that rate. The meter counts input tokens, cache reads, and cache writes toward that threshold.
73The list price for [Claude Haiku 5.5](https://platform.claude.com/docs/en/models/haiku-5-5/overview) has a [higher rate for prompts over a token threshold](https://code.claude.com/docs/en/model-config.md#haiku-5-5-context-window-and-pricing). When Haiku 5.5 serves a request whose prompt exceeds the threshold, a gateway server running Claude Code v2.1.293 or later prices the whole request at that rate. The meter counts input tokens, cache reads, and cache writes toward that threshold.
7474
7575If one of your `pricing.overrides` rows matches the request, that row's rates apply at any prompt length.
7676
7777### Postgres availability
7878
79The pre-check queries Postgres with a two-second timeout. If the store is unreachable or times out, enforcement fails open by default: the request proceeds, the gateway logs a warning, and the response carries no `anthropic-ratelimit-unified-*` headers. Set [`enforcement.fail_closed_on_error: true`](/docs/en/claude-apps-gateway-config#enforcement) to fail closed instead, which returns the same `429 billing_error` but with the message `spend limit unavailable` and no period, reset time, or `retry-after` header. Fail-open keeps a store outage from becoming an inference outage; fail-closed guarantees no unmetered spend.
79The pre-check queries Postgres with a two-second timeout. If the store is unreachable or times out, enforcement fails open by default: the request proceeds, the gateway logs a warning, and the response carries no `anthropic-ratelimit-unified-*` headers. Set [`enforcement.fail_closed_on_error: true`](https://code.claude.com/docs/en/claude-apps-gateway-config#enforcement) to fail closed instead, which returns the same `429 billing_error` but with the message `spend limit unavailable` and no period, reset time, or `retry-after` header. Fail-open keeps a store outage from becoming an inference outage; fail-closed guarantees no unmetered spend.
8080
81Fail-open only helps while your load balancer or orchestrator still routes traffic to the gateway. See [Outage behavior](/docs/en/claude-apps-gateway-deploy.md#outage-behavior) for `store.readiness_grace_seconds`, which keeps replicas passing their readiness check through a short outage.
81Fail-open only helps while your load balancer or orchestrator still routes traffic to the gateway. See [Outage behavior](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#outage-behavior) for `store.readiness_grace_seconds`, which keeps replicas passing their readiness check through a short outage.
8282
8383### Usage warnings in Claude Code
8484
85Claude Code warns a developer as they approach their cap: once utilization passes 75%, and again past 95% of their most-consumed cap. When the gateway blocks a request, Claude Code shows the gateway's `429` message as is, including your `admin.blocked_message`. It also shows the cap in `/usage` and passes it to the developer's [status line](/docs/en/statusline.md#spend-limit-fields) script.
85Claude Code warns a developer as they approach their cap: once utilization passes 75%, and again past 95% of their most-consumed cap. When the gateway blocks a request, Claude Code shows the gateway's `429` message as is, including your `admin.blocked_message`. It also shows the cap in `/usage` and passes it to the developer's [status line](https://code.claude.com/docs/en/statusline.md#spend-limit-fields) script.
8686
8787Each display needs a minimum Claude Code version on the developer's machine and on the gateway server:
8888
from line 94
9494
9595The warnings and the percentage come from the `anthropic-ratelimit-unified-*` headers, which the gateway adds to each successful `/v1/messages` response for a developer who has a cap. The headers always describe the developer's own cap: the gateway strips the upstream provider's rate-limit headers, which describe your shared quota, and never forwards them.
9696
97The spend a developer sees is the gateway's own [estimate](#how-requests-are-priced), the same figure it enforces the cap with, and not an amount from your provider's bill. Claude Code reads the dollar amounts with a separate request to the gateway. If you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` on developers' machines, as [Compliance posture](/docs/en/claude-apps-gateway-deploy.md#compliance-posture) suggests, Claude Code skips that request. With that variable set, or with a gateway server older than v2.1.284, the bar and the status line stay percentage-only.
97The spend a developer sees is the gateway's own [estimate](#how-requests-are-priced), the same figure it enforces the cap with, and not an amount from your provider's bill. Claude Code reads the dollar amounts with a separate request to the gateway. If you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` on developers' machines, as [Compliance posture](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#compliance-posture) suggests, Claude Code skips that request. With that variable set, or with a gateway server older than v2.1.284, the bar and the status line stay percentage-only.
9898
9999## Admin API reference
100100
from line 158
158158
159159| Table | Contents | Retention |
160160| - | - | - |
161| `spend` | Per-principal period-to-date counters in cents | [`admin.spend_retention_months`](/docs/en/claude-apps-gateway-config#admin), default 13 |
161| `spend` | Per-principal period-to-date counters in cents | [`admin.spend_retention_months`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin), default 13 |
162162| `spend_limits` | The configured caps | Until deleted via the API |
163| `admin_audit` | The mutation trail | [`admin.audit_retention_days`](/docs/en/claude-apps-gateway-config#admin), default 365 |
164| `principal_emails` | Each principal's last-seen email, display name, and IdP groups. Contains PII. | [`admin.identity_retention_days`](/docs/en/claude-apps-gateway-config#admin) since last activity, default 90 |
163| `admin_audit` | The mutation trail | [`admin.audit_retention_days`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin), default 365 |
164| `principal_emails` | Each principal's last-seen email, display name, and IdP groups. Contains PII. | [`admin.identity_retention_days`](https://code.claude.com/docs/en/claude-apps-gateway-config#admin) since last activity, default 90 |
165165
166166When a developer leaves, delete any per-user cap via `DELETE /v1/organizations/spend_limits/{id}`; their spend and identity rows age out on the retention windows above. To erase one person immediately, for offboarding or a data subject access request (DSAR), run `DELETE FROM principal_emails WHERE principal = '<sub>'` directly against the gateway database. That removes the only table holding their email, name, and groups. The `spend` and `admin_audit` rows reference the pseudonymous OIDC `sub` only and age out on their own windows.
167167
168168## Related
169169
170* [`admin` and `enforcement` configuration](/docs/en/claude-apps-gateway-config#admin): enabling the admin API and tuning retention
171* [Deployment guide](/docs/en/claude-apps-gateway-deploy.md#postgres): Postgres schema and backup guidance
170* [`admin` and `enforcement` configuration](https://code.claude.com/docs/en/claude-apps-gateway-config#admin): enabling the admin API and tuning retention
171* [Deployment guide](https://code.claude.com/docs/en/claude-apps-gateway-deploy.md#postgres): Postgres schema and backup guidance
172172
No line in this hunk matches that.