Orchestrator Runs
Start and observe multi-agent orchestrator runs — /v1/runs, its event stream, and signed webhook delivery.
A run executes a preset multi-agent graph. Start one, then observe it through polling, a replayable SSE stream, or signed webhooks.
Base URL: https://api.misar.io/coder. Every endpoint authenticates with Authorization: Bearer <API_KEY>.
List presets
/v1/runs/presetsThe graph presets available to POST /v1/runs. Takes no parameters.
Response fields
presetsstring[]Preset names, sorted.
curl https://api.misar.io/coder/v1/runs/presets \
-H "Authorization: Bearer $MISARCODER_API_KEY"{
"presets": [
"bug_fix",
"debate",
"plan_then_code",
"research_crew",
"research_then_synthesize"
]
}Start a run
/v1/runsRequest body
presetstringbodyrequiredA preset name from GET /v1/runs/presets.
argsobjectbodyArguments forwarded to the preset's graph builder. Defaults to {}.
initial_stateobjectbodyStarting state for the graph. Defaults to {}.
webhook_urlstringbodyWhere to POST each event. Must be https:// and must not resolve to a private or reserved address.
webhook_secretstringbodyShared secret for signing deliveries. At least 16 characters.
run_idstringbodySupply your own run id instead of letting the server generate one.
Response fields
run_idstringIdentifier for every other endpoint on this page.
graph_namestringThe graph that was built.
statusstringpending or running at creation. Over a run's life: pending, running, finished, error, cancelled.
started_atstringISO-8601 UTC start time.
curl -X POST https://api.misar.io/coder/v1/runs \
-H "Authorization: Bearer $MISARCODER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"preset": "plan_then_code",
"args": { "task": "Add pagination to the reports endpoint" },
"webhook_url": "https://acme.com/hooks/misarcoder",
"webhook_secret": "a-secret-at-least-16-chars"
}'{
"run_id": "run_9a2f1c40",
"graph_name": "plan_then_code",
"status": "running",
"started_at": "2026-08-04T11:22:41.008Z"
}Status codes
| Code | Meaning |
|---|---|
200 | Run started |
400 | webhook_url must use https://, webhook_url resolves to a private or reserved address, webhook_secret must be at least 16 characters, or invalid preset args |
401 | Missing authorization or Invalid API key |
404 | unknown preset: <name> |
List runs
/v1/runsEvery retained run. Takes no parameters.
Response fields
runsobject[]Run records — see the field list under "Get a run".
curl https://api.misar.io/coder/v1/runs \
-H "Authorization: Bearer $MISARCODER_API_KEY"History is bounded
The registry retains 200 runs, evicting the oldest finished ones first. Persist anything you need long-term — do not treat this as an audit log.
Get a run
/v1/runs/{run_id}Path parameters
run_idstringpathrequiredThe run id.
Response fields
run_idstringRun identifier.
graph_namestringThe preset graph that was built.
statusstringpending, running, finished, error, or cancelled.
errorstring | nullFailure detail when status is error.
started_atstringISO-8601 UTC.
finished_atstring | nullISO-8601 UTC, once terminal.
event_countnumberEvents buffered so far.
webhook_urlstring | nullConfigured delivery target.
webhook_disabledbooleantrue once deliveries were auto-disabled after repeated failures.
webhook_failuresnumberConsecutive delivery failures.
tokens_usednumberTokens consumed by the run.
completedstring[]Node ids that finished.
curl https://api.misar.io/coder/v1/runs/run_9a2f1c40 \
-H "Authorization: Bearer $MISARCODER_API_KEY"{
"run_id": "run_9a2f1c40",
"graph_name": "plan_then_code",
"status": "finished",
"error": null,
"started_at": "2026-08-04T11:22:41.008Z",
"finished_at": "2026-08-04T11:24:02.911Z",
"event_count": 34,
"webhook_url": "https://acme.com/hooks/misarcoder",
"webhook_disabled": false,
"webhook_failures": 0,
"tokens_used": 18422,
"completed": ["plan", "code", "review"]
}Returns 404 run not found for an unknown id.
Get buffered events
/v1/runs/{run_id}/eventsThe complete buffered timeline, in one response. Use this when you missed the stream.
Response fields
run_idstringThe run id.
eventsobject[]Every event recorded so far.
curl https://api.misar.io/coder/v1/runs/run_9a2f1c40/events \
-H "Authorization: Bearer $MISARCODER_API_KEY"Cancel a run
/v1/runs/{run_id}/cancelCancels an in-flight run. Takes no body.
Response fields
run_idstringThe run id.
statusstringcancelled.
curl -X POST https://api.misar.io/coder/v1/runs/run_9a2f1c40/cancel \
-H "Authorization: Bearer $MISARCODER_API_KEY"{ "run_id": "run_9a2f1c40", "status": "cancelled" }404 run not found covers both an unknown id and a run with no active scheduler.
Stream events
/v1/runs/{run_id}/streamServer-Sent Events for a run.
Late subscribers get the whole run
Connecting mid-run replays every buffered event first, then continues live. Connecting to an already-finished run replays the buffer and closes. You never miss the start.
curl -N https://api.misar.io/coder/v1/runs/run_9a2f1c40/stream \
-H "Authorization: Bearer $MISARCODER_API_KEY" \
-H "Accept: text/event-stream"data: {"type":"graph_started","entry":"plan","node_count":3,"event_id":"…","timestamp":"…"}
data: {"type":"agent_started","role":"planner","model":"qwen3:8b","node_id":"plan","agent_id":"…","event_id":"…","timestamp":"…"}
event: end
data: {}Event frames are unnamed
Every data frame is an unnamed SSE frame — the default message type — with the event kind carried inside the JSON as type. Only the terminator is named: event: end with an empty body. A client that dispatches on the SSE event: name will see nothing but end. Parse data and branch on type.
Common type values
| Type | Payload |
|---|---|
graph_started | entry, node_count, graph |
graph_state | completed, in_flight, aborted |
agent_started | role, model, node_id |
agent_finished | role, node_id, status (ok, cancelled, error), plus error on failure |
budget_exceeded | tokens_used, cap |
graph_finished | aborted, abort_reason, completed, errors, tokens_used |
Executor events — tool calls, tool results, text deltas — flow through unchanged, tagged with the emitting agent_id. Every frame also carries event_id and timestamp, plus agent_id, parent_id, and run_id where applicable.
There is no heartbeat frame. Set your own idle timeout.
Webhooks
When webhook_url is set, every event is also POSTed to it as { "run_id": …, "event": … }.
X-Misar-Signature: t=<unix timestamp>,v1=<hex hmac-sha256>Compute the HMAC with webhook_secret and compare in constant time. Reject deliveries whose timestamp is far from now.
| Property | Value |
|---|---|
| Delivery timeout | 5 s |
| Attempts per event | 3 |
| Backoff base | 0.5 s |
| Consecutive failures before auto-disable | 5 |
Once auto-disabled, webhook_disabled on the run record flips to true and no further deliveries are attempted for that run.