Per-API-key spend budgets
A spend budget is a monthly ceiling, per API key, expressed as a positive integer count of minor currency units (for example cents) plus a 3-letter ISO-4217 currency such asUSD. Set it on any active key through the developer API and Devotel Orbit will report that key’s live usage against it and fire an alert the first time spend crosses each threshold you configure — so one runaway integration, or a leaked key, cannot blow its budget silently.
This surface is distinct from the existing budget controls:
- It is a spend ceiling (money), not a request-count budget. The per-key request quota and per-minute rate limit in Per-API-key usage limits and spend alerts block by request volume; a spend budget caps the billable amount a key may accumulate in a UTC month.
- It is persisted on the API and shared with your team, not held in your browser. The dashboard badge described in Per-API-key usage budgets and threshold alerts is a per-browser tripwire; the budgets you set here are stored in your organization and read back identically for every operator.
How budgets are stored
Budgets live in your organization’ssettings.api_key_budgets — a free-form JSONB slot, so the feature requires no schema migration and applies to every existing organization immediately. It is deliberately kept separate from the settings.api_governance slot that holds the request-rate/quota config from Per-API-key usage limits and spend alerts, so editing one surface can never bleed into the other. A key with no budget entry resolves to “unlimited” — existing, unconfigured keys behave exactly as before.
Writes apply on the next request: a 60-second per-pod read cache is invalidated on every write, so a freshly-saved budget takes effect immediately rather than waiting out the cache TTL. A reseller subaccount is its own organization, so a partner budgets a downstream key by writing this config on the child organization — no cross-tenant plumbing.
Read the budget surface
Owner / admin / developer scope.budgetisnullfor a key with no spend ceiling (unlimited);usageis still reported for unbudgeted keys.last_notified_percentis the alert high-water mark — the highest threshold percent already notified for this key in the current month. See the alert semantics below.usage.requests_this_minuteis the key’s live in-flight count for the current minute window;usage.requests_this_monthis the count for the current UTC month — the same live metering peek the rate-limit surface uses.- The read hydrates at most 250 keys;
keys_truncated: truetells you the list was cut. defaults.alert_thresholdsis the threshold set that applies when you do not pass one;defaults.max_alert_thresholdscaps how many thresholds a single key may carry.
Set or clear a budget
limit_minor— positive integer ceiling in minor currency units (50000 = $500.00 when the currency is USD). A zero, negative, or fractional value is rejected with a422; to remove the ceiling sendnullinstead of zero.currency— 3-letter ISO-4217 code, required whenever alimit_minoris set. It is upper-cased on save, sousdreads back asUSD.period— only"monthly"is supported today; the ceiling resets on the 1st of each UTC month. Any other value is a422.alert_thresholds— ascending integer percentages in (0, 100]. Duplicates are dropped and the list is sorted ascending. Omit it to use the default[50, 80, 100]; sendnullto restore the default. At most 10 thresholds per key.
404 — a write can never be applied to another tenant’s key. Writes are audit-logged (developer.api_key_budget.updated), and the persisted value reads back byte-identical to what metering enforces, because both paths use the same validation.
Alert semantics
Thresholds are integer percentages of the ceiling in (0, 100], held ascending and de-duplicated. Each fires once per threshold per month, via thelast_notified_percent high-water mark:
- The first time the month’s usage crosses a threshold, that threshold fires and the mark advances to it.
- A threshold at or below the mark never re-fires within the same month, even if spend dips back under it and crosses again.
- The mark persists across edits to the budget’s amount or currency, so a simple edit does not re-fire thresholds you have already acknowledged this month.
- Clearing the budget (
limit_minor: null) removes the entry entirely; setting a fresh budget afterwards starts a new mark, so alerts re-arm.
limit_minor: 50000 ($500.00 USD) and thresholds [50, 80, 100]:
- Spend reaches
25,000minor units (25000 / 50000 = 50%) →usage_percentis 50, the 50% threshold fires,last_notified_percentbecomes 50. - Spend reaches
40,000(80%) → the 80% threshold fires, the mark advances to 80. - Spend reaches the ceiling
50,000(100%) → the 100% threshold fires; the key is at its cap. - Usage percentage is floored — spend of
39,999is 79.998% but reports 79%, so it does not prematurely trip the 80% threshold.
Roles and audit
Reading the surface requires owner, admin, or developer scope. Setting or clearing a budget is additionally restricted to owner, admin, or developer, and every write is audit-logged with the key id, the new ceiling and thresholds, and whether the operation was a clear (developer.api_key_budget.updated).
How it relates to the other budget guides
Three surfaces now govern per-key usage — set the ones that match what you need:- Spend budget (this guide): a money ceiling per key per month, persisted on the organization, with alert-once-per-threshold notifications. Use it to bound what a key can spend and to alert the team.
- Request-count budget (usage budgets and threshold alerts): a per-browser dashboard badge that flags a key at a request threshold. Its Warning that “budgets are stored in your browser, not on the API” applies to that badge only — the spend budgets above ARE persisted on the API and shared with your team, which is exactly what that guide recommends pairing with.
- Request quotas and rate limits (usage limits and spend alerts): hard per-minute and per-month request caps that return
429when exceeded. Use those for blocking by request volume; use a spend budget for bounding by money.
Edge behaviour
- A key with no configured budget never appears as over-limit; budgets are strictly opt-in.
- A malformed value is rejected at write time with a
422, never persisted — so a bad hand-edit cannot fabricate a tiny cap that blocks the key, and can never throw on the read path. - At most 10 thresholds per key; duplicates and out-of-range values are rejected or de-duplicated at write time.
- Clearing the ceiling is a
null, not a0— a zero is rejected because it would hard-block the key, which is never the intent (to disable a key, revoke it).