Workflows
Every call needs Authorization: Bearer <key>. 8 calls:
- List workflow runs, newest first:
GET /v1/workflow-runs - Get a workflow run and its steps:
GET /v1/workflow-runs/:id - List workflows, most recently edited first:
GET /v1/workflows - Create a draft workflow:
POST /v1/workflows - Get a workflow with its draft graph:
GET /v1/workflows/:id - Edit the draft, or pause, resume or archive a workflow:
PATCH /v1/workflows/:id - Publish the draft and turn the workflow on:
POST /v1/workflows/:id/publish - List a workflow's versions, newest first:
GET /v1/workflows/:id/versions
List workflow runs, newest first
GET /v1/workflow-runs
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
workflow_id | string (uuid) | No | |
status | enum | No | One of: running, waiting, completed, failed, cancelled. |
contact_id | string | No | Contact id (ctc_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].contact_id | string or null | Contact id (ctc_...). |
data[].error_code | string or null | |
data[].finished_at | string (date-time) or null | ISO 8601 timestamp. |
data[].id | string (uuid) | |
data[].resume_at | string (date-time) or null | ISO 8601 timestamp. |
data[].started_at | string (date-time) | ISO 8601 timestamp. |
data[].status | enum | One of: running, waiting, completed, failed, cancelled. |
data[].steps | object[] | |
data[].steps[].at | string (date-time) | ISO 8601 timestamp. |
data[].steps[].detail | object | |
data[].steps[].node_id | string | |
data[].steps[].status | enum | One of: completed, skipped, failed, waiting. |
data[].version | integer | From 1 to 9007199254740991. |
data[].workflow_id | string (uuid) | |
data[].workflow_version_id | string (uuid) | |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get a workflow run and its steps
GET /v1/workflow-runs/:id
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
contact_id | string or null | Contact id (ctc_...). |
error_code | string or null | |
finished_at | string (date-time) or null | ISO 8601 timestamp. |
id | string (uuid) | |
resume_at | string (date-time) or null | ISO 8601 timestamp. |
started_at | string (date-time) | ISO 8601 timestamp. |
status | enum | One of: running, waiting, completed, failed, cancelled. |
steps | object[] | |
steps[].at | string (date-time) | ISO 8601 timestamp. |
steps[].detail | object | |
steps[].node_id | string | |
steps[].status | enum | One of: completed, skipped, failed, waiting. |
version | integer | From 1 to 9007199254740991. |
workflow_id | string (uuid) | |
workflow_version_id | string (uuid) |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List workflows, most recently edited first
GET /v1/workflows
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
status | enum | No | One of: draft, live, paused, archived. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].graph | object | |
data[].graph.edges | object[] | Up to 400 items. |
data[].graph.nodes | object[] | Up to 200 items. |
data[].has_draft | boolean | |
data[].id | string (uuid) | |
data[].name | string | |
data[].published_version | integer or null | From 1 to 9007199254740991. |
data[].published_version_id | string (uuid) or null | |
data[].runs_30d | object | |
data[].runs_30d.completed | integer | From 0 to 9007199254740991. |
data[].runs_30d.failed | integer | From 0 to 9007199254740991. |
data[].runs_30d.total | integer | From 0 to 9007199254740991. |
data[].status | enum | One of: draft, live, paused, archived. |
data[].trigger | enum | One of: message.received, contact.created, schedule, webhook. |
data[].trigger_config | object | |
data[].updated_at | string (date-time) | ISO 8601 timestamp. |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Create a draft workflow
POST /v1/workflows
The workflow starts as a draft; publish it to turn it on. Test-mode API keys are refused, because workflows send live messages.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
graph | object | No | Default {"edges":[],"nodes":[]}. |
graph.edges | object[] | Yes | Up to 400 items. |
graph.edges[].from | string | Yes | Up to 64 characters. |
graph.edges[].label | string | No | Up to 40 characters. |
graph.edges[].to | string | Yes | Up to 64 characters. |
graph.nodes | object[] | Yes | Up to 200 items. |
graph.nodes[].config | object | No | Default {}. |
graph.nodes[].id | string | Yes | Up to 64 characters. |
graph.nodes[].position | object | No | |
graph.nodes[].type | enum | Yes | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
name | string | Yes | Up to 120 characters. |
trigger | enum | Yes | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | No | Default {}. |
Response 201
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
graph | object | |
graph.edges | object[] | Up to 400 items. |
graph.edges[].from | string | Up to 64 characters. |
graph.edges[].label | string | Up to 40 characters. |
graph.edges[].to | string | Up to 64 characters. |
graph.nodes | object[] | Up to 200 items. |
graph.nodes[].config | object | Default {}. |
graph.nodes[].id | string | Up to 64 characters. |
graph.nodes[].position | object | |
graph.nodes[].type | enum | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
has_draft | boolean | |
id | string (uuid) | |
name | string | |
published_version | integer or null | From 1 to 9007199254740991. |
published_version_id | string (uuid) or null | |
runs_30d | object | |
runs_30d.completed | integer | From 0 to 9007199254740991. |
runs_30d.failed | integer | From 0 to 9007199254740991. |
runs_30d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, live, paused, archived. |
trigger | enum | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get a workflow with its draft graph
GET /v1/workflows/:id
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
graph | object | |
graph.edges | object[] | Up to 400 items. |
graph.edges[].from | string | Up to 64 characters. |
graph.edges[].label | string | Up to 40 characters. |
graph.edges[].to | string | Up to 64 characters. |
graph.nodes | object[] | Up to 200 items. |
graph.nodes[].config | object | Default {}. |
graph.nodes[].id | string | Up to 64 characters. |
graph.nodes[].position | object | |
graph.nodes[].type | enum | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
has_draft | boolean | |
id | string (uuid) | |
name | string | |
published_version | integer or null | From 1 to 9007199254740991. |
published_version_id | string (uuid) or null | |
runs_30d | object | |
runs_30d.completed | integer | From 0 to 9007199254740991. |
runs_30d.failed | integer | From 0 to 9007199254740991. |
runs_30d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, live, paused, archived. |
trigger | enum | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Edit the draft, or pause, resume or archive a workflow
PATCH /v1/workflows/:id
Name, trigger and graph changes go to a draft version; the live version keeps running until the draft is published. status: paused stops new runs and holds running and waiting ones where they are; status: live resumes a paused workflow that has a published version, and its held runs continue. status: archived is final: it stops new runs and cancels running and waiting ones. Test-mode API keys are refused.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
graph | object | No | |
graph.edges | object[] | Yes | Up to 400 items. |
graph.edges[].from | string | Yes | Up to 64 characters. |
graph.edges[].label | string | No | Up to 40 characters. |
graph.edges[].to | string | Yes | Up to 64 characters. |
graph.nodes | object[] | Yes | Up to 200 items. |
graph.nodes[].config | object | No | Default {}. |
graph.nodes[].id | string | Yes | Up to 64 characters. |
graph.nodes[].position | object | No | |
graph.nodes[].type | enum | Yes | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
name | string | No | Up to 120 characters. |
status | enum | No | One of: paused, archived, live. |
trigger | enum | No | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | No |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
graph | object | |
graph.edges | object[] | Up to 400 items. |
graph.edges[].from | string | Up to 64 characters. |
graph.edges[].label | string | Up to 40 characters. |
graph.edges[].to | string | Up to 64 characters. |
graph.nodes | object[] | Up to 200 items. |
graph.nodes[].config | object | Default {}. |
graph.nodes[].id | string | Up to 64 characters. |
graph.nodes[].position | object | |
graph.nodes[].type | enum | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
has_draft | boolean | |
id | string (uuid) | |
name | string | |
published_version | integer or null | From 1 to 9007199254740991. |
published_version_id | string (uuid) or null | |
runs_30d | object | |
runs_30d.completed | integer | From 0 to 9007199254740991. |
runs_30d.failed | integer | From 0 to 9007199254740991. |
runs_30d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, live, paused, archived. |
trigger | enum | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Publish the draft and turn the workflow on
POST /v1/workflows/:id/publish
Checks the draft (one trigger, every step reachable, no loops, valid settings, existing segments, labels, people, teams and agents) and makes it the live version. Runs already going stay on the version they started on. Test-mode API keys are refused.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
graph | object | |
graph.edges | object[] | Up to 400 items. |
graph.edges[].from | string | Up to 64 characters. |
graph.edges[].label | string | Up to 40 characters. |
graph.edges[].to | string | Up to 64 characters. |
graph.nodes | object[] | Up to 200 items. |
graph.nodes[].config | object | Default {}. |
graph.nodes[].id | string | Up to 64 characters. |
graph.nodes[].position | object | |
graph.nodes[].type | enum | One of: trigger, condition, wait, send, assign, label, webhook, ai. |
has_draft | boolean | |
id | string (uuid) | |
name | string | |
published_version | integer or null | From 1 to 9007199254740991. |
published_version_id | string (uuid) or null | |
runs_30d | object | |
runs_30d.completed | integer | From 0 to 9007199254740991. |
runs_30d.failed | integer | From 0 to 9007199254740991. |
runs_30d.total | integer | From 0 to 9007199254740991. |
status | enum | One of: draft, live, paused, archived. |
trigger | enum | One of: message.received, contact.created, schedule, webhook. |
trigger_config | object | |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List a workflow's versions, newest first
GET /v1/workflows/:id/versions
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].graph | object | |
data[].graph.edges | object[] | Up to 400 items. |
data[].graph.nodes | object[] | Up to 200 items. |
data[].id | string (uuid) | |
data[].published_at | string (date-time) or null | ISO 8601 timestamp. |
data[].version | integer | From 1 to 9007199254740991. |
data[].workflow_id | string (uuid) |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.