Workflow & Multi-Agent Planning API
Execute workflows and leverage multi-agent planning for complex task decomposition through the Orchestrator API.
Overview
The Workflow API provides:
- Workflow Execution: Execute predefined workflows with sequential/parallel steps
- Multi-Agent Planning (MAP): LLM-powered task decomposition and execution
- Execution Tracking: Monitor workflow progress and retrieve results
Base URL: http://localhost:8081 (Orchestrator)
Authentication
All endpoints require:
Authorization: Basic base64(clientId:clientSecret)headerContent-Type: application/jsonheader (for POST requests)
Workflow requests include a user context for audit trail:
user.id— User identifieruser.email— User emailuser.role— User role for policy evaluation
Workflow Execution
POST /api/v1/workflows/execute
Execute a workflow definition.
Request:
curl -X POST http://localhost:8081/api/v1/workflows/execute \
-H "Content-Type: application/json" \
-d '{
"workflow": {
"metadata": {
"name": "travel-booking",
"version": "1.0"
},
"spec": {
"steps": [
{
"name": "search_flights",
"type": "mcp_query",
"connector": "amadeus-travel",
"statement": "search_flights",
"parameters": {
"origin": "SFO",
"destination": "CDG",
"departure_date": "2025-06-01"
}
},
{
"name": "search_hotels",
"type": "mcp_query",
"connector": "amadeus-travel",
"statement": "search_hotels",
"parameters": {
"city": "Paris",
"check_in": "2025-06-01",
"check_out": "2025-06-07"
}
},
{
"name": "summarize",
"type": "llm",
"prompt": "Summarize the flight and hotel options for a trip from SFO to Paris",
"depends_on": ["search_flights", "search_hotels"]
}
]
}
},
"input": {
"budget": 5000,
"currency": "USD"
},
"user": {
"id": 123,
"email": "[email protected]",
"role": "user"
}
}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
workflow.metadata.name | string | Yes | Workflow name |
workflow.spec.steps | array | Yes | Array of workflow steps |
input | object | No | Input data for the workflow |
user | object | Yes | User context for audit |
Step Types:
| Type | Description |
|---|---|
mcp_query | Execute a query via MCP connector |
mcp_execute | Execute a command via MCP connector |
llm | Send prompt to LLM provider |
condition | Conditional branching |
parallel | Execute steps in parallel |
Response (200 OK):
{
"id": "wf_exec_abc123",
"status": "completed",
"workflow_name": "travel-booking",
"started_at": "2025-01-02T10:00:00Z",
"completed_at": "2025-01-02T10:00:05Z",
"steps": [
{
"name": "search_flights",
"status": "completed",
"process_time": "1.234s",
"output": {
"flights": [
{"airline": "Air France", "price": 850}
]
}
},
{
"name": "search_hotels",
"status": "completed",
"process_time": "1.456s",
"output": {
"hotels": [
{"name": "Hotel Eiffel", "price_per_night": 200}
]
}
},
{
"name": "summarize",
"status": "completed",
"process_time": "2.123s",
"output": "I found great options for your trip..."
}
],
"output": {
"final_result": "I found great options for your trip..."
}
}
GET /api/v1/workflows/executions/{id}
Get details of a workflow execution.
Request:
curl http://localhost:8081/api/v1/workflows/executions/wf_exec_abc123
Response (200 OK):
{
"id": "wf_exec_abc123",
"status": "completed",
"workflow_name": "travel-booking",
"started_at": "2025-01-02T10:00:00Z",
"completed_at": "2025-01-02T10:00:05Z",
"duration_ms": 5234,
"steps": [
{
"name": "search_flights",
"status": "completed",
"started_at": "2025-01-02T10:00:00Z",
"completed_at": "2025-01-02T10:00:01Z",
"process_time": "1.234s"
},
{
"name": "search_hotels",
"status": "completed",
"started_at": "2025-01-02T10:00:00Z",
"completed_at": "2025-01-02T10:00:01Z",
"process_time": "1.456s"
},
{
"name": "summarize",
"status": "completed",
"started_at": "2025-01-02T10:00:02Z",
"completed_at": "2025-01-02T10:00:05Z",
"process_time": "2.123s"
}
],
"output": {
"final_result": "I found great options for your trip..."
}
}
GET /api/v1/workflows/executions
List recent workflow executions.
Request:
curl "http://localhost:8081/api/v1/workflows/executions?limit=10"
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 10 | Number of executions to return (max: 100) |
offset | integer | 0 | Pagination offset |
status | string | (all) | Filter by status: pending, running, completed, failed |
Response (200 OK):
{
"executions": [
{
"id": "wf_exec_abc123",
"workflow_name": "travel-booking",
"status": "completed",
"started_at": "2025-01-02T10:00:00Z",
"duration_ms": 5234
},
{
"id": "wf_exec_def456",
"workflow_name": "data-pipeline",
"status": "failed",
"started_at": "2025-01-02T09:00:00Z",
"error": "Step 'fetch_data' timed out"
}
],
"count": 2
}
GET /api/v1/workflows/executions/tenant/{tenant_id}
List workflow executions for a specific tenant.
Request:
curl http://localhost:8081/api/v1/workflows/executions/tenant/my-tenant
Response (200 OK):
{
"tenant_id": "my-tenant",
"count": 5,
"executions": [
{
"id": "wf_exec_abc123",
"workflow_name": "travel-booking",
"status": "completed",
"started_at": "2025-01-02T10:00:00Z"
}
]
}
Multi-Agent Planning (MAP)
POST /api/v1/plan
Submit a complex query for LLM-powered task decomposition and execution.
Request:
curl -X POST http://localhost:8081/api/v1/plan \
-H "Content-Type: application/json" \
-d '{
"query": "Plan a business trip from San Francisco to Paris for June 1-7, find flights under $1000 and 4-star hotels near the Eiffel Tower",
"domain": "travel",
"execution_mode": "auto",
"user": {
"id": 123,
"email": "[email protected]",
"role": "user"
},
"context": {
"budget": 5000,
"currency": "USD",
"preferences": {
"airline_alliance": "SkyTeam",
"hotel_amenities": ["wifi", "breakfast"]
}
}
}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language query |
domain | string | No | Domain hint: travel, healthcare, finance, generic |
execution_mode | string | No | Execution mode: auto, parallel, sequential |
user | object | Yes | User context (required for governance) |
context | object | No | Additional context for planning |
Response (200 OK):
{
"success": true,
"plan_id": "plan_xyz789",
"steps": [
{
"id": "step_1_search_flights",
"name": "search_flights",
"type": "mcp_query",
"description": "Search for flights from SFO to CDG under $1000",
"depends_on": [],
"agent": "amadeus-travel",
"parameters": {
"origin": "SFO",
"destination": "CDG",
"departure_date": "2025-06-01",
"return_date": "2025-06-07",
"max_price": 1000
}
},
{
"id": "step_2_search_hotels",
"name": "search_hotels",
"type": "mcp_query",
"description": "Search for 4-star hotels near Eiffel Tower",
"depends_on": [],
"agent": "amadeus-travel",
"parameters": {
"city": "Paris",
"check_in": "2025-06-01",
"check_out": "2025-06-07",
"star_rating": 4,
"landmark": "Eiffel Tower"
}
},
{
"id": "step_3_summarize",
"name": "summarize_options",
"type": "llm",
"description": "Create a summary of travel options",
"depends_on": ["step_1_search_flights", "step_2_search_hotels"]
}
],
"workflow_execution_id": "wf_exec_abc123",
"result": "I found excellent options for your Paris trip:\n\n**Flights:**\n- Air France AF123: $850 direct, departing 10:00 AM\n- Delta DL456: $920 with 1 stop\n\n**Hotels:**\n- Hotel Eiffel Palace (4-star): $180/night, 0.5 km from Eiffel Tower\n- Le Meridien Étoile (4-star): $210/night, 1.2 km from Eiffel Tower\n\nTotal estimated cost: $1,930-$2,390 (within your $5,000 budget)",
"metadata": {
"tasks_executed": 3,
"execution_mode": "parallel",
"execution_time_ms": 4567,
"tasks": [
{"name": "search_flights", "status": "completed", "time_ms": 1234},
{"name": "search_hotels", "status": "completed", "time_ms": 1456},
{"name": "summarize_options", "status": "completed", "time_ms": 2345}
]
}
}
Plan Status
GET /api/v1/plan/{id}
Get the status of a previously submitted plan.
Request:
curl http://localhost:8081/api/v1/plan/plan_xyz789
Response (200 OK):
{
"plan_id": "plan_xyz789",
"status": "completed",
"query": "Plan a business trip from San Francisco to Paris",
"domain": "travel",
"steps": [
{
"id": "step_1_search_flights",
"name": "search_flights",
"status": "completed"
}
],
"result": "I found excellent options for your Paris trip..."
}
POST /api/v1/plan/execute
Execute a previously generated plan (two-step MAP flow). Use this when you want to review a plan before executing it.
Request:
curl -X POST http://localhost:8081/api/v1/plan/execute \
-H "Content-Type: application/json" \
-d '{
"plan_id": "plan_xyz789",
"user": {
"id": 123,
"email": "[email protected]",
"role": "user"
}
}'
Unified Execution API
The Unified Execution API provides a single interface for tracking both MAP plans and WCP workflows. It includes status queries and cancellation.
Base URL: http://localhost:8081 (Orchestrator)
CORS: All endpoints respond to OPTIONS preflight requests with Access-Control-Allow-Origin: * and allow GET, POST, OPTIONS methods with Content-Type, Authorization, X-Tenant-ID, and X-Org-ID headers.
GET /api/v1/unified/executions
List executions across both MAP plans and WCP workflows.
Request:
curl "http://localhost:8081/api/v1/unified/executions?limit=20&execution_type=wcp_workflow"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results (default: 20, max: 100). Invalid values fall back to default. |
offset | integer | Pagination offset (default: 0). Invalid values fall back to default. |
execution_type | string | Filter by type: map_plan or wcp_workflow |
status | string | Filter by status (see Execution Status Values) |
Headers:
| Header | Required | Description |
|---|---|---|
X-Tenant-ID | No | Filter by tenant ID (multi-tenancy) |
X-Org-ID | No | Filter by organization ID |
Response (200 OK):
{
"executions": [
{
"execution_id": "wf_abc123",
"execution_type": "wcp_workflow",
"name": "data-pipeline",
"status": "running",
"progress_percent": 66.7,
"total_steps": 3,
"current_step_index": 2,
"started_at": "2026-02-06T10:00:00Z",
"created_at": "2026-02-06T10:00:00Z",
"updated_at": "2026-02-06T10:00:03Z"
}
],
"total": 1,
"limit": 20,
"offset": 0,
"has_more": false
}
The has_more field indicates whether additional pages of results exist beyond the current offset.
GET /api/v1/unified/executions/{id}
Get detailed status of a specific execution. The {id} parameter accepts:
- An execution ID (direct lookup)
- A WCP workflow ID (prefix
wf_orwcp_) - A MAP plan ID (prefix
plan_)
The API tries multiple lookup strategies and returns the first match.
Request:
curl http://localhost:8081/api/v1/unified/executions/wf_abc123
Response (200 OK):
{
"execution_id": "wf_abc123",
"execution_type": "wcp_workflow",
"name": "data-pipeline",
"source": "crewai",
"status": "running",
"current_step_index": 2,
"total_steps": 3,
"progress_percent": 66.7,
"started_at": "2026-02-06T10:00:00Z",
"duration": "5s",
"steps": [
{
"step_id": "step-1",
"step_index": 0,
"step_name": "Fetch Data",
"step_type": "tool_call",
"status": "completed",
"started_at": "2026-02-06T10:00:00Z",
"ended_at": "2026-02-06T10:00:01Z",
"duration": "1s",
"decision": "allow",
"model": "gpt-4",
"provider": "openai"
},
{
"step_id": "step-2",
"step_index": 1,
"step_name": "Process Data",
"step_type": "llm_call",
"status": "completed",
"started_at": "2026-02-06T10:00:01Z",
"ended_at": "2026-02-06T10:00:03Z",
"duration": "2s",
"decision": "allow",
"model": "gpt-4",
"provider": "openai"
},
{
"step_id": "step-3",
"step_index": 2,
"step_name": "Store Results",
"step_type": "tool_call",
"status": "running",
"started_at": "2026-02-06T10:00:03Z"
}
],
"metadata": {
"workflow_id": "wf_abc123"
},
"created_at": "2026-02-06T10:00:00Z",
"updated_at": "2026-02-06T10:00:03Z"
}
Example: WCP step with policy gate and approval flow:
{
"step_id": "gate-1",
"step_index": 0,
"step_name": "Policy Evaluation",
"step_type": "gate",
"status": "approval",
"started_at": "2026-02-06T10:00:00Z",
"decision": "require_approval",
"decision_reason": "Query accesses PII columns in production database",
"policies_matched": ["pii-protection", "prod-data-access"],
"approval_status": "pending",
"model": "gpt-4",
"provider": "openai",
"result_summary": "Awaiting manager approval for PII data access"
}
ExecutionStatus field reference:
| Field | Type | Omitted when empty |
|---|---|---|
execution_id | string | No |
execution_type | string | No |
name | string | No |
source | string | Yes |
status | string | No |
current_step_index | integer | No |
total_steps | integer | No |
progress_percent | float | No |
started_at | datetime | No |
completed_at | datetime | Yes |
duration | string | Yes |
steps | array | Yes |
error | string | Yes |
tenant_id | string | Yes |
org_id | string | Yes |
user_id | string | Yes |
client_id | string | Yes |
estimated_cost_usd | float | Yes |
actual_cost_usd | float | Yes |
metadata | object | Yes |
created_at | datetime | No |
updated_at | datetime | No |
StepStatus field reference:
| Field | Type | Omitted when empty |
|---|---|---|
step_id | string | No |
step_index | integer | No |
step_name | string | No |
step_type | string | No |
status | string | No |
started_at | datetime | Yes |
ended_at | datetime | Yes |
duration | string | Yes |
decision | string | Yes |
decision_reason | string | Yes |
policies_matched | string[] | Yes |
approval_status | string | Yes |
approved_by | string | Yes |
approved_at | datetime | Yes |
model | string | Yes |
provider | string | Yes |
input | object | Yes |
output | object | Yes |
cost_usd | float | Yes |
result_summary | string | Yes |
error | string | Yes |
GET /api/v1/unified/executions/{id}/stream
Stream real-time execution status updates via Server-Sent Events (SSE). The connection sends the current execution state immediately on connect, then pushes events as the execution progresses. The server closes the connection when the execution reaches a terminal state (completed, failed, cancelled, aborted, expired).
Request:
curl -N http://localhost:8081/api/v1/unified/executions/wf_abc123/stream \
-H "Accept: text/event-stream"
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Execution ID, WCP workflow ID, or MAP plan ID |
Headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Basic base64(clientId:clientSecret) |
X-Tenant-ID | No | Tenant ID (used for per-tenant connection limits) |
Response Headers:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
SSE Event Format:
Each event follows the standard SSE format with id, event, and data fields:
id: 1707220800000
event: execution.started
data: {"execution_id":"wf_abc123","execution_type":"wcp_workflow","name":"data-pipeline","status":"running",...}
The data payload is the full ExecutionStatus JSON object (same schema as the GET endpoint).
Event Types:
| Event | Description |
|---|---|
status | Initial execution state sent on connect |
execution.started | Execution has begun |
execution.completed | Execution completed successfully (terminal) |
execution.failed | Execution failed (terminal) |
execution.cancelled | Execution was cancelled (terminal) |
step.started | A step has started executing |
step.completed | A step completed successfully |
step.failed | A step failed |
step.decision | A policy gate decision was made on a step |
Connection Lifecycle:
- Client connects; server sends the current state as a
statusevent - If the execution is already terminal, the server closes the connection immediately
- While running, the server pushes events as execution state changes
- A
:keepaliveSSE comment is sent every 15 seconds to prevent proxy idle timeouts - On terminal event (
execution.completed,execution.failed,execution.cancelled), the server closes the connection - If the client disconnects, the server cleans up the subscription
Connection Limits:
In community mode, each tenant is limited to 5 concurrent SSE connections. Enterprise mode has no limit. Exceeding the limit returns 429 Too Many Requests.
Error Responses:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Missing execution ID |
| 404 | NOT_FOUND | Execution not found |
| 429 | TOO_MANY_REQUESTS | Per-tenant SSE connection limit reached |
| 500 | INTERNAL_ERROR | Streaming not supported or lookup failure |
| 503 | SERVICE_UNAVAILABLE | Event streaming not available |
POST /api/v1/unified/executions/{id}/cancel
Cancel a running execution. Propagates to the appropriate subsystem:
- WCP workflows are aborted via
AbortWorkflow - MAP plans are cancelled via
CancelPlan
Request:
curl -X POST http://localhost:8081/api/v1/unified/executions/wf_abc123/cancel \
-H "Content-Type: application/json" \
-d '{"reason": "no longer needed"}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for cancellation (default: "cancelled via unified API") |
Response (200 OK):
Returns the full updated ExecutionStatus object (same schema as the GET endpoint):
{
"execution_id": "wf_abc123",
"execution_type": "wcp_workflow",
"name": "data-pipeline",
"status": "cancelled",
"current_step_index": 1,
"total_steps": 3,
"progress_percent": 33.3,
"started_at": "2026-02-06T10:00:00Z",
"completed_at": "2026-02-06T10:00:05Z",
"duration": "5s",
"steps": [...],
"created_at": "2026-02-06T10:00:00Z",
"updated_at": "2026-02-06T10:00:05Z"
}
Error Responses:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Missing execution ID or unknown execution type |
| 404 | NOT_FOUND | Execution not found |
| 409 | CONFLICT | Execution already in terminal state |
| 500 | INTERNAL_ERROR | Subsystem cancellation failed |
Execution Status Values
Workflow Status
| Value | Description |
|---|---|
pending | Execution queued but not started |
running | Execution in progress |
completed | All steps completed successfully |
failed | One or more steps failed |
cancelled | Execution was cancelled via the cancel endpoint |
aborted | WCP workflow aborted (e.g., policy violation) |
expired | MAP plan expired before execution started |
Step Status Values
| Status | Description |
|---|---|
pending | Step not yet started |
running | Step currently executing |
completed | Step completed successfully |
failed | Step failed |
skipped | Step was skipped |
blocked | Step blocked by policy (WCP) |
approval | Step waiting for human approval (WCP) |
Step Types
| Type | Description |
|---|---|
llm_call | LLM provider invocation |
tool_call | External tool or function call |
connector_call | MCP connector invocation |
human_task | Human-in-the-loop task |
synthesis | MAP result synthesis step |
action | Generic action step |
gate | WCP policy gate evaluation |
Execution Flow
- Workflow enters
pendingstatus when submitted - Steps with no dependencies start in parallel (status:
running) - Steps with
depends_onwait until all dependencies arecompleted - If any step fails and has no error handler, the workflow status becomes
failed - On success of all steps, the workflow status becomes
completed
Gate Decisions
Policy gate decisions on steps (WCP):
| Decision | Description |
|---|---|
allow | Step allowed to proceed |
block | Step blocked by policy |
require_approval | Step requires human approval before proceeding |
Approval Status
Approval state when a step has decision: "require_approval":
| Status | Description |
|---|---|
pending | Awaiting approval |
approved | Approved by a user |
rejected | Rejected by a user |
Error Responses
All error responses use a consistent format:
{
"error": {
"code": "NOT_FOUND",
"message": "Execution not found: exec-123"
}
}
Workflow API errors:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | INVALID_WORKFLOW | Workflow definition is invalid |
| 400 | MISSING_USER_CONTEXT | User context required for governance |
| 404 | EXECUTION_NOT_FOUND | Workflow execution not found |
| 404 | PLAN_NOT_FOUND | Plan does not exist |
| 500 | PLANNING_FAILED | LLM planning engine failed |
| 504 | EXECUTION_TIMEOUT | Workflow exceeded timeout |
Example (400):
{
"error": {
"code": "INVALID_WORKFLOW",
"message": "Workflow spec.steps must contain at least one step"
}
}
Example (404):
{
"error": {
"code": "EXECUTION_NOT_FOUND",
"message": "Workflow execution 'wf_exec_invalid' not found"
}
}
Example (504):
{
"error": {
"code": "EXECUTION_TIMEOUT",
"message": "Workflow 'travel-booking' exceeded 60s timeout at step 'search_flights'"
}
}
Unified Execution API errors:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Missing or invalid execution ID |
| 404 | NOT_FOUND | Execution not found |
| 409 | CONFLICT | Execution already in terminal state (cancel only) |
| 500 | INTERNAL_ERROR | Internal server error |
Next Steps
- Agent Endpoints - Policy enforcement API
- MCP Connectors - Configure data connectors
- Integration Guides - Framework integrations