AI Usage & Budgets
AI → AI usage shows what your fleet spends on AI: every node reports its AI usage to the Control Panel, and the page adds it up for the whole workspace. The page is free on every plan. Setting an AI budget (caps, alerts and enforcement on the nodes) needs the 🔒 Business plan or above, see Control Center features by plan.
You need the billing:read permission to open the page (owners, admins, managers and viewers have it). Changing the budget needs billing:write (owners and admins).
Where the numbers come from
Each Cloud OS node already records the cost of every AI request it makes (provider, model, input and output tokens, and a cost estimate from its price list). Every 5 minutes the node sends the Control Panel one line per day, provider and model with that day’s totals: requests, tokens in and out, cached tokens when the provider reports them, and the cost estimate. The first report after a node starts covers the last 35 days, so history catches up after an outage.
- Each line is the full total for that day, so a report that is sent twice is simply stored once.
- Requests to local models (Ollama) are counted, at $0.
- Days are UTC days.
- When you remove a node, its spend stays in the month’s totals (shown with its last hostname).
The page
| Part | What it shows |
|---|---|
| Month picker | The current month (month to date) or any of the last 12 months |
| Spend MTD | Spend so far this month, and the share of the monthly cap when a budget is set (red once the cap is reached) |
| Forecast | Month-to-date spend projected over the whole month: spend ÷ days elapsed × days in the month. Amber when the forecast is above the monthly cap. For a past month it is the final spend |
| Requests / Tokens | Completed AI requests and prompt + completion tokens (cached tokens underneath) |
| Top model | The model with the highest spend this period |
| Nodes over budget | Nodes whose spend reached their own cap (per-node monthly or daily cap) |
| Spend per day | A line per day; the daily cap is drawn dashed when you set one |
| By node / By model | Sortable tables: spend, today’s spend, requests, tokens, the node’s monthly cap and an Over badge; per model the spend, requests, tokens in / out and how many nodes used it |
AI budget
🔒 Business plan and above. The AI budget card on the right holds one budget for the workspace. Every field is optional: leave it empty for “no cap”.
| Setting | Meaning |
|---|---|
| Mode | Soft: owners and admins get notifications, nothing is blocked. Hard: in addition, nodes pause requests to paid AI providers once a cap is reached |
| Workspace / month, Workspace / day | Caps on the whole workspace’s spend |
| Each node / month, Each node / day | Default caps for every node |
| Alert at | Percentage of the monthly cap that sends the early warning (80 % by default) |
| Node overrides | Different caps for single nodes (an override replaces both per-node defaults for that node; an empty field there means no cap for that node) |
Notifications
When new usage comes in, the Control Panel checks the budget and posts to the notifications bell of the workspace owners and admins (kind ai.budget, link to AI usage). Each alert is sent once per period:
- AI spend at 80 % of the monthly budget (your threshold), once per month
- Monthly AI budget reached, once per month
- Daily AI budget reached, once per day
- <node> reached its monthly / daily AI budget, once per node and period
Hard budgets on the nodes
With a hard budget, every node receives the caps on its next heartbeat (within about 30 seconds), together with what the other nodes of the workspace spent this month and today. The node adds its own live spend and, once a cap is reached, refuses new requests to paid providers with:
AI requests are paused: the workspace reached its monthly AI budget ($400.12 of $400.00). Local models keep working. A workspace admin can raise the limit in Control Center → AI usage.
- Local models (Ollama) keep working.
- The node keeps the last budget it received across restarts, so the cap holds even while the Control Panel is unreachable.
- Raising the cap, switching to Soft, removing the budget or the start of a new day / month lifts the block on the next heartbeat.
- Spend from other nodes reaches a node with a delay of a few minutes (the reporting interval), so a workspace can overshoot a workspace cap by what its nodes spend in that window. Per-node caps are checked against the node’s own live spend.
On plans below Business
The AI usage page stays fully available. The budget card shows an upgrade card with a Business badge and an Upgrade button. PUT /api/ai/usage/policy returns 402 with the standard upgrade_required body ("feature": "ai_budgets", "required_plan": "business").
A budget saved before a downgrade becomes inactive: no alerts are sent and nodes are released on their next heartbeat. It is kept, and becomes active again after an upgrade. You can remove it with Remove saved budget.
API
| Endpoint | Method | Permission | Description |
|---|---|---|---|
/api/ai/usage/summary?month=YYYY-MM | GET | billing:read | Totals, forecast, top model, spend per day, per node and per model, budget status. Omit month for the current month. Free on every plan |
/api/ai/usage/policy | GET | billing:read | {policy, node_caps, gated, required_plan}; policy is null when no budget is set |
/api/ai/usage/policy | PUT | billing:write | Set the budget (Business+, 402 otherwise). Audited as ai.budget.update |
/api/ai/usage/policy | DELETE | billing:write | Remove the budget (allowed on every plan). Audited as ai.budget.delete |
curl -X PUT https://panel.quazzar.cloud/api/ai/usage/policy \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{
"mode": "hard",
"monthly_cap_usd": 400,
"daily_cap_usd": 20,
"node_monthly_cap_usd": 120,
"node_daily_cap_usd": 0,
"alert_threshold_pct": 80,
"node_caps": [{ "instance_id": "7c9e…", "monthly_cap_usd": 150, "daily_cap_usd": 8 }]
}'mode is soft or hard, caps are USD between 0 and 10,000,000 (0 = no cap), alert_threshold_pct is 1–100, and at least one cap must be set. Node overrides must name nodes of your workspace. Invalid values return 422.
Summary response (shortened):
{
"month": "2026-09", "from": "2026-09-01", "to": "2026-09-25", "current": true,
"days_in_month": 30, "days_elapsed": 25,
"totals": { "cost_usd": 403.4, "requests": 36306, "tokens_in": 18153000, "tokens_out": 6454400,
"cache_read_tokens": 5445900, "cache_write_tokens": 0 },
"today_usd": 22.1, "forecast_usd": 484.08,
"top_model": { "provider": "anthropic", "model": "claude-sonnet-4-5", "nodes": 7, "cost_usd": 250.11, "…": "…" },
"nodes_over_budget": 1,
"by_day": [{ "day": "2026-09-01", "cost_usd": 8.0, "requests": 720, "tokens": 488000 }],
"by_node": [{ "instance_id": "…", "hostname": "edge-ew2-0600", "cost_usd": 125.05, "today_usd": 5.0,
"monthly_cap_usd": 120, "daily_cap_usd": 0, "over_budget": true, "…": "…" }],
"by_model": [{ "provider": "openai", "model": "gpt-4o", "nodes": 4, "cost_usd": 84.71, "…": "…" }],
"budget": { "mode": "hard", "active": true, "monthly_cap_usd": 400, "daily_cap_usd": 20,
"used_pct": 100.85, "forecast_pct": 121.02, "month_reached": true, "day_reached": true },
"gated": false, "required_plan": "business"
}Nodes send their usage in the ai_usage field of the agent heartbeat and receive the hard budget in the ai_budget field of the reply (pkg/agentpb/ai_usage.go). An older Control Panel that doesn’t know these fields ignores them, and nodes keep their last budget.