Skip to content

Workflows API

Base path: /api/workflows

All endpoints require authentication. See API Overview for auth details.

GET /api/workflows

Query parameters: status, trigger_type, tag, limit (max 200), offset

Response:

{
"workflows": [
{
"id": "wf_abc123",
"name": "Data pipeline",
"version": 3,
"status": "active",
"trigger_type": "manual",
"tags": ["data", "etl"],
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-03-01T00:00:00Z"
}
],
"total": 5
}
POST /api/workflows
{
"definition": {
"name": "Fetch and notify",
"steps": [
{
"id": "fetch",
"type": "http_request",
"config": {
"method": "GET",
"url": "https://api.example.com/data"
}
},
{
"id": "notify",
"type": "agent_task",
"config": {
"agent_id": "agent_123",
"goal": "Summarize the fetched data and post to Slack"
},
"depends_on": ["fetch"]
}
]
},
"trigger_type": "manual",
"tags": ["notifications"]
}

Returns 201 with {"id": "wf_abc123", "workflow": {...}}.

GET /api/workflows/{id}
PUT /api/workflows/{id}
{
"definition": {...},
"change_summary": "Added error handling step"
}
DELETE /api/workflows/{id}
PATCH /api/workflows/{id}/status
{"status": "paused"}

Valid statuses: draft, active, paused, archived

POST /api/workflows/validate

Validate a workflow definition without creating it:

{"definition": {...}}

Response:

{
"valid": true,
"errors": []
}

Errors example:

{
"valid": false,
"errors": [
"Step 'notify' depends on 'fetch' which doesn't exist",
"Cycle detected: step_a → step_b → step_a"
]
}
GET /api/workflows/{id}/versions

Response:

{
"versions": [
{"version": 3, "change_summary": "Added error step", "created_at": "..."},
{"version": 2, "change_summary": "Fixed URL", "created_at": "..."},
{"version": 1, "change_summary": "Initial version", "created_at": "..."}
]
}
GET /api/workflows/{id}/versions/{version}

Returns the full workflow definition at that version.

GET /api/workflows/{id}/diff?v1=1&v2=3

Response:

{
"diff": [
{"op": "add", "path": "/steps/2", "value": {...}},
{"op": "replace", "path": "/steps/0/config/url", "value": "https://new-url.com"}
],
"summary": "Added 1 step, modified 1 step",
"v1": 1,
"v2": 3
}
POST /api/workflows/{id}/rollback
{"version": 2}

Returns the workflow after rollback. Creates a new version entry.

POST /api/workflows/{id}/run
{
"input_data": {"dataset_id": "ds_123"},
"trigger": "manual"
}

Returns 202 immediately:

{"run_id": "run_abc123"}

The workflow executes asynchronously. Use the run ID to track progress.

Concurrent run limit: configurable via WORKFLOW_MAX_CONCURRENT_RUNS (default: 10).

GET /api/workflows/{id}/runs

Query: status, limit, offset

GET /api/workflows/runs/{run_id}

Response includes step-by-step results:

{
"run": {
"id": "run_abc123",
"workflow_id": "wf_abc123",
"status": "completed",
"trigger": "manual",
"started_at": "2026-03-02T14:00:00Z",
"completed_at": "2026-03-02T14:01:23Z",
"duration_seconds": 83,
"step_runs": [
{
"step_id": "fetch",
"status": "completed",
"output": {"status_code": 200, "body": {...}},
"started_at": "...",
"duration_seconds": 1
},
{
"step_id": "notify",
"status": "completed",
"output": "Posted summary to #general",
"started_at": "...",
"duration_seconds": 82
}
]
}
}
POST /api/workflows/runs/{run_id}/cancel
POST /api/workflows/runs/{run_id}/resume
{"from_step": "notify"}

Omit from_step to resume from the last checkpoint.

DELETE /api/workflows/runs/{run_id}
GET /api/workflows/runs/{run_id}/stream

Server-Sent Events stream:

event: step_started
data: {"run_id":"run_abc123","step_id":"fetch","timestamp":"..."}
event: step_completed
data: {"run_id":"run_abc123","step_id":"fetch","output":{...}}
event: run_completed
data: {"run_id":"run_abc123","status":"completed","duration_seconds":83}
GET /api/workflows/templates

Query: category, is_builtin, limit, offset

GET /api/workflows/templates/{id}

Install a template (create workflow from template)

Section titled “Install a template (create workflow from template)”
POST /api/workflows/templates/{id}/install
{"name": "My custom pipeline"}

Returns 201 with {"workflow_id": "wf_abc123"}.

GET /api/workflows/{id}/schedules
POST /api/workflows/{id}/schedules
{
"cron_expression": "0 9 * * 1-5",
"timezone": "America/New_York",
"input_data": {"dataset": "daily"}
}

Returns 201 with {"schedule_id": "sched_abc123"}.

DELETE /api/workflows/schedules/{id}
TypeDescription
http_requestMake an HTTP API call
scriptRun a shell or Python script
agent_taskDelegate to an AI agent
conditionBranch based on an expression
loopIterate over a list
waitPause for duration or condition
webhookEmit an outbound HTTP request