API reference
12 operations in workflows. Raw spec: openapi.json.
/api/v1/workflows/authorPOST /api/workflows/author — author a workflow draft from a sentence.
Admin-gated (Edit). NOT a write: it returns a draft, its issues and the diff, and persists nothing. The completion rides the shared AI admission path with the completion + tool-calling edges.
Request body
AuthorWorkflowRequest
Responses
| Status | Description |
|---|---|
200 | |
403 | AI admission refused (typed reason in the envelope) |
422 | the request or the base document did not validate |
Security: bearer
/api/v1/workflows/documentsGET /api/workflows/documents
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/documentsPOST /api/workflows/documents — the document is validated before storage (see [`validate_definition`]); the row is created as revision 1.
Request body
CreateWorkflowDocumentRequest
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/documents/{id}GET /api/workflows/documents/{id}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | document not visible in scope |
Security: bearer
/api/v1/workflows/documents/{id}PATCH /api/workflows/documents/{id} — replacing the document validates it and advances the revision.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
UpdateWorkflowDocumentRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | document not visible in scope |
Security: bearer
/api/v1/workflows/nodesGET /api/workflows/nodes — the catalogue, filtered. Declarations carry no org data, so any authed org member may read; each consuming surface keeps its own data gates.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
audience | query | — | No | Which audience's slice to return: `human` (the palette) or `ai` (the LLM tool catalogue). Defaults to `human`. |
tier | query | — | No | Restrict to one tier: `a`, `b` or `c`. Defaults to every tier. |
family | query | — | No | Restrict to one family: `trigger`, `decision`, `condition`, `action`, `control` or `value`. |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/nodes/{id}GET /api/workflows/nodes/{id} — one node with both schemas parsed. The on-demand schema leg the authoring model uses, so exposing the catalogue to a prompt costs one call per node it actually needs rather than the whole catalogue inlined.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Node id, e.g. ticket.create |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/plugin-nodesGET /api/workflows/plugin-nodes — the org's plugin-contributed workflow nodes, parsed through the same contract the registry uses.
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/runsGET /api/workflows/runs — the run ledger, newest first, filterable by status and by rule. Keyset-cursored on `(created_at, id)`, exactly like the webhook delivery ledger: the two logs page and behave alike.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | — | No | Optional status filter: running | waiting | succeeded | failed | abandoned. |
rule_id | query | — | No | Optional rule filter: only that workflow's runs. |
cursor | query | — | No | Cursor from the previous page's `next_cursor`. |
limit | query | — | No | Page size (default 50, capped at 200). |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
/api/v1/workflows/runs/{id}GET /api/workflows/runs/{id} — one run with its whole trace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | run not visible in scope |
Security: bearer
/api/v1/workflows/runs/{id}/retryPOST /api/workflows/runs/{id}/retry — re-run a failed run as a NEW row.
The refusal is the point: if re-running would repeat a step that declares `idempotent = false`, the answer is a typed 409 that names every offending node rather than a second ticket or a second email. The idempotency key (IF1) is claimed before anything is written, so a double-submit returns the first retry instead of queueing two.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
RetryRunRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | run not visible in scope |
409 | not retryable, or a repeat would double-apply |
422 | unknown retry mode |
Security: bearer
/api/v1/workflows/runs/{id}/stepsGET /api/workflows/runs/{id}/steps — one run's step trace, paged.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor | query | — | No | |
limit | query | — | No | |
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | run not visible in scope |
Security: bearer