Set up budgets

Put spend ceilings on organizations, teams, users and keys.

AOCore enforces spend at four levels: key → user → team → organization. A request must pass every level that applies to it. The effective ceiling is therefore the tightest limit in the chain, not the one nearest the key.

The part that surprises people

Setting a generous budget on a key does not raise its ceiling. If the key belongs to a user whose monthly budget is exhausted, the request is refused regardless of what the key allows. Budgets restrict; they never grant.

So when a request is rejected for budget, the question is not “what is this key’s budget” but “which of the four levels is exhausted”.

Steps

1. Open /organizations and set the organization ceiling first. Working top-down means you never set a child budget that the parent silently overrides.

Organizations

2. Open the organization to see its teams, members and current spend.

Organization detail

3. Set team budgets from /teams, then user budgets from /users.

4. Set key budgets at issue time — see Issue and scope an API key.

5. Review the whole picture at /budgets.

Budgets

Reset periods

Each budget carries an optional duration — daily, weekly, monthly. The counter resets at the start of the next period; a budget with no duration is cumulative and never resets.

Reset is driven by a scheduled job, not by read-time computation. A budget whose reset appears not to have fired is a scheduler question, not a budget-config one.

Soft limits

A soft budget raises an alert without refusing traffic. Use it as an early warning ahead of the hard ceiling — particularly on organizations, where hitting a hard limit stops every team beneath at once.

Watching consumption

  • /spend — aggregate spend by model, user, team and tag
  • /spend-logs — the individual rows behind those totals
  • /anomalies — statistically unusual movement, see Respond to a spend anomaly

Spend Analytics

Dashboard and analytics figures are served from a pre-aggregated daily rollup for complete calendar days, with today overlaid live. Complete days therefore reconcile exactly with the raw logs; today’s figures move as traffic arrives.

Attribution requires a tag or an owner

Spend is attributed to whatever the request carried. A key bound to no user, team or organization produces rows that appear in totals but cannot be broken down. If /spend shows a large unattributed bucket, look for unbound keys before suspecting the aggregation.

API equivalent

curl -X POST https://<gateway>/budget/new \
  -H "X-Aoedge-Identity-Context: <attested context>" \
  -H "Content-Type: application/json" \
  -d '{"organization_id":"<uuid>","max_budget":10000,"budget_duration":"monthly","soft_budget":8000}'