The atomic spend increment that actually pauses a run happens inside the executor loop (
recordSpend under BEGIN IMMEDIATE), not over REST. These routes are the operator surface: set a cap, read the ledger, resume a paused scope, and view the audit trail.Routes
| Method | Path | Summary |
|---|---|---|
GET | /api/governance/budgets | List every budget row |
POST | /api/governance/budgets | Set or raise a budget cap |
POST | /api/governance/budgets/:scope/:scopeId/resume | Resume a paused scope |
GET | /api/governance/audit | Read the forensic audit log |
POST | /api/governance/delegation-approval | Route a risky action to the leader’s approval queue |
GET | /api/approvals | List persisted approval decisions |
POST | /api/approvals | Persist an approval decision |
GET /api/governance/budgets
Lists every budget row, newest-updated first.
Response 200 OK
All budget rows.
cap-mode budget auto-pauses the run at 100% of limitUsdCents (the kill-switch). A warn-mode budget records spend and emits warning events at the 80% and 100% crossings but never reaches paused.
POST /api/governance/budgets
Sets a budget cap for a scope, or raises an existing one. A new scope starts at spent 0 / active. Raising the cap above current spend un-pauses the scope.
Request body
Budget scope. One of
'agent', 'mission', 'team', 'tenant'.The id of the scoped entity.
Spending cap in US cents. Must be a positive integer. A cap of
0 is rejected.'warn' (default) — track spend and emit warnings. 'cap' — auto-pause at the limit.A cap of
0 is rejected. “Uncapped” is the absence of a budget row, not a zero limit. To make a scope uncapped, delete its budget row or leave it without one.Response 200 OK
POST /api/governance/budgets/:scope/:scopeId/resume
Human override: forces a paused scope back to active. The kill-switch re-arms on the next spend crossing. Pass graceUsdCents to raise the cap above current spend so the run can make forward progress. The response includes willRepause: true when you resume an at/over-limit scope without enough grace.
One of
'agent', 'mission', 'team', 'tenant'. An unknown value returns 400.The scoped entity’s id.
Request body (optional)
Additional headroom in cents. Use this to raise the limit above current spend so the next run isn’t immediately re-paused.
Response 200 OK
The resumed budget row (same shape as the list).
true when spentUsdCents >= limitUsdCents — the next cost event will re-pause this scope.GET /api/governance/audit
Reads the append-only forensic audit log — installs, approvals, tool calls, budget events, cap hits, verifications, and circuit breaks — newest first. The audit is written in-process by the subsystems that emit events; there is no write endpoint.
Filter to one agent’s audit rows.
Filter by event type. Valid values:
install, approval, tool_call, budget, cap_hit, verification, circuit_break. Ignored if the value is not one of these literals.Lower bound on
createdAt (epoch ms).Max rows returned. Clamped to 1,000. Default
200.Response 200 OK
Matching audit rows.
POST /api/governance/delegation-approval
Routes a delegated child’s risky action to the leader’s approval queue. If a prior sticky allow_always for the (leader, scope) pair exists, the call returns immediately. Otherwise it opens a pending row in the tool_call_approvals table and blocks until the leader resolves it or the TTL/poll-deadline expires.
Request body
The leader agent who must resolve this approval.
Delegation kind, mapped to the scope key
'delegate:<kind>'. Defaults to 'code'.The name of the agent the work is delegated to (used in the approval prompt text).
The delegated task description (used in the approval prompt text).
The board task this delegation gates. Lets the TTL reaper unblock the task on expiry.
Responses
200 OK — a prior sticky allow_always short-circuits the prompt:
200 OK — approval was awaited; the resolution is whatever the leader chose or a terminal expiry:
GET /api/approvals
Lists persisted approval decisions from the approval_history table, newest first. This is a decision-history log distinct from the live delegation handshake above.
Filter to one agent. Omit for all agents.
Max rows. Clamped to 1–200. Default
50.Response 200 OK
POST /api/approvals
Persists a single approval decision into the approval_history table.
Request body
The agent this decision applies to.
The decision. One of
'allow-once', 'allow-always', 'deny'.The tool name this decision covers.
Optional JSON object with additional context. Stored as a JSON string.
Response 200 OK
See also
- Governance concepts — budgets, the kill-switch, circuit breakers, and approvals
- Verification — what produces
verificationaudit events - Governance dashboard — the UI over these routes
- REST API overview