Skip to content
Select themeSelect language

`GET /api/workflows/{id}` — get one workflow with its ordered steps.

GET
/api/workflows/{id}
curl --request GET \
--url https://example.com/api/workflows/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0
id
required
string format: uuid

Workflow id

Media typeapplication/json

A workflow plus its graph — the GET/PUT /api/workflows/{id} body.

steps keeps the v1 agent-only wire shape (every agent node in ordinal order with depends_on rebuilt from the edge set) so older callers keep working. nodes + edges is the typed-node graph the V8 builder consumes: every node kind with its config, position and handle-carrying edges.

object
created_at
required
string format: date-time
edges
required
Array<object>

One directed edge as returned to the client (ADR 0020 V8) — a connection from source’s source_handle output into target.

object
id
required
string format: uuid
source
required
string
source_handle
required
string
target
required
string
id
required
string format: uuid
max_concurrent_runs

Issue #110: per-workflow concurrency cap; None = unlimited.

integer | null format: int32
name
required
string
nodes
required
Array<object>

One typed node as returned to the client (ADR 0020 V8). Carries the node’s kind, its kind-specific config blob and its canvas position — the shape the Svelte Flow builder renders directly.

object
config
required
id
required
string format: uuid
key
required
string
kind
required

The node kind (node.kind, workflow_nodes.kind CHECK). Runtime stays String; the spec narrows it to the closed [workflow_svc::NodeKindSpec].

string
Allowed values: agent gate human end code notify_telegram notify_email notify_webhook notify_discord loop db_query db_execute http_request transform wait_event llm_classify imap_ack app connector
ordinal
required
integer format: int32
parent_node_key

WP V16: when set, this node lives INSIDE the named loop frame’s sub-graph. The V8 builder wires up parentId / extent: 'parent' on Svelte Flow nodes carrying this field.

string | null
position
required

A node’s canvas position in a response body.

object
x
required
number format: double
y
required
number format: double
project_id
required
string format: uuid
steps
required
Array<object>

A workflow step (an agent node) as returned to the client.

ADR 0020 reshapes the schema to typed nodes + edges; this DTO keeps the v1 agent-step wire shape (step_key + depends_on) so the existing web canvas stays functional — depends_on is rebuilt from the node’s incoming edges.

object
agent_type
required
string
depends_on
required
Array<string>
id
required
string format: uuid
kind
required

The node kind (node.kind, workflow_nodes.kind CHECK). Runtime stays String; the spec narrows it to the closed [workflow_svc::NodeKindSpec].

string
Allowed values: agent gate human end code notify_telegram notify_email notify_webhook notify_discord loop db_query db_execute http_request transform wait_event llm_classify imap_ack app connector
on_failure
required
string
ordinal
required
integer format: int32
prompt_template
required
string
step_key
required
string
Example
{
"nodes": [
{
"kind": "agent"
}
],
"steps": [
{
"kind": "agent"
}
]
}

Structured client error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Authentication required

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Permission denied

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Workflow not found

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Structured server error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}