Executions
Monitor and control workflow executions. Each execution represents a single run of a workflow, including its status, progress, node-level spans, and logs.
All endpoints require authentication via X-API-Key header and the appropriate scope.
Execution Object
{
"_id": "exec_xyz789",
"workflowId": "wf_abc123",
"workflowVersionId": null,
"workflowVersionNumber": null,
"workflowVersionSource": "working-copy",
"userId": "user_456",
"ownerId": "user_456",
"organizationId": "org_xyz",
"status": "completed",
"runEnvironment": "development",
"triggerType": "manual",
"triggerInputs": {},
"definition": {
"nodes": [],
"connections": []
},
"outputs": {
"mysql-a1B2c3": { "rowCount": 1500 }
},
"errorMessage": null,
"createdAt": "2025-02-01T14:22:00Z",
"startedAt": "2025-02-01T14:22:00Z",
"endedAt": "2025-02-01T14:25:30Z",
"durationMs": 210000,
"updatedAt": "2025-02-01T14:25:30Z"
}
userId is the user who started the run (the audit trail). ownerId is the user the run belongs to for every usage figure: the user who deployed the workflow for a deployed run, the user who ran it for a draft run. See Who usage belongs to.
definition is the workflow's nodes and connections as they were when the run started. outputs holds each node's output keyed by node ID once the run has finished. errorMessage is set when the run fails, and for partial_success names each failed node and each loop's failed item count. workflowVersionSource is working-copy for a run of the draft, deployed for a run of a deployed version (with workflowVersionId and workflowVersionNumber set), or unversioned-deployment. The list endpoint leaves out definition.
Run Statuses
| Status | Finished | Meaning |
|---|---|---|
pending | No | Queued, not started yet |
running | No | Nodes are running. A run waiting on a person (Wait for Input, Human Feedback, Human Checkpoint) is running with a pending request (see GET …/human-requests) |
completed | Yes | Every node finished and produced its output, and every loop delivered all its items |
completed_with_gaps | Yes | The run reached the end, but some nodes produced no output. The Runs list shows it as a warning, "Completed with gaps" |
partial_success | Yes | The run finished but not everything succeeded: a node failed under continueOnError, or a loop, map or distributed loop delivered only some of its items. errorMessage names each failed node with its error and each loop with how many of its items failed. The Runs list shows it as a warning, "Partial success" |
failed | Yes | A node failed without continueOnError, or a loop had items and delivered none of them |
error | Yes | The run could not start or was ended by a platform error |
stopped | Yes | Stopped by a user |
cancelled | Yes | Cancelled by a user |
timeout | Yes | Ran past its time limit |
A finished run never changes status again. For completed_with_gaps and partial_success, read the run's spans to see which nodes or items produced nothing.
Span Object
{
"_id": "span_001",
"executionId": "exec_xyz789",
"workflowId": "wf_abc123",
"parentSpanId": null,
"nodeId": "mysql-a1B2c3",
"nodeType": "mysql",
"category": "sources",
"spanType": "NODE",
"name": "mysql:mysql-a1B2c3",
"status": "completed",
"startTime": "2025-02-01T14:22:01Z",
"endTime": "2025-02-01T14:22:45Z",
"durationMs": 44000,
"inputData": {},
"configData": {},
"mappedInput": {},
"outputData": {
"rowCount": 1500
},
"errorMessage": null,
"errorStack": null,
"metadata": {},
"createdAt": "2025-02-01T14:22:01Z",
"updatedAt": "2025-02-01T14:22:45Z"
}
Log Object
{
"_id": "log_001",
"executionId": "exec_xyz789",
"timestamp": "2025-02-01T14:22:45Z",
"level": "INFO",
"message": "Successfully extracted 1500 rows from orders table",
"nodeId": "mysql-a1B2c3",
"createdAt": "2025-02-01T14:22:45Z"
}
This is a log line written by a node while it runs. The platform's own entries about the run (for example "Test execution started") have a different shape: workflowId, executionId, level in lower case, message, userId and createdAt.
GET /api/v1/workflows/-/executions
List executions with optional filtering.
Scope: workflows:read
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workflowId | string | No | Filter by workflow ID |
status | string | No | Filter by status, one of the run statuses |
triggerType | string | No | Filter by trigger type: manual, schedule, webhook, api |
since | string | No | ISO 8601 datetime. Return executions started after this time |
until | string | No | ISO 8601 datetime. Return executions started before this time |
limit | integer | No | Number of results to return (default: 50, max: 200) |
cursor | string | No | meta.nextCursor of the previous page; omit for the first page |
sort | string | No | Sort field, prefix with - for descending (default: -created_at, newest first) |
Runs that share a sort value are ordered by _id, so paging with limit and cursor returns each run once.
Response 200 OK
{
"data": [
{
"_id": "exec_xyz789",
"workflowId": "wf_abc123",
"userId": "user_456",
"ownerId": "user_456",
"organizationId": "org_xyz",
"status": "completed",
"runEnvironment": "development",
"triggerType": "manual",
"triggerInputs": {},
"createdAt": "2025-02-01T14:22:00Z",
"startedAt": "2025-02-01T14:22:00Z",
"endedAt": "2025-02-01T14:25:30Z",
"durationMs": 210000,
"updatedAt": "2025-02-01T14:25:30Z"
}
],
"meta": {
"total": 156,
"limit": 50,
"nextCursor": "eyJvIjo1MH0",
"requestId": "req_abc123"
}
}
GET /api/v1/workflows/-/executions/:id
Get a single execution by ID, including the full workflow definition that was used.
Scope: workflows:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Response 200 OK
Returns the full Execution object, including definition.
{
"data": {
"_id": "exec_xyz789",
"workflowId": "wf_abc123",
"userId": "user_456",
"ownerId": "user_456",
"organizationId": "org_xyz",
"status": "completed",
"triggerType": "manual",
"triggerInputs": {},
"definition": {
"nodes": [],
"connections": []
},
"outputs": {
"mysql-a1B2c3": { "rowCount": 1500 }
},
"createdAt": "2025-02-01T14:22:00Z",
"startedAt": "2025-02-01T14:22:00Z",
"endedAt": "2025-02-01T14:25:30Z",
"durationMs": 210000,
"updatedAt": "2025-02-01T14:25:30Z"
},
"meta": {
"requestId": "req_abc123"
}
}
POST /api/v1/workflows/-/executions/:id/stop
Stop a running execution. Its pods are removed, and the run ends stopped.
Scope: workflows:execute
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Response 200 OK: the execution, as GET /workflows/-/executions/:id shows it, status stopped.
Error 409 Conflict
Returned if the execution is not in running status. To end a run that is still pending, use cancel.
{
"type": "urn:strongly:problem:invalid-state",
"title": "invalid-state",
"status": 409,
"detail": "Cannot stop execution with status: completed",
"code": "invalid-state",
"requestId": "req_abc123"
}
POST /api/v1/workflows/-/executions/:id/cancel
Cancel a run that has not finished (pending or running). Its pods are removed and the run ends cancelled. Cancelling a run that has already finished changes nothing: the execution is returned as it ended.
Scope: workflows:execute
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Response 200 OK: the execution, as GET /workflows/-/executions/:id shows it, status cancelled (or the status it had already ended with).
POST /api/v1/workflows/-/executions/:id/resume
Resume a paused or stopped execution.
Scope: workflows:execute
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Request Body
{
"triggerData": {
"key": "value"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
triggerData | object | No | Additional data to pass when resuming |
Response 200 OK
The execution, as GET /workflows/-/executions/:id shows it, running again from its last checkpoint.
POST /api/v1/workflows/-/executions/:executionId/human-requests/:id/respond
Answer a pending request of a running execution (:id is the request's requestId): the data a Wait for Input node waits for, a Human Feedback answer, or a Human Checkpoint decision. Find the request with GET …/human-requests. The node reads the answer within seconds and the run continues. The respondent is the API key's user. A request is answered once.
Scope: workflows:execute
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
executionId | string | Yes | Execution ID |
id | string | Yes | The pending request's requestId |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
data | any | Yes | The answer, shaped by the request's type (below) |
Request type | data |
|---|---|
input | Any JSON value. When the node has an Input Schema, the value must match it |
feedback | text: a string. rating: a number from 1 to ratingScale. choice: one of choices. form: an object with every required form field |
checkpoint | { "decision": "approved" or "rejected", "message": "...", "input": { <input field key>: value } }. input must hold every required input field. When the checkpoint names approvers, only they can decide |
{
"data": { "decision": "approved", "message": "Numbers check out", "input": { "reason": "verified" } }
}
Response 200 OK
The request as answered: its run, id and type, and the answer it holds (status, the respondent and the value or decision).
{
"data": {
"executionId": "exec_abc123",
"requestId": "input_ask_exec_abc123_1700000000000",
"type": "input",
"status": "responded",
"respondent": "ada@example.com",
"value": { "region": "eu" },
"respondedAt": "2026-10-11T12:00:00.000Z"
},
"meta": { "requestId": "..." }
}
Errors
| Status | Code | Description |
|---|---|---|
400 | validation-error | Missing data, or the answer does not fit the request (the message says what is wrong) |
403 | forbidden | Caller cannot access this execution's workflow, or is not one of the checkpoint's approvers |
404 | not-found | Execution not found, or it has no pending request with this ID (answered, timed out, or the run ended) |
GET /api/v1/workflows/-/executions/:id/human-requests
List what a running execution waits on from a person. Every request has type (input, feedback or checkpoint), requestId, nodeId (the canvas node that waits), createdAt and expiresAt, and what it asks:
type | Node | Fields |
|---|---|---|
input | Wait for Input | prompt, inputSchema |
feedback | Human Feedback | prompt, feedbackType (text, rating, choice, form), ratingScale, choices, formFields |
checkpoint | Human Checkpoint | title, description, data (what is under review), context, approvers (emails; empty means anyone who can run the workflow), collectInput, inputFields |
Scope: workflows:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Response 200 OK
{
"data": {
"executionId": "exec_xyz789",
"workflowId": "wf_abc123",
"executionStatus": "running",
"pendingInputs": [
{
"key": "input_requests/input_ask_exec_xyz789_1791486063320",
"type": "input",
"requestId": "input_ask_exec_xyz789_1791486063320",
"executionId": "exec_xyz789",
"nodeId": "ask",
"prompt": "Which region?",
"inputSchema": null,
"createdAt": "2026-10-08T19:01:03.320567",
"expiresAt": "2026-10-08T20:01:03.320572"
}
]
},
"meta": {
"requestId": "req_abc123"
}
}
POST /api/v1/workflows/-/executions/:executionId/human-requests/:id/notify
Announce a pending request of a running execution on the channels its Human Checkpoint node sets (in-app, email, webhook). The node calls it; the channels and recipients are read from the request in the run's state, never from the caller.
Scope: workflows:execute
| Parameter | Type | Required | Description |
|---|---|---|---|
executionId | string | Yes | The execution |
id | string | Yes | The request's requestId |
Response 200 OK: executionId, requestId and channels: for each channel the node
sets (in_app, email, webhook), what was sent or why not (error).
GET /api/v1/workflows/-/executions/:id/spans
List execution spans. Each span represents the execution of a single node within the workflow.
Scope: workflows:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
nodeId | string | No | Filter spans by node ID |
Response 200 OK
{
"data": [
{
"_id": "span_001",
"executionId": "exec_xyz789",
"workflowId": "wf_abc123",
"parentSpanId": null,
"nodeId": "mysql-a1B2c3",
"nodeType": "mysql",
"category": "sources",
"spanType": "NODE",
"name": "mysql:mysql-a1B2c3",
"status": "completed",
"startTime": "2025-02-01T14:22:01Z",
"endTime": "2025-02-01T14:22:45Z",
"durationMs": 44000,
"inputData": {},
"mappedInput": {},
"outputData": {
"rowCount": 1500
},
"errorMessage": null,
"metadata": {}
},
{
"_id": "span_002",
"executionId": "exec_xyz789",
"workflowId": "wf_abc123",
"parentSpanId": null,
"nodeId": "code-d4E5f6",
"nodeType": "code",
"category": "transform",
"spanType": "NODE",
"name": "code:code-d4E5f6",
"status": "completed",
"startTime": "2025-02-01T14:22:46Z",
"endTime": "2025-02-01T14:24:00Z",
"durationMs": 74000,
"inputData": {},
"mappedInput": {},
"outputData": {
"rowCount": 1450
},
"errorMessage": null,
"metadata": {}
}
],
"meta": {
"requestId": "req_abc123"
}
}
Spans are listed oldest first.
GET /api/v1/workflows/-/executions/:id/logs
Get execution logs. Logs are produced by individual nodes during execution and include informational messages, warnings, and errors.
Scope: workflows:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
level | string | No | Filter by log level: debug, info, warning, error. Node log lines store the level in upper case and are matched either way |
limit | integer | No | Number of log entries to return (default: 100, max: 1000) |
Response 200 OK
{
"data": [
{
"_id": "log_003",
"executionId": "exec_xyz789",
"timestamp": "2025-02-01T14:23:10Z",
"level": "WARNING",
"message": "50 rows skipped due to null primary key",
"nodeId": "code-d4E5f6",
"createdAt": "2025-02-01T14:23:10Z"
},
{
"_id": "log_002",
"executionId": "exec_xyz789",
"timestamp": "2025-02-01T14:22:45Z",
"level": "INFO",
"message": "Successfully extracted 1500 rows from orders table",
"nodeId": "mysql-a1B2c3",
"createdAt": "2025-02-01T14:22:45Z"
}
],
"meta": {
"requestId": "req_abc123"
}
}
Entries are newest first; see the Log object for the two shapes an entry can have.
GET /api/v1/workflows/-/executions/:id/progress
Get an execution's status and progress, including node-level completion counts.
The call waits up to about 9 seconds for the run to finish before it answers. If status is still pending or running, call it again. Once the run has finished as completed, completed_with_gaps or partial_success, the response includes outputs, a short preview of each node's output keyed by node ID, so you can see which nodes produced nothing. A finished run also carries nextAction, a sentence saying what to check next.
Scope: workflows:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Execution ID |
Response 200 OK
{
"data": {
"executionId": "exec_xyz789",
"status": "running",
"progress": 66,
"totalNodes": 6,
"completedNodes": 4,
"failedNodes": 0,
"runningNodes": 1,
"startedAt": "2025-02-01T14:22:00Z",
"endedAt": null,
"durationMs": 180000
},
"meta": {
"requestId": "req_abc123"
}
}
A run that finished with gaps:
{
"data": {
"executionId": "exec_xyz789",
"status": "completed_with_gaps",
"progress": 83,
"totalNodes": 6,
"completedNodes": 5,
"failedNodes": 0,
"runningNodes": 0,
"startedAt": "2025-02-01T14:22:00Z",
"endedAt": "2025-02-01T14:25:30Z",
"durationMs": 210000,
"outputs": {
"node_1": "{ \"rowCount\": 1500 }"
},
"nextAction": "Execution COMPLETED WITH GAPS: it finished, but some node outputs are missing. ..."
},
"meta": {
"requestId": "req_abc123"
}
}
Dead letters
A run the platform could not submit (its trigger fired, but the run could not start) is kept as a
dead letter and retried on a schedule. Each entry has a status: pending (waiting for its next
retry), retrying, resolved (a retry ran; executionId is that run), exhausted (out of
retries) or discarded.
GET /api/v1/workflows/:workflowId/dead-letters
The dead letters of a workflow, or of every workflow you can see with workflowId -, newest
failure first.
Scope: workflows:read
| Parameter | Type | Required | Description |
|---|---|---|---|
workflowId | string | Yes | The workflow, or - for every workflow |
status | string | No | Only entries in this status; several comma-separated (pending,exhausted) |
limit | integer | No | Results per page |
cursor | string | No | meta.nextCursor of the previous page |
Response 200 OK: a page of dead letters.
GET /api/v1/workflows/-/dead-letters/:id
A dead letter: its workflow, status, retryCount and maxRetries, nextRetryAt, the last
error, and on resolution the executionId of the retry that ran. An entry you may not see is
404 not-found.
Scope: workflows:read
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The dead letter |
Response 200 OK
POST /api/v1/workflows/-/dead-letters/:id/retry
Retry a dead letter now: run its workflow with the failed run's inputs, as you. Refused while a retry of it is running, and for a resolved or discarded entry.
Scope: workflows:execute
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The dead letter |
Response 200 OK: outcome (resolved, pending, exhausted, reverted or unknown),
with the executionId of the run when it started, or the error.
POST /api/v1/workflows/-/dead-letters/:id/discard
Give up on a dead letter: it is never retried.
Scope: workflows:execute
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
notes | string | No | Why it is discarded |
Response 200 OK: the dead letter, status discarded, its resolution recording who discarded it, when and why.