Skip to main content
Browse the documentation

Control and safety

Governance and guardrails

The limits that hold whether or not anyone is asked — pausing the company, per-run caps, agent permissions, guardrails and the company's rules.

Approvals put a person in front of single actions. The controls on this page work without anyone in the loop: they decide what an agent can do at all, how much a run may cost, and what happens to traffic before and after the model. Start with the first two sections; most companies need nothing more.

Stop everything: pause the company

When something looks wrong, pause the whole company. Pausing stops every automated run: agent and mission schedules are held (not deleted), runs started by webhooks, delegation, missions or departments are refused with COMPANY_PAUSED, and automated runs already in flight are cancelled. A person's own chat with any agent still answers, so you can investigate.

Before you pause, see what it would stop — this call changes nothing:

curl -s https://api.snaga.ai/api/v1/tenants/me/company/pause-scope \
  -H "Authorization: Bearer $SNAGA_API_KEY"

Then pause, optionally with a reason, and resume when ready:

curl -s -X POST https://api.snaga.ai/api/v1/tenants/me/company/pause \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Checking yesterday’s outbound emails"}'

curl -s -X POST https://api.snaga.ai/api/v1/tenants/me/company/resume \
  -H "Authorization: Bearer $SNAGA_API_KEY"

Both need an admin or owner and the tenants:write scope. On resume, held schedules fire again from their next instant.

Cap what a run may spend

Three ceilings limit cost, from the widest to the narrowest:

  • The company's spend cap — a budget per day, week or month, checked before every run starts. See Usage and limits.
  • An agent's per-run cap — max_budget_per_run_usd in the agent's permission set (below).
  • One run's limits — resource_limits on POST /api/v1/runs: max_duration_ms, max_steps, max_tool_calls, max_tokens_per_run and max_cost_usd. Any other key is refused with 422.

A run that crosses its cost ceiling fails with error_code: BUDGET_EXCEEDED, and error_details says which limit it hit and how much was spent.

Rehearse before you launch

A company's test run (POST /api/v1/tenants/me/test-run) runs one cycle with every tool that would publish, send, pay or run a command withheld — not offered, and refused if called anyway — whatever the agent's autonomy. A new company cannot launch until a test run has passed for its current version.

Agent permissions

An agent's permission set limits what that agent may do, independent of approvals:

FieldEffect
allowed_toolsA non-empty list limits the agent's runs to exactly these tools; every other tool is neither offered nor executed. An empty list sets no limit.
max_budget_per_run_usdHard cost cap for each of the agent's runs. 0 means no cap from this field.
can_spawn, max_spawn_depthWhether the agent may create child agents, and how deep.
can_self_modifyChecked only when the agent spawns a child agent: the child cannot exceed the parent's permissions. It does not stop an agent editing itself.

Read it with GET /api/v1/governance/permissions/{agentId} and change it with PUT /api/v1/governance/permissions/{agentId}. The GET answers 404 while the agent has no permission set at all — the usual state until one is written. The PUT merges: a field you omit keeps its stored value, but a list you send replaces the stored list.

Guardrails

A guardrail screens agent traffic. The platform has built-in guardrails, and you can add your own as a webhook: Snaga calls your URL to screen the traffic, and applies the guardrail's action. Register one with POST /api/v1/guardrails:

curl -s https://api.snaga.ai/api/v1/guardrails \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "pii-screen",
    "webhook_url": "https://example.com/guardrail",
    "phase": "both",
    "action": "block",
    "secret": "<shared secret>"
  }'
FieldValues
phaseinput, output or both — screen what goes into the model, what comes out, or both. Required.
actionblock (default), redact, warn or log.
timeout_msHow long to wait for your webhook. Default 5000.
secretUsed to sign each call. Never returned; the listing says has_secret.

The URL is checked before it is stored and again at every call. A new guardrail takes effect without a restart. GET /api/v1/guardrails lists your custom guardrails (not the built-in ones); DELETE /api/v1/guardrails/{guardrailId} removes one and detaches it from every agent that named it. A run stopped by a guardrail ends with the status guardrail_blocked. Scopes: guardrails:read and guardrails:write.

The company's rules

For companies that want written rules for their agents, Snaga keeps a constitution: a set of rules with a tamper-evident history. Where governance is switched off on a deployment, these routes answer 501.

  • GET /api/v1/governance/constitution reads the rules. Each rule says whether it is advisory — whether anything can actually enforce it.
  • POST /api/v1/governance/check asks whether an action by an agent would be allowed, and which rules it would break. It records nothing.
  • GET /api/v1/governance/violations/{agentId} lists violations recorded against an agent.
  • Every change to the rules is appended to a ledger; GET /api/v1/governance/ledger/verify (admin or founder) recomputes the chain and says whether it is intact.
  • Safe mode — POST /api/v1/governance/emergency/safe-mode — halts non-essential agent execution in your company; while it is on, every governance check blocks. It is per company, not platform-wide, and only the company's founder can activate it. GET /api/v1/governance/emergency/state says whether it is on.

See what happened

  • GET /api/v1/runs/{runId}/audit-log — the audit trail of one run.
  • GET /api/v1/tenants/me/company/changes — every change to the company, newest first.
  • GET /api/v1/tenants/me/company/versions — earlier versions of the company; a restore is made as a proposal you apply.