[FEATURE] Claude apps gateway: threshold notifications (80% warning / 90% critical / 100% exceeded) for daily, weekly, and monthly spend limits
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Problem Statement
The Claude apps gateway supports daily, weekly, and monthly spend caps applied per organization, group, or user (set via the admin API), and meters period-to-date spend against the spend table in cents. Enforcement today is binary and terminal: when a principal reaches a configured cap, the gateway emits a spend.blocked audit event and returns 429, blocking further inference.
There is no proactive signal before that hard stop. From the developer's side, work proceeds normally right up until it abruptly fails with a 429, mid-task, with no prior indication that they were close to a cap. From the operator's side, the only spend-related audit event (spend.blocked) also fires after the limit is already hit, so there is nothing to alert on that would let an admin intervene — raise a cap, reassign work, or flag a runaway session — before a developer is cut off.
This is a poor experience for exactly the runaway-usage scenarios spend limits exist to catch (e.g. recursive sub-agent fan-out burning a daily cap in minutes), because the first anyone hears of it is a blocked request.
Proposed Solution
Add configurable threshold notifications evaluated per spend window (daily, weekly, monthly) as period-to-date spend crosses each threshold, with three default levels:
| Level | Default threshold | Meaning |
| ---------- | ----------------- | --------------------------------------------------- |
| warning | 80% of the cap | Approaching the limit |
| critical | 90% of the cap | Nearly exhausted |
| exceeded | 100% of the cap | Cap reached (aligns with existing spend.blocked) |
1. New audit events. Emit a structured audit event the first time each (principal, window, level) boundary is crossed within a period, so operators can alert on them via their existing log aggregator:
{
"event": "spend.threshold",
"level": "warning", // warning | critical | exceeded
"window": "daily", // daily | weekly | monthly
"sub": "<oidc-sub>",
"email": "<principal-email>",
"groups": ["..."],
"period_to_date_cents": 8000,
"limit_cents": 10000,
"pct": 80,
"period_start": "2026-07-06T00:00:00Z"
}
Fire once per boundary per period (de-duplicated) to avoid log spam on every request past the threshold. exceeded may either reuse/augment the existing spend.blocked event or be emitted alongside it — implementer's choice, as long as the three levels are consistently distinguishable.
2. Developer-facing notice. Surface the current highest-crossed threshold back to the CLI so the developer actually sees it (audit logs alone don't reach them). A lightweight approach: return advisory response headers on inference responses, e.g.
x-cc-gateway-spend-level: warning
x-cc-gateway-spend-window: daily
x-cc-gateway-spend-pct: 82
and have the CLI render a one-line notice (e.g. "Approaching your daily gateway spend limit (82%)") at warning/critical. This gives developers a chance to wrap up or request more budget before the 429.
3. Configuration. Make thresholds configurable in gateway.yaml (under the existing spend-limit config), with the 80/90/100 defaults and a per-window opt-out:
admin:
spend_limits:
notifications:
enabled: true
thresholds: [80, 90, 100] # percent; drives warning / critical / exceeded
windows: [daily, weekly, monthly]
client_headers: true # emit x-cc-gateway-spend-* advisory headers
Defaults should be safe to ship on (audit events on, at the standard thresholds); client_headers could default off for operators who don't want the CLI notice.
Why this belongs in the gateway (not client-side hooks)
The gateway is the only component that knows each principal's authoritative period-to-date spend and configured caps — that state lives in its spend ledger, keyed on the verified OIDC sub from the session JWT, not on the client. Existing client-side approaches (e.g. #11008 "expose token usage/cost in hook inputs", #55945 "hook that fires when you run out of tokens") operate on local session data and can't see gateway-enforced, cross-session, per-window caps or group/org-level limits. This request is specifically about the gateway surfacing its own limit state before it blocks.
Alternatives Considered
- Poll the admin API for spend counters and build external alerting. Works, but requires every operator to build and run a poller, introduces lag, and still doesn't give the developer any heads-up in the CLI.
- Parse
spend.blockedaudit events. Reactive only — the developer is already blocked by the time it fires. - Rely on OTLP token-usage metrics at the collector. Good for dashboards, but metrics-based alerting is decoupled from the gateway's actual cap configuration and doesn't reach the client.
Alternative Solutions
_No response_
Priority
High - Significant impact on productivity
Feature Category
Configuration and settings
Use Case Example
_No response_
Additional Context
- Docs: Claude apps gateway — spend limits, deployment & operations (audit events,
spendtable, fail-open behavior). - Related client-side requests (different layer): #11008, #55945, #72994.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗