Multi-agent flows

Many agents. One graph. A human where it matters.

A flow is a list of steps with depends_on edges. Independent steps run in parallel, a human_gate pauses the run until someone weighs in, and the single is_output step becomes the answer. Every step is a normal, billed, logged model call.

3
Step kinds: agent_call, human_gate, repeat
202
Always async — poll the run
1
Output step per flow, validated
A network of glowing nodes joined by flowing orange lines, a hand reaching in to a central checkpoint node
What you get

A DAG engine, not a prompt chain.

◈

agent_call

A model call. agent_config is a saved persona slug, an inline {species_name, system_prompt, temperature, max_tokens}, or a slug with overrides layered on top. Prompts are templated.

✋

human_gate

Pauses the run. context is resolved and shown to a person; their human_input comes back through POST /v2/flows/runs/{run}/resume and is available to later steps.

⟳

repeat

A compile-time macro: count rounds of an inner step group — a rebuttal loop, a refine loop — expanded into ordinary steps with repeat.prev / repeat.cur references. Capped platform-wide.

⇶

Parallel by construction

Two steps with no edge between them run concurrently through one parallel pipeline call. The validator rejects cycles, unknown dependencies and missing or duplicate output steps before a run ever starts.

⌕

Web search on a budget

Any agent_call can declare tool_budget: N — up to N bounded rounds of a real, cited web search before the step must answer. Every round is a real billed call, hard-capped at N+1.

▤

Saved, versioned, owned

/v2/flows and /v2/agent-configs are CRUD. Editing a spec bumps its version; in-flight runs keep their snapshot. Flows are owned by your account and public unless you mark them private.

A flow spec

Two hot takes → a human review → one cool synthesis.

The two hot agents have no edge between them, so they run in parallel. The gate waits for both, shows them to a person, and the synthesizer gets everything — including the human's note.

{ "steps": [
  { "step_key": "hot_1", "kind": "agent_call", "agent_config": "hot-agreeable",
    "depends_on": [], "is_output": false,
    "prompt": { "messages": [{"role": "user", "content": "{{input.prompt_package}}"}] } },
  { "step_key": "hot_2", "kind": "agent_call", "agent_config": "hot-contrarian",
    "depends_on": [], "is_output": false,
    "prompt": { "messages": [{"role": "user", "content": "{{input.prompt_package}}"}] } },
  { "step_key": "review", "kind": "human_gate", "depends_on": ["hot_1", "hot_2"],
    "prompt_for_human": "Compare the two takes before synthesis.",
    "context": { "hot_1": "{{hot_1.output.content}}", "hot_2": "{{hot_2.output.content}}" } },
  { "step_key": "cool_synth", "kind": "agent_call", "agent_config": "cool-synthesizer",
    "depends_on": ["hot_1", "hot_2", "review"], "is_output": true,
    "prompt": { "messages": [{"role": "user", "content":
      "Original: {{input.prompt_package}}\n\nAgreeable: {{hot_1.output.content}}\n\nContrarian: {{hot_2.output.content}}\n\nHuman guidance: {{review.human_input.note}}\n\nWrite the final synthesized answer."}] } }
] }

Run it, then poll.

# saved flow: the slug is the endpoint
curl -X POST https://fire.prosaga.net/v2/flows/hot-cool-review/run \
  -H "Authorization: Bearer $FIRE_API_KEY" -H "Content-Type: application/json" \
  -d '{"input": {"prompt_package": "…"}}'
# → 202 {"run_id": 123, "status": "pending"}

# poll; the gate shows as awaiting_human
curl https://fire.prosaga.net/v2/flows/runs/123?verbosity=compact \
  -H "Authorization: Bearer $FIRE_API_KEY"

# a person answers the gate
curl -X POST https://fire.prosaga.net/v2/flows/runs/123/resume \
  -H "Authorization: Bearer $FIRE_API_KEY" -H "Content-Type: application/json" \
  -d '{"step_key": "review", "human_input": {"note": "go with the contrarian take"}}'

Templates resolve against input.* and any completed step's output.content or human_input.*. A referenced token that isn't in context fails the run loudly rather than substituting an empty string. Each step's output.meta.call_id and price are on the run, and total_cost_usd sums them.

Visual designer

Design flows on a canvas, save, run and watch the steps.

The client portal includes a graphical editor for exactly this spec: drop agent, gate and repeat nodes, draw the dependencies, write the prompt templates, pick a persona per step. It validates with the same rules the API does, saves to your account's flow definitions, and can start a test run and show each step completing.

Whatever you build there is a plain spec you can also fetch from GET /v2/flows/{slug} and version in your own repo.

Step kinds, at a glance

kindWhat it doesBilled?
agent_callOne model call; may carry tool_budget for web search roundsYes, per call
human_gatePauses the run until /resume supplies human_inputNo
repeatExpands count rounds of inner steps at compile timePer expanded call
tool_callReserved — recognised by the spec, rejected by the engine for now—
FAQ

Questions evaluators ask.

Can I get the result synchronously?

No, by design. Every run and resume returns 202 immediately and a queue worker executes the graph. Poll GET /v2/flows/runs/{run} — use ?verbosity=compact for a progress indicator without the content.

How is a flow billed?

Per step. Each agent_call goes through the same pipeline as /v1/chat, with its own call_id and meta.price; the run carries total_cost_usd. Human gates cost nothing while they wait.

How many custom flows can I save?

Paying accounts can hold 10 active flow definitions by default; deactivating one frees a slot. Ad-hoc, unsaved specs passed inline to POST /v2/flows/run don't count against it.

Who can see my flow?

A flow you create is owned by your account and public unless you set is_public: false. A private flow is invisible and un-runnable to everyone else — its existence is never leaked. Only the owner can edit or delete, public or not.

A raised hand holding a burning torch — the Fire brand emblem
Ready when you are

Get a key. Make a call. See the price.

Free to sign up — you only pay when you top up. No card required to get your first key.