Skip to main content
Orchestrations coordinate multiple agents to handle complex, multi-domain tasks. A coordinator agent analyzes incoming messages and delegates subtasks to specialized entity agents based on their role descriptions. The coordinator synthesizes entity responses into a unified reply.

Common Patterns

Create an orchestration, add entity agents with clear role descriptions, then use the streaming endpoint. The coordinator automatically handles delegation. Entity role descriptions should be specific and non-overlapping so the coordinator can make clear routing decisions.

CRUD

POST /api/orchestrations

Create an orchestration.
{ "name": "Team", "strategy": "supervisor" }
requests.post(f"{BASE_URL}/api/orchestrations", headers=headers, json={"name": "Team", "strategy": "supervisor"})

GET /api/orchestrations

List all orchestrations.
requests.get(f"{BASE_URL}/api/orchestrations", headers=headers)

GET /api/orchestrations/

Get orchestration with its entities.
id
string
required
Orchestration ID
requests.get(f"{BASE_URL}/api/orchestrations/{orch_id}", headers=headers)

PUT /api/orchestrations/

Update orchestration config.
id
string
required
Orchestration ID
requests.put(f"{BASE_URL}/api/orchestrations/{orch_id}", headers=headers, json={"name": "Updated"})

DELETE /api/orchestrations/

Delete an orchestration.
id
string
required
Orchestration ID
requests.delete(f"{BASE_URL}/api/orchestrations/{orch_id}", headers=headers)

Entities

POST /api/orchestrations//entities

Add an agent as an entity.
id
string
required
Orchestration ID
entity_type
string
required
Use "agent". The route accepts any string ≤50 chars, but the orchestrator’s execution path only invokes entities where entity_type === "agent" — other values are stored but silently skipped at run time.
entity_ref_id
string
required
UUID of the agent to add.
role_description
string
Free-text role hint shown to the coordinator when delegating. Replaces the prior role field used in older docs examples.
config
object
Per-entity overrides; defaults to {}.
position
integer
Sort order in list responses; defaults to 0.
The route returns 400 if either entity_type or entity_ref_id is missing. List/PUT responses key off entity_ref_id and role_description, so any client trying to round-trip will see the same field names.
{
  "entity_type": "agent",
  "entity_ref_id": "agent-uuid",
  "role_description": "Handles billing"
}
requests.post(f"{BASE_URL}/api/orchestrations/{orch_id}/entities", headers=headers, json={"entity_type": "agent", "entity_ref_id": agent_id, "role_description": "Handles billing"})

GET /api/orchestrations//entities

List entities in the orchestration.
id
string
required
Orchestration ID
requests.get(f"{BASE_URL}/api/orchestrations/{orch_id}/entities", headers=headers)

PUT /api/orchestrations//entities/

Update an entity. Only role_description, config, and position are writable — any other top-level keys are silently ignored. entity_type and entity_ref_id are not updatable; create a new entity instead.
id
string
required
Orchestration ID
eid
string
required
Entity ID
role_description
string
Free-text role hint shown to the coordinator when delegating.
config
object
Per-entity overrides.
position
integer
Sort order in list responses.
{ "role_description": "Updated role" }
requests.put(f"{BASE_URL}/api/orchestrations/{orch_id}/entities/{entity_id}", headers=headers, json={"role_description": "Updated role"})

DELETE /api/orchestrations//entities/

Remove an entity.
id
string
required
Orchestration ID
eid
string
required
Entity ID
requests.delete(f"{BASE_URL}/api/orchestrations/{orch_id}/entities/{entity_id}", headers=headers)

Execution

POST /api/orchestrations//run/stream

Run orchestration with streaming SSE. Includes delegation events.
id
string
required
Orchestration ID
{ "message": "Hello" }
requests.post(f"{BASE_URL}/api/orchestrations/{orch_id}/run/stream", headers=headers, json={"message": "Hello"}, stream=True)

GET /api/orchestrations/runs/

Get orchestration run result.
run_id
string
required
Run ID
requests.get(f"{BASE_URL}/api/orchestrations/runs/{run_id}", headers=headers)

Hooks

Orchestration hooks fire at lifecycle events (e.g. before_run, after_run) and can call out to webhooks or other handler types. Hooks fire in position order; setting enabled: false keeps the row but skips execution.

POST /api/orchestrations//hooks

Add a hook.
id
string
required
Orchestration ID
event
string
required
Lifecycle event name (e.g. before_run, after_run).
type
string
required
Hook handler type (e.g. webhook).
config
object
required
Handler-specific configuration (for webhook type, includes url).
matcher
object
Optional condition narrowing when the hook fires.
enabled
boolean
Defaults to true.
position
integer
Execution order within the event. Defaults to 0.
{
  "event": "after_run",
  "type": "webhook",
  "config": { "url": "https://example.com/orch-hook" },
  "enabled": true,
  "position": 0
}
requests.post(f"{BASE_URL}/api/orchestrations/{orch_id}/hooks", headers=headers, json={"event": "after_run", "type": "webhook", "config": {"url": "https://example.com/hook"}})

GET /api/orchestrations//hooks

List hooks for the orchestration, ordered by position.
id
string
required
Orchestration ID
requests.get(f"{BASE_URL}/api/orchestrations/{orch_id}/hooks", headers=headers)

DELETE /api/orchestrations//hooks/

Remove a hook.
id
string
required
Orchestration ID
hook_id
string
required
Hook ID
requests.delete(f"{BASE_URL}/api/orchestrations/{orch_id}/hooks/{hook_id}", headers=headers)

Sessions

Session-level reads on orchestrations. The streaming /run/stream endpoint returns a session_id you can use here to fetch history.

GET /api/orchestrations//sessions

List the most recent 100 sessions for an orchestration. Each entry includes session_id, run_count, first_message, last_activity_at, and created_at.
id
string
required
Orchestration ID
requests.get(f"{BASE_URL}/api/orchestrations/{orch_id}/sessions", headers=headers)

GET /api/orchestrations//sessions//messages

Assembled messages for a session. Each assistant message carries per-run reasoning replay metadata (reasoning_requested, reasoning_duration_ms, reasoning, events) so a chat UI can re-render the original “Thought for X.Xs” pill on refresh. Tool calls are attached per-message via tool_calls. The legacy top-level events field is preserved for older clients.
id
string
required
Orchestration ID
session_id
string
required
Session ID
requests.get(f"{BASE_URL}/api/orchestrations/{orch_id}/sessions/{session_id}/messages", headers=headers)

Error Responses

Orchestration routes return {"error": "<message>"} (no structured error code field).
StatusDescription
400The orchestration has no entity agents — add at least one before running
400Hook POST is missing one of event, type, or config
404No orchestration exists with the given ID
404No hook exists with the given ID for this orchestration
404No orchestration session with the given ID