Skip to content
Talk to our solutions team

HTTP API

All routes are tenant-scoped via the four CPET headers (X-Customer, X-Product, X-Env, X-Tenant) and require a Bearer token. A CPET that resolves to no configured tenant returns 400.

MethodPathPurpose
POST/workflow/startStart a run
POST/workflow/signalDeliver a named signal to a waiting instance
POST/workflow/resumeResume a specific node — {instanceid, node, data}
POST/workflow/eventResume by event id — {instanceid, event, data}
POST/workflow/cancelCancel a run — {instanceid}
GET/workflow/status?instanceid=Current instance status
GET/workflow/logs?instanceid=Merged, time-sorted instance + node event log
GET/workflow/config?id=|name=|path=A definition’s type and declared variables. Accepts an API key or a Bearer token
Terminal window
curl -X POST https://<host>/workflow/start \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "X-Customer: acme" -H "X-Product: shop" -H "X-Env: prod" -H "X-Tenant: eu" \
-d '{"workflowname":"order-approval","context":{"order_id":"1234"}}'

Identify the definition with exactly one of:

FieldMeaning
workflowidDefinition id
workflownameDefinition name
workflowpathDefinition path — fetched from meta if not already loaded
workflowA full inline definition, registered on the fly

Other fields:

FieldTypePurpose
contextobjectRun variables, available to tasks as {{var}}
starttaskstringOverride the first node
taskliststring[]Restrict execution to a subset of tasks
selectorsobjectPer-task agent requirements, e.g. {"train": {"tag": "gpu"}}
workertag / tag, modelstringAgent routing shorthands
workeridstring[]Pin to specific agents
workeridsobjectPer-task agent map
workerdomainstringResolve an agent by infrastructure address
affinitystringnone / single-agent / instance / definition / payload
affinity-keystring[]Payload fields for payload-scoped affinity
pin-agentboolShorthand for affinity: single-agent
restart-on-failureboolRestart rather than resume when an agent dies

Query ?user=true injects the caller’s identity into task context.

Responses:

// 200 — dispatched
{ "message": "...", "instanceid": "01K…", "status": "executing", "workflowid": "" }
// 202 — accepted but queued (no agent free); same shape, status "queued"
{ "message": "...", "instanceid": "01K…", "status": "queued", "workflowid": "" }

Failure responses:

StatusMeaningHeader
503No agent is currently freeRetry-After: 5
429The overflow queue is fullRetry-After: 10
400No agent matches the requested selectors, or the definition/tenant is invalid

503 and 429 are both retryable — the run was not started. 400 on selectors means no agent in the fleet can ever satisfy them, so retrying won’t help.

Terminal window
curl -X POST https://<host>/workflow/signal \
-H "Authorization: Bearer $TOKEN" $H \
-d '{"instanceid":"01K…","signal_name":"approved","data":{"approver_name":"Dana"}}'

The signal name must match an event declared on the Wait node, and any fields that event lists under required must be present. Response: {"success": true}.

MethodPathReturns
GET/agentsAgents serving this tenant: {agents:[{id, version, status, type, domain, grpcaddress, httpaddress, healthy, tags?, capabilities?}]}
GET/workflow/queueThis tenant’s queued work: {total_pending, items[]}
DELETE/workflow/queue/:idCancel one queued item. 403 if it belongs to another tenant, 404 if unknown

Requires a control-plane token. These are cross-tenant.

MethodPathReturns
GET/admin/agents?tenant=All agents, with tenants[], exclusive, max_concurrent_tasks
GET/admin/agents/:idOne agent including full metadata
GET/admin/queue?tenant=&status=Queue across tenants, plus pending_by_tenant
DELETE/admin/queue/:idCancel any queued item, bypassing the tenant check
GET/admin/instances?tenant=Instances grouped by tenant

Mounted at clean paths: /rest/* (entity CRUD), /schema/* (including openapi.json, jsonschema, graphql, cue, zod), /admin/data/* (migration plans, seeds, retention, locks), and /superadmin/tenant/*. Applying a plan, retention, and lock force-release all require superadmin.

GET /health and GET /ready — unauthenticated, no CPET headers required.