Workflows API
Starting, signalling, suspending and resuming long-running processes, plus the admin surface.
For concepts and configuration see the block documentation.
Driving an instance
Section titled “Driving an instance”| Endpoint | Purpose |
|---|---|
POST /workflow/start | Begin an instance |
GET /workflow/status | Where an instance has reached |
POST /workflow/signal | Deliver a signal — addressed to one instance |
POST /workflow/event | Deliver an event — broadcast to instances waiting on it |
POST /workflow/resume | Resume a suspended instance |
POST /workflow/cancel | Stop an instance |
GET /workflow/logs | Execution history for an instance |
GET /workflow/config | Definitions loaded for this tenant |
GET /workflow/queue | Queued work |
Signal or event? A signal is addressed to one instance and usually carries a human decision — you send it because you know which instance you are answering. An event is broadcast and wakes whichever instances are waiting on it — you send it because a fact changed. Choosing wrong is the usual cause of an instance that hangs forever.
GET /workflow/config is worth checking after a deploy: a definition that failed to load
produces no error until something tries to use it.
Administration
Section titled “Administration”| Endpoint | Purpose |
|---|---|
GET /admin/agents | Connected workers |
GET /admin/agents/{id} | One worker |
GET /admin/instances | Running instances |
GET /admin/queue | The work queue |
GET /admin/queue/{id} | One queued item |
/admin/instances is the first place to look when a process appears stuck. An instance in a
wait state is usually correct — waiting for a signal nobody sent — and telling that apart
from a wedged instance is what the endpoint is for.
Authentication
Section titled “Authentication”Every route requires a bearer token. One route also accepts an API key:
| Route | Accepts |
|---|---|
GET /workflow/config | An API key or a bearer token |
| Everything else | A bearer token only |
A missing or invalid token is 401 with a plain-text body (Unauthorized), not the JSON error
envelope — branch on the status before parsing.
Authorization
Section titled “Authorization”Authentication only proves who you are. Each /workflow/* route is additionally gated by a
per-tenant access rule, evaluated as JavaScript, and each route has its own rule name:
| Route | Rule name |
|---|---|
POST /workflow/start | workflow.start |
POST /workflow/resume | workflow.resume |
POST /workflow/event | workflow.resume |
POST /workflow/signal | workflow.signal |
POST /workflow/cancel | workflow.cancel |
GET /workflow/status | workflow.status |
GET /workflow/logs | workflow.logs |
GET /workflow/config | workflow.config |
GET /agents | agents.list |
GET /workflow/queue | queue.status |
DELETE /workflow/queue/{id} | queue.cancel |
Lookup falls back: the named rule, then authorization.admin, then the service default. Rule code
receives user.id, user.email, user.roles, user.is_superadmin, tenant and action, and
returning a truthy value allows the request.
A denial is 403 with {"message": "access denied"} — also not the standard envelope.
The /admin/* routes do not use the rule engine. They require a superadmin token and are
checked separately, so a tenant access rule can neither grant nor revoke them.
Tenancy
Section titled “Tenancy”Every request carries the four platform tenancy headers — X-Customer, X-Product, X-Env and
X-Tenant. They are the partition key for storage, quotas and audit, and they also select which
tenant’s access rules apply, so a request without them is rejected rather than served against a
default tenant.
Errors
Section titled “Errors”| Status | Body | Raised by |
|---|---|---|
400 | JSON error envelope | Request parse and validation — the most common failure by far |
401 | Plain text Unauthorized | Missing or invalid token |
403 | {"message": "access denied"} | An access rule denied the request, or no rules exist in deny-by-default mode |
500 | JSON error envelope | Unexpected server error |
Three shapes across four statuses. A client must branch on the status code first — only 400 and
500 carry the standard envelope.