Appearance
Budgets & spend caps
A budget is a spend ceiling merido enforces on the request path. When a budget's hard limit is reached, new requests are blocked with HTTP 402 before any upstream call is made — so a runaway client, a leaked key, or a single expensive customer can never overspend.
Budgets live in the dashboard under Limits → Budgets (or the /api/budgets API).
The shape of a budget
Every budget is defined by four things:
| Part | Options | Meaning |
|---|---|---|
| Scope | org · virtual_model · key | What the cap applies to. |
| Window | hourly · daily · weekly · monthly · yearly · lifetime | How often spend resets. |
| Metric | usd (default) · charge · total_tokens · requests | What is counted. |
| Limits | hard (required) · soft (optional) | The ceiling, and an optional early-warning threshold. |
- The hard limit blocks new requests (HTTP 402) once spend reaches it.
- The soft limit does not block: it warns and shifts routing toward cheaper models, giving you headroom before the hard stop.
Spend is tracked live on an engine counter, so the dashboard shows real-time burn-down against the cap.
Lifetime budgets are prepaid balances
A budget with the lifetime window never resets — spend accumulates forever, so the cap behaves as a prepaid balance:
balance = hard_limit − spentThis is a natural fit for reseller scenarios: provision one API key per end-user, set a lifetime USD budget on that key as their prepaid balance, and merido blocks the key once the balance is drawn down. To "top up", raise the key's hard limit. Because a lifetime cap is cumulative (not time-windowed), its 402 carries no Retry-After — the balance must be increased, not waited out.
Migrated from "Credit wallets"
The standalone per-key credit-wallet feature was folded into budgets: a prepaid wallet is exactly a lifetime, usd, key-scoped budget. There is one model to learn instead of two.
Temporary increases
For time-windowed budgets you can grant a temporary increase — extra headroom that expires at a time you choose — without permanently raising the cap. This is the audited "give them more room until end of month" lever. (A lifetime/prepaid budget is topped up by editing its hard limit instead.)
API
| Method | Path | Purpose |
|---|---|---|
GET | /api/budgets | List budgets with live spend. |
POST | /api/budgets | Create a budget (scope_type, scope_id, window, hard_limit_usd, optional soft_limit_usd, metric, model_glob). |
PUT | /api/budgets/{id} | Update the limits / enabled flag. |
DELETE | /api/budgets/{id} | Remove a budget. |
POST | /api/budgets/{id}/increase | Grant a temporary, expiring increase. |
A lifetime USD key budget is created exactly like any other budget — just set "window": "lifetime":
bash
curl -X POST http://localhost:8788/api/budgets \
-H 'content-type: application/json' \
-d '{"scope_type":"key","scope_id":42,"window":"lifetime","hard_limit_usd":25}'