Budgets
Spend limits, pricing overrides, and credit accounting.
Budgets are opt-in on each deployment (the GATEWAY_BUDGETS kill-switch, off by default). Ask
your platform operator whether budgets are enabled before relying on them — with the switch off,
no budget check runs at all, usage isn't counted against budgets, and budget alerts don't fire.
Budgets let you cap spend or token usage at the API key, BYOK Connection, workspace, or metadata-tag level, independent of your overall credit balance. They're a tighter, resettable ceiling — not a replacement for topping up credits.
Scopes
Every applicable budget is checked independently on each request — a request is rejected if it would exceed any budget that applies to it, with no pooling across levels (a workspace budget doesn't share headroom with a key budget under it).
| Level | Applies to | levelId is |
|---|---|---|
key | One API key | The API key's id |
connection | One BYOK Connection (an @<slug> you've configured) | The Connection's id |
workspace | Everything in the workspace | The workspace's id |
tag | Requests in one workspace that carry one metadata tag | The workspace's id, plus the tag |
A budget can cap cost (USD) or tokens (input + output combined).
- A key budget counts every request made with that API key, whatever model or Connection it uses. Requests made with a short-lived ephemeral token count against the API key that minted it.
- A connection budget counts only requests that route through that
Connection with an
@<slug>/<model>model string. - When you create a key or connection budget,
levelIdmust be an active (not revoked) API key or Connection in your organisation; anything else is rejected withVALIDATION_ERROR.
Earlier gateway releases did not enforce key budgets: they compared a key budget against the Connection id instead of the API key id, so it never matched. Key budgets you created on those releases start counting usage and blocking requests as soon as your deployment runs a fixed gateway. Review their limits before then.
Budgets bind to the organisation that made the request, not the one that pays for it. Under pooled billing a child organisation's requests are paid from its parent's wallet, but a budget on the child's workspace or key still applies to the child — so a workspace budget is the per-child spend cap.
Budgets on a metadata tag
A tag budget caps one slice of a workspace's traffic: a channel, a feature,
an agent release. You pick the workspace, a tag key, and a tag value (for
example channel = voice, or agentVersion = v12), and the budget
applies to every request in that workspace whose
x-ai-setu-metadata header carries exactly
that key with exactly that value:
curl https://gateway.aisetu.ai/v1/chat/completions \
-H "Authorization: Bearer $AI_SETU_API_KEY" \
-H "Content-Type: application/json" \
-H 'x-ai-setu-metadata: {"channel":"voice","agentVersion":"v12"}' \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'- Matching is exact and case-sensitive:
Voicedoes not matchvoice. - A request without the tag (or with another value) is not counted against the tag budget and is never blocked by it.
- A request can match several tag budgets at once (one on
channel, one onagentVersion); like every other level, each is checked independently and exceeding any of them rejects the request. - The workspace's own budget still applies to tagged requests.
- The tag must fit in the 256-byte metadata header, so
{"key":"value"}can be at most 256 bytes. - The tag can't be edited after creation; delete the budget and create a new one.
Alerts work the same way as for any budget; alert emails name the scope as
Tag "channel=voice" in workspace "Prod", and webhook payloads include
budget.tag: {"key": "channel", "value": "voice"}.
Over GraphQL, create one with level: TAG, the workspace id as levelId,
and tagKey / tagValue; list them with budgets(level: TAG, levelId: ...).
Reset cadence
| Value | Meaning |
|---|---|
none | No automatic reset — the cap is a lifetime ceiling |
weekly | Resets every Sunday 00:00 UTC |
monthly | Resets the 1st of each month, 00:00 UTC |
| A custom interval in days | Resets every N days from creation |
On exhaustion
A budget-exhausted request returns 402 with code
wesence.budget_exhausted — distinct from wesence.insufficient_credits
(your platform balance is empty) and from a 429 rate-limit rejection. The
response carries which level was breached and, if the budget resets, when:
| Header | Meaning |
|---|---|
X-AI-Setu-Budget-Level | key | connection | workspace | tag |
X-AI-Setu-Budget-Reset-At | RFC 3339 timestamp of the next reset, omitted if the budget doesn't reset |
Branch on error.code, not just the HTTP status — several distinct
conditions share 402. See Errors.
Alerts
Each budget can carry up to 10 alert thresholds, so you hear about spend
before a budget runs out. A threshold is either a percent of the limit
(50, 80, 90, 100, or any whole number from 1 to 100) or an
absolute amount in the budget's unit (dollars or tokens, below the
limit). Percent thresholds follow the limit if you change it. 100% means
the budget is exhausted.
- Thresholds are checked about once a minute.
- Each threshold alerts once per reset period. A
monthlybudget that crosses 80% in March alerts again only if it crosses 80% in April. - When usage reaches the limit, a
budget.exhaustedalert fires even if 100% isn't one of your thresholds. - Alerts never block traffic. Requests are rejected only at the limit itself, and only when budget enforcement is enabled.
Alerts are delivered two ways:
| Channel | Who gets it |
|---|---|
| Every organization member whose role can manage billing (Owners always). One email per budget per check, for the highest threshold just crossed. | |
| Webhooks | Each endpoint you register under Settings → Notifications subscribed to budget.threshold / budget.exhausted. A workspace-scoped endpoint only receives that workspace's budgets. |
Over GraphQL, thresholds go in alertThresholdsJson as a JSON array, for
example [{"percent":80},{"percent":100},25000000] (the last entry is $25
in USD micros).
Capping an autonomous agent's spend
If you're wiring up a runtime agent that mints its own short-lived
ephemeral tokens, you can set a spend
cap directly on the token at mint time, independent of whether workspace
budgets are enabled. Once the token's cap is hit, further calls on that
token return 402 with code wesence.credential_cap_exceeded — the rest of
your workspace keeps working.
Configuring budgets
Budgets are managed in the console under Settings → Limits, where you set the level (including a metadata tag inside a workspace), type, limit, reset cadence, and alert thresholds for each one. Webhook endpoints for alerts live under Settings → Notifications.