Control and safety
Approvals
How an agent stops and asks before it acts, how you answer — allow, decline with feedback, or refuse — and what happens if nobody does.
Agents in Snaga can send messages, publish, call services and change data. Some of that you want done without being asked; some of it should never happen without a person saying yes. Approvals are the line between the two: before a tool call that needs permission, the run stops and waits for you.
What decides whether an agent asks
Each agent carries its own approval policy, set on the agent:
| Field | What it does |
|---|---|
autonomy.level | The default. manual asks before every tool, approve_risky asks only for risky ones, full_auto asks for none. |
approval_required_tools | Tool names that always need a person's approval. |
auto_approve_tools | Tool names the agent may call without asking. |
tool_overrides | Per-tool trust that overrides the default: always_allow, ask_first or never_allow. |
You change them with PATCH /api/v1/agents/{agentId}. Each of these list fields is
replaced when you send it, not merged: send the full list you want. To change one
tool's trust without touching the rest, use
PATCH /api/v1/agents/{agentId}/autonomy/tool-override with tool_name and
trust_level; it answers with the agent's whole override list.
In the web app, ticking Always allow this on an approval card records the same kind of per-tool choice for that agent.
The Chief of Staff can also propose a different approval policy for an agent
(set_approval_policy), but a proposal changes nothing until a person applies it.
What happens when a run needs approval
- The run's
statusbecomesawaiting_approvaland it stops. GET /api/v1/runs/{runId}returnspending_approvals: for each waiting tool call, itsid, the toolnameand itsargs— exactly what the agent wants to do.- The item appears in the company's queue of things waiting for a person, and in the web app as a card that reads Asks your permission.
curl -s https://api.snaga.ai/api/v1/runs/<run_id> \
-H "Authorization: Bearer $SNAGA_API_KEY"
Three ways to answer
| Answer | Call | What happens to the run |
|---|---|---|
| Allow | POST /api/v1/runs/{runId}/approve | The tool call goes ahead and the run continues. |
| Decline with feedback | POST /api/v1/runs/{runId}/revise | The tool is not called; the agent is told why and what to change, and the run continues. |
| Refuse | POST /api/v1/runs/{runId}/reject | The run ends as failed with error_code: approval_rejected. |
The body of approve is optional and may carry a response for the agent. Any other
field is refused — you cannot "approve with approved: false"; to say no, use
revise or reject.
curl -s -X POST https://api.snaga.ai/api/v1/runs/<run_id>/approve \
-H "Authorization: Bearer $SNAGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"response": "Go ahead, but keep it under 200 words."}'
revise is usually the right "no": the agent reads your feedback (required) as the
outcome of what it tried, and does the work again differently.
curl -s -X POST https://api.snaga.ai/api/v1/runs/<run_id>/revise \
-H "Authorization: Bearer $SNAGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"feedback": "Do not email the customer. Draft the reply and show it to me."}'
reject takes an optional reason, which is stored on the run and becomes its
error. Use it when the whole task should stop.
All three need the runs:create scope; revise and reject also need the person
behind the key to have permission to approve runs. Each answers 409 if the run is
not waiting for approval any more — someone may have answered first.
In the web app the card offers Allow, Don't allow and Not now. Not now sends nothing: the request keeps waiting for you.
If nobody answers
A run does not wait forever. A run still waiting for approval about 24 hours after it
started is stopped, with error_code: run_approval_expired. Start the task again if
it is still needed.
The record
Every decision is kept on the run, in approvals, oldest first: the decision
(approved, rejected or revised), the tools it covered, decided_at,
decided_by and, for a refusal or a revision, the reason. You can always see who
allowed what, and when.
Everything else that waits for a person
Approvals are one of several kinds of item that wait for you. One call lists them all:
curl -s "https://api.snaga.ai/api/v1/analytics/inbox?limit=50" \
-H "Authorization: Bearer $SNAGA_API_KEY"
counts gives the backlog by kind (approval, input, paused, failed, and
review and proposal); items lists them with a one-line summary of what is being
asked. It needs analytics:read. In the web app this is Needs you.
| Waiting item | How to answer |
|---|---|
A question (awaiting_input) | POST /api/v1/runs/{runId}/respond with a response. The run resumes. |
| A proposed change to the company | POST /api/v1/tenants/me/proposals/{proposalId}/apply or …/reject. Only a person can apply one; an agent's credential is refused. Unanswered proposals expire after 7 days. |
| A mission result held for review | POST /api/v1/missions/{missionId}/objectives/{objectiveId}/review with a decision of accept, revise (with feedback) or reject. |
Related
- Governance and guardrails — limits that apply whether or not anyone is asked.
- How Snaga works — runs and their states.