Spend Limits
Every API key can carry an optional monthly spend limit in US dollars. Once the key’s billed usage in the current calendar month reaches the limit, further requests with that key are refused until you raise the limit, switch to another key, or the month rolls over.
Spend limits are the blast-radius control for API keys: a leaked key, a runaway script, or an experimental integration can never spend more than the budget you gave it.
How it works
- The limit covers everything the key does, every billable surface it can reach, in one dollar number.
- Spend is measured by the same billing engine that produces your invoice, at your plan’s prices. The number the limit counts is the number you are billed.
- The window is the calendar month (UTC). Limits reset automatically at 00:00 UTC on the 1st.
- Keys without a limit are unaffected. Limits are per key, independent of your workspace balance.
Enforcement runs against billed usage, which trails live traffic by a couple of minutes. A key crossing its limit mid-burst can briefly overshoot before it is cut off.
Setting a limit
Manage limits in the console under API Keys: set a limit when creating a key, or open Edit on an existing key to add, raise, lower, or remove one at any time - the change takes effect immediately and the key secret never changes. Each capped key shows its month-to-date spend against the limit right in the key list.
Workspace-wide monthly budget
Per-key limits bound one credential; the workspace budget bounds everything. Owners can set
a monthly USD budget in workspace settings (Settings → Workspace). Once the workspace’s billed
month-to-date spend - across every API key plus console usage - reaches the budget, new requests
are refused with a 402 whose error code is spend_budget_exceeded,
until the budget is raised or the month resets (1st, UTC). The two controls compose: a key stops
at its own limit even when the workspace budget has room, and the budget stops everything even
for uncapped keys.
The budget has the same webhook alerts as per-key limits: subscribe an endpoint to
workspace.spend_budget.warning (80%) and workspace.spend_budget.reached (100%). Each fires
at most once per month for a given budget value (changing the budget re-arms them); data.object
is a workspace snapshot with monthly_budget and monthly_spend, and the crossing details ride
as data.spend_budget_alert.
Project budgets
A project’s monthly_budget is the ceiling in between: it bounds the work attributed to one project, and an application that models each of its customers as a project uses it as that customer’s allowance.
Once the project’s billed month-to-date spend reaches it, new billable work attributed to the project is refused with a 402 whose error code is project_spend_limit_exceeded, distinct from the workspace’s spend_budget_exceeded.
Subscribe an endpoint to project.spend_budget.warning (80%) and project.spend_budget.reached (100%) to hear it coming.
They use the same thresholds and the same once-per-month-per-budget-value rule as the workspace pair, so changing the budget re-arms them.
An endpoint scoped to a project receives only that project’s events; a workspace-wide endpoint receives every project’s.
data.object is the project exactly as GET /v1/projects/{project_id} returns it, and the crossing details ride as data.spend_budget_alert:
The same answer is readable without waiting for an event: every project read carries monthly_budget_status (ok, warning or reached, on the same thresholds) and monthly_budget_remaining, which goes negative by the overshoot once spend has passed the budget.
A crossing is detected by the budget check the next billable request attributed to the project makes, and project alerts pause while the workspace itself is over its own budget, which the workspace events already cover.
Get warned before a key hits its limit
Workspace webhook endpoints can subscribe to two spend-limit events, so you hear about a key approaching its budget instead of discovering it through failing requests:
Each event fires at most once per key per calendar month for a given limit value; changing
the limit re-arms both thresholds against the new value. data.object is the API key
exactly as a GET returns it (including spend_cap and spend_cap_remaining), and the
crossing details ride alongside it as data.spend_cap_alert:
When a key hits its limit
Requests with the key fail with HTTP 402 and the error code spend_cap_exceeded:
Handle it distinctly from payment_required: payment_required means the workspace balance
needs a top-up; spend_cap_exceeded means this specific key hit the budget you set for it, and
raising the key’s limit in the console unblocks it immediately.
In-flight requests are never interrupted. The limit gates new requests only.