Spend caps
Set spending limits by organization, project, environment, or API key
Spend caps let you limit how much API usage can cost over a rolling time window. You configure them in your dashboard under Organization settings → Spend caps. You can also set per-key caps when editing an API key's scope.
Spend caps are separate from your credit balance. A request can fail with insufficient_credits when you are out of credits, or with spend_cap_exceeded when a configured cap would be exceeded. Both return HTTP 402.
Scope types
Each spend cap applies to one scope. Usage is the billed USD cost of completed requests.
| Scope | What counts toward the cap |
|---|---|
| Organization | All API spend across every project and environment in the org |
| Project | Spend for that project only |
| Environment | Spend for that environment only |
| API key | Spend for requests made with that key only |
You can enable multiple caps at once. For example, an org cap, a project cap, and a per-key cap can all apply to the same request.
How caps stack
Each enabled cap is evaluated on every request. Usage counts toward every cap that applies at once.
- Block mode: when settled spend in the rolling window (plus the estimated cost of the current request) reaches 100% of the limit, the gateway rejects the request with HTTP
402and error codespend_cap_exceeded. - Warn mode: when utilization reaches 80% or higher, Sansa logs a warning and can send notification emails. Warn caps do not block requests.
Caps do not compound into a single shared budget. A $100 org cap and a $50 project cap are two independent limits. Either one can block traffic when exceeded in block mode.
Rolling windows
Every cap has a window measured in days (1 to 365). Spend is summed over the last N days, not calendar months.
| Window | Typical use |
|---|---|
| 1 day | Daily cap (shown as "daily" in API error messages) |
| 30 days | Common default; not a calendar month |
Daily and 30-day caps set in the key scope editor also appear on the organization spend caps page.
If you create a cap for the same scope and window twice, the second save updates the existing cap instead of creating a duplicate.
Where to configure caps
Organization spend caps (central hub)
Go to Organization settings → Spend caps in your dashboard. From there you can:
- Add caps at organization, project, environment, or API key scope
- Choose limit amount, window length, and block vs warn
- For API key scope, pick the key by name from a dropdown
- Filter, search, and delete caps
Organization owners and admins can manage spend caps.
Per-key scope editor
When creating or editing an API key, open the Spend cap section in the key scope sidebar. You can set optional daily and 30-day window limits and choose block or warn. The same caps appear in the organization spend caps list.
Plans and entitlements
| Plan | Spend caps |
|---|---|
| Free | One organization-level cap |
| Pro and above | Organization caps plus project, environment, and API key caps |
Contact support if you need granular caps on a Free plan.
Block error messages
When a block-mode cap would be exceeded, the API returns:
{
"error": {
"code": "spend_cap_exceeded",
"message": "This request would exceed the 30-day spend cap for this organization.",
"request_id": "a3f2c1d0-8b4e-4f9a-b2d1-7c5e3a1f0e9b"
}
}The message names the window (daily or N-day) and the scope (organization, project, environment, or API key) of the cap that blocked the request. When several caps are exceeded, it names the most specific scope: API key, then environment, project, organization.
Handling spend cap errors in code
Check error.code to tell a spend cap from running out of credits:
Python
except openai.APIStatusError as e:
code = e.body.get("error", {}).get("code")
if e.status_code == 402 and code == "spend_cap_exceeded":
print("Spend cap reached:", e.body["error"]["message"])
elif e.status_code == 402:
print("Add credits from your dashboard")TypeScript
} catch (err) {
if (err instanceof OpenAI.APIError && err.status === 402) {
const code = (err.error as { code?: string })?.code;
if (code === "spend_cap_exceeded") {
console.error("Spend cap reached:", err.error.message);
} else {
console.error("Add credits from your dashboard");
}
}
}Do not retry spend_cap_exceeded until the rolling window spend drops or you raise the cap.
Related topics
- Errors: full error codes, including
insufficient_creditsandspend_cap_exceeded - Organization settings in your dashboard: billing, credits, and spend caps