Skip to main content
Browse the documentation

Automation

Missions

Turn a larger goal into objectives that agents carry out in order, with budgets, checks, an optional go-ahead from a person and a review at the end.

A single run is right for a single job. A goal like "prepare the quarterly investor update" is several jobs that depend on each other, each needing its own agent, its own budget and a way to tell when it is really done. A mission holds that together.

A mission goes through five stages: goal → objectives → authorization → execution → after-action review. Each objective is assigned to an agent or a team, runs as ordinary runs, and counts as done only when its success criteria have been checked.

Missions are switched on per company; where they are off, every mission route answers 404.

Start a mission

There are two ways in. Send a plan you wrote, and it is used exactly as written. Or send only a goal with available_agents, and the platform's planner breaks it into objectives for you.

curl -X POST https://api.snaga.ai/api/v1/missions \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "<session_id>",
    "goal": "Quarterly investor update",
    "plan": {
      "goal": "Quarterly investor update",
      "classification": "mission",
      "requires_authorization": true,
      "objectives": [
        {
          "title": "Collect the numbers",
          "description": "Revenue, burn and headcount for the quarter",
          "success_criteria": ["All three figures present with sources"],
          "priority": "high",
          "depends_on_indices": [],
          "assigned_agent_id": "<analyst_agent_id>",
          "budget": { "max_runs": 3, "max_tokens": 200000, "max_cost_usd": 2 }
        },
        {
          "title": "Draft the letter",
          "description": "One page for investors, plain language",
          "success_criteria": ["Under 500 words", "Uses the collected figures"],
          "priority": "medium",
          "depends_on_indices": [0],
          "assigned_agent_id": "<writer_agent_id>",
          "budget": { "max_runs": 3, "max_tokens": 100000, "max_cost_usd": 1 },
          "review_required": true
        }
      ]
    }
  }'

depends_on_indices points at earlier objectives in the list; together they must form a graph with no cycles. Each objective needs an agent or a team (assigned_agent_id or assigned_team_id) and a budget with max_runs, max_tokens and max_cost_usd. An objective that would cross its budget is stopped.

Optional per objective:

  • commanders_intent — the end state to preserve when the literal instruction stops fitting.
  • roe — rules of engagement: autonomous_actions, requires_approval and prohibited. A tool named in requires_approval waits for a person every time; a tool named in prohibited is never offered to the agent. Every entry is also written into the agent's instructions.
  • decision_points (branches of the plan), deadline, review_required.

The answer is 201 with mission_id, the objective_ids and run_started, which says whether work has already begun.

The go-ahead

With requires_authorization: true the mission stops at awaiting_authorization before anything runs — use it for plans that change things or reach outside your company. A person passes the gate with POST /api/v1/missions/{missionId}/authorize, and the mission starts.

If your company is already running as many missions as it may at once, the mission waits in executing; POST /api/v1/missions/{missionId}/run starts it later.

While it runs

A mission's status is one of draft, planning, awaiting_authorization, executing, paused and verifying, and ends as completed, failed or aborted.

GET /api/v1/missions/{missionId}/events streams progress as server-sent events: mission (a snapshot on connect), status_change, checkpoint_added, aar_finalized and a final terminal. Each connection lasts at most 15 minutes, so a long mission is expected to reconnect. GET /api/v1/missions/{missionId} is the authoritative record — poll it alongside the stream. GET /api/v1/missions/{missionId}/objectives shows each objective with what it has spent so far.

When an objective's run stops for a person — an approval or a question — the mission waits for the decision rather than counting a failure. If the person refuses, that objective ends with abort_reason: rejected_by_person.

Reviewing results

An objective with review_required: true does not finish on its own. Once its result passes the checks it waits at awaiting_review for a person:

curl -X POST https://api.snaga.ai/api/v1/missions/<mission_id>/objectives/<objective_id>/review \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "revise", "feedback": "Lead with the revenue figure" }'

accept completes it; revise sends it back with your feedback (up to 10 times); reject fails it.

Steering a mission

  • POST /api/v1/missions/{missionId}/pause asks it to hold. It stops after the current objective settles, not instantly.
  • POST /api/v1/missions/{missionId}/resume continues it. Objectives already verified are not run, or paid for, again.
  • POST /api/v1/missions/{missionId}/abort ends it for good and cancels the run in flight, so spending stops.
  • PATCH /api/v1/missions/{missionId}/objectives/{objectiveId} changes an objective's assignment, budget, deadline, rules or text — not its status.

The after-action review

Once a mission has finished, GET /api/v1/missions/{missionId}/aar returns its review: the outcome (success, partial, failed or aborted), how long each phase took, each objective's final status and whether its success criteria held (verified), a failure_analysis when something failed, and lessons — patterns with recommendations for next time. Before the mission ends this answers 404.

Missions on a schedule

To run the same plan regularly, send it to POST /api/v1/missions/schedules with a cron line, an optional timezone and a name. Each fire starts a fresh mission from the plan, with every review and rule carried over. As with agent schedules, the cron line has five fields and may not fire more often than every five minutes. GET /api/v1/missions/schedules lists them, and DELETE /api/v1/missions/schedules/{scheduleId} stops one without touching missions it already started.

All fields: API reference.