Automations
The workflows built in Automations: list, read, create (from a template or a plan), change settings, activate, deactivate and delete them, and add or remove contacts.
The workflows built in Automations: list, read, create (from a template or a plan), change settings, activate, deactivate and delete them, and add or remove contacts.
Every route takes Authorization: Bearer <ACCESS_TOKEN> unless the auth line says otherwise. Ids are numbers. Errors use the shape on the errors page.
| Route | Scope | What it does |
|---|---|---|
GET /v1/workflows | automations.read | List the automation workflows in a workspace owned by the installer. |
GET /v1/workflows/{id} | automations.read | One workflow with its steps and settings. |
GET /v1/workflow-templates | automations.read | The templates saved in a workspace, to create workflows from. |
GET /v1/workflows/node-catalog | automations.read | Every step type a plan can use, and the fields each one takes. |
POST /v1/workflows/validate | automations.read | Dry-run a plan: the problems it has. Nothing is saved. |
POST /v1/workflows | automations.write | Create a workflow from a template or a plan. It is saved as a draft. |
PATCH /v1/workflows/{id} | automations.write | Rename it, or change stop on reply, re-entry or the sending hours. |
POST /v1/workflows/{id}/activate | automations.write | Turn a workflow on. |
POST /v1/workflows/{id}/deactivate | automations.write | Turn a workflow off (back to draft). |
DELETE /v1/workflows/{id} | automations.write | Delete a workflow. |
POST /v1/workflows/{id}/contacts | automations.write | Start a workflow for up to 100 contacts. |
DELETE /v1/workflows/{id}/contacts/{contact_id} | automations.write | Stop a workflow for one contact. |
List workflows
GET https://api.bluereacher.com/v1/workflowsAuth: Bearer access token. Scope: automations.read.
List the automation workflows in a workspace owned by the installer.
Read-only list of the workflows built in Automations for a workspace. Scoped to the installer, so a token can only read the workflows of its own workspaces. Supports pagination and name search.
An unknown or non-owned workspace_id returns 404 (never an empty 200), and the same 404 is returned whether the workspace does not exist or simply is not yours — so existence is never leaked.
Pagination: page is clamped to >= 1 (default 1) and limit to [1, 200] (default 10). Invalid bounds are normalised rather than rejected; the response pagination object reports the applied page / limit, max_limit, total, total_pages, the raw requested values, and a normalized flag.
This is a read-only surface — creating, editing, and triggering workflows is done in the dashboard, not via the API.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspace_id | query | number | yes | The workspace whose workflows to list. Must belong to the installer. |
page | query | number | no | Page number — integer clamped to >= 1; default 1. Invalid values (0, negative, non-numeric) are normalised to 1, NOT rejected; see the response pagination object. |
limit | query | number | no | Page size — integer clamped to [1, 200]; default 10. Out-of-range or non-numeric values are normalised, NOT rejected; the applied bounds and a normalized flag are echoed in the response pagination object. |
search | query | string | no | Filter workflows by name (case-insensitive). |
Request
curl -X GET "https://api.bluereacher.com/v1/workflows?workspace_id=7&page=1&limit=10" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK):
{
"success": true,
"data": {
"workflows": [
{
"id": "wf_9a1",
"name": "Welcome new lead",
"status": "active",
"created_at": "2026-05-21T09:14:22.000Z",
"updated_at": "2026-07-01T12:00:00.000Z"
},
{
"id": "wf_9a2",
"name": "Missed-call follow up",
"status": "draft",
"created_at": "2026-06-02T10:00:00.000Z",
"updated_at": "2026-06-02T10:00:00.000Z"
}
],
"total": 12,
"activeCount": 8,
"draftCount": 4
},
"pagination": {
"page": 1,
"limit": 10,
"max_limit": 200,
"total": 12,
"total_pages": 2,
"requested": {
"page": null,
"limit": null
},
"normalized": false
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 400 | workspace_id missing | workspace_id is required |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.read. This integration was granted: … |
| 404 | workspace_id does not exist or is not owned by the installer (same response for both, so existence is never leaked) | Workspace not found or not accessible to this token |
Response fields
workflows: The page of workflows plus totals for the workspace. Fields:
| Field | Type | Description |
|---|---|---|
workflows | array<object> | The page of workflows. Each carries id, name, status ("active" / "draft"), created_at, updated_at. |
total | number | Total workflows in the workspace matching the filter. Example: 12 |
activeCount | number | How many of them are active. Example: 8 |
draftCount | number | How many of them are drafts. Example: 4 |
Get workflow
GET https://api.bluereacher.com/v1/workflows/{id}Auth: Bearer access token. Scope: automations.read.
One workflow with its steps and settings.
The workflow must be the installer's own and in the workspace_id sent; anything else is 404. nodes and edges are the canvas graph exactly as stored.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | number | yes | Workflow id (from List workflows). |
workspace_id | query | number | yes | A workspace of the installer. |
Request
curl -X GET "https://api.bluereacher.com/v1/workflows/1201?workspace_id=7" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK):
{
"success": true,
"data": {
"id": 1201,
"name": "Welcome new contacts",
"status": "draft",
"workspace_id": 7,
"stop_on_reply": true,
"allow_re_entry": true,
"execution_window": {
"enabled": false,
"timezone": null,
"start_time": null,
"end_time": null,
"skip_weekends": false
},
"step_count": 4,
"nodes": [
{
"id": "contactCreated",
"type": "contactCreated",
"position": {
"x": 0,
"y": 0
},
"data": {
"note": ""
}
},
{
"id": "welcome",
"type": "sendSMS",
"position": {
"x": 0,
"y": 220
},
"data": {
"phone": "{{contact.number}}",
"message": "Hi {{contact.first_name}}, thanks for signing up!"
}
},
{
"id": "wait1",
"type": "wait",
"position": {
"x": 0,
"y": 440
},
"data": {
"waitType": "duration",
"delay": 86400000,
"delayValue": 1,
"delayUnit": "days"
}
},
{
"id": "tag",
"type": "addTag",
"position": {
"x": 0,
"y": 660
},
"data": {
"tags": [
"welcomed"
]
}
}
],
"edges": [
{
"id": "e-contactCreated-welcome",
"source": "contactCreated",
"target": "welcome",
"sourceHandle": "out"
},
{
"id": "e-welcome-wait1",
"source": "welcome",
"target": "wait1",
"sourceHandle": "out"
},
{
"id": "e-wait1-tag",
"source": "wait1",
"target": "tag",
"sourceHandle": "out"
}
],
"created_at": "2026-10-28T09:00:00.000Z",
"updated_at": "2026-10-28T09:00:00.000Z"
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.read. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The workflow does not exist, is not the installer's, or is in another workspace | Workflow not found or not accessible to this token |
Response fields
workflow. Fields:
| Field | Type | Description |
|---|---|---|
id | number | Workflow id. Example: 1201 |
name | string | Workflow name. Example: Welcome new contacts |
status | string | draft (not running) or active (running). Example: draft |
workspace_id | number | The workspace it runs in. Example: 7 |
stop_on_reply | boolean | A contact who replies leaves the workflow. |
allow_re_entry | boolean | A contact who finished can start it again. |
execution_window | object | The hours it may send in: enabled, timezone, start_time, end_time, skip_weekends. |
step_count | number | How many steps (canvas nodes) it has, the trigger included. Example: 4 |
nodes | array<object> | The steps as the canvas stores them (id, type, data, position). Get and create only. |
edges | array<object> | The connections between steps (source, target, sourceHandle). Get and create only. |
created_at | string (ISO 8601) | Created. |
updated_at | string (ISO 8601) | Last saved. |
List workflow templates
GET https://api.bluereacher.com/v1/workflow-templatesAuth: Bearer access token. Scope: automations.read.
The templates saved in a workspace, to create workflows from.
These are the installer's own templates (saved from Automations with Save as template). Pass an id from here as template_id to Create workflow.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspace_id | query | number | yes | A workspace of the installer. |
Request
curl -X GET "https://api.bluereacher.com/v1/workflow-templates?workspace_id=7" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK):
{
"success": true,
"data": [
{
"id": 88,
"name": "Missed call text-back",
"step_count": 3,
"updated_at": "2026-10-20T11:00:00.000Z"
}
]
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.read. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
Node catalog
GET https://api.bluereacher.com/v1/workflows/node-catalogAuth: Bearer access token. Scope: automations.read.
Every step type a plan can use, and the fields each one takes.
The reference for writing a plan. detail=summary (the default) lists every type with its title, purpose and whether it is a trigger or an action. detail=full&types=sendSMS,wait adds, for just those types, when to use them, how they work, their default data and the field schema (fields) that says what data may set.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
detail | query | enum | no | Default summary. |
types | query | string | no | Comma-separated step types, with detail=full. |
Request
curl -X GET "https://api.bluereacher.com/v1/workflows/node-catalog?types=sendSMS%2Cwait" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK (detail=full&types=sendSMS)):
{
"success": true,
"data": []
}| Status | When | Message |
|---|---|---|
| 200 | OK (detail=full&types=sendSMS) | |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.read. This integration was granted: … |
Validate a plan
POST https://api.bluereacher.com/v1/workflows/validateAuth: Bearer access token. Scope: automations.read.
Dry-run a plan: the problems it has. Nothing is saved.
A plan is a list of named steps. Each step has a unique name, a type from the Node catalog, optional data (only the fields you want to set — the rest take the type's defaults), and points at the next step by name: next for a single path, branches for a step that splits (ifElse: true / false; findContact: found / notFound).
A plan may start with one trigger of each type (several triggers must all point at the same first step), or with none — then contacts enter only through Add contacts to a workflow.
envelope is optional: name, stopOnReply, allowReEntry, executionWindow. Its status is ignored; a new workflow is always a draft.
Each issue names the step it is about. A plan with no issues is what Create workflow accepts.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
plan | body | object | yes | { steps: [...], envelope?: {...} } — at most 200 steps. |
Request
curl -X POST "https://api.bluereacher.com/v1/workflows/validate" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"plan": {
"steps": [
{
"name": "contactCreated",
"type": "contactCreated",
"next": "welcome"
},
{
"name": "welcome",
"type": "sendSMS",
"data": {
"message": "Hi {{contact.first_name}}, thanks for signing up!"
},
"next": "wait1"
},
{
"name": "wait1",
"type": "wait",
"data": {
"waitType": "duration",
"delay": 86400000,
"delayValue": 1,
"delayUnit": "days"
},
"next": "tag"
},
{
"name": "tag",
"type": "addTag",
"data": {
"tags": [
"welcomed"
]
},
"next": null
}
],
"envelope": {
"name": "Welcome new contacts",
"stopOnReply": true
}
}
}'Responses
A 200 reply (Valid):
{
"success": true,
"data": {
"valid": true,
"issues": [],
"step_count": 4
}
}| Status | When | Message |
|---|---|---|
| 200 | Valid | |
| 200 | Has problems | |
| 400 | Not a plan | every plan step needs a name and a type |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.read. This integration was granted: … |
Create workflow
POST https://api.bluereacher.com/v1/workflowsAuth: Bearer access token. Scope: automations.write.
Create a workflow from a template or a plan. It is saved as a draft.
Send either template_id (a copy of one of your templates) or plan (see Validate a plan), not both. A plan is validated first; if it has problems nothing is created and the issues come back (400 INVALID_PLAN).
The new workflow is always a draft: it does not run and messages nobody until you activate it (Activate workflow).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspace_id | body | number | yes | A workspace of the installer. |
template_id | body | number | no | A template from List workflow templates. |
plan | body | object | no | A plan: { steps: [...], envelope?: {...} }. |
name | body | string | no | Default: the plan's envelope.name, or "<template name> (copy)". |
stop_on_reply | body | boolean | no | A contact who replies leaves the workflow. |
allow_re_entry | body | boolean | no | A contact who finished can start it again. |
execution_window | body | object | null | no | Only send between these hours: { "enabled": true, "timezone": "Australia/Sydney", "start_time": "09:00", "end_time": "18:00", "skip_weekends": true }. null (or enabled: false) turns it off. |
Request
curl -X POST "https://api.bluereacher.com/v1/workflows" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": 7,
"plan": {
"steps": [
{
"name": "contactCreated",
"type": "contactCreated",
"next": "welcome"
},
{
"name": "welcome",
"type": "sendSMS",
"data": {
"message": "Hi {{contact.first_name}}, thanks for signing up!"
},
"next": "wait1"
},
{
"name": "wait1",
"type": "wait",
"data": {
"waitType": "duration",
"delay": 86400000,
"delayValue": 1,
"delayUnit": "days"
},
"next": "tag"
},
{
"name": "tag",
"type": "addTag",
"data": {
"tags": [
"welcomed"
]
},
"next": null
}
],
"envelope": {
"name": "Welcome new contacts",
"stopOnReply": true
}
},
"execution_window": {
"enabled": true,
"timezone": "Australia/Sydney",
"start_time": "09:00",
"end_time": "18:00",
"skip_weekends": true
}
}'Responses
A 201 reply (Created (draft)):
{
"success": true,
"message": "Workflow created as a draft. It runs once activated (POST /workflows/{id}/activate).",
"data": {
"id": 1201,
"name": "Welcome new contacts",
"status": "draft",
"workspace_id": 7,
"stop_on_reply": true,
"allow_re_entry": true,
"execution_window": {
"enabled": true,
"timezone": "Australia/Sydney",
"start_time": "09:00",
"end_time": "18:00",
"skip_weekends": true
},
"step_count": 4,
"nodes": [
{
"id": "contactCreated",
"type": "contactCreated",
"position": {
"x": 0,
"y": 0
},
"data": {
"note": ""
}
},
{
"id": "welcome",
"type": "sendSMS",
"position": {
"x": 0,
"y": 220
},
"data": {
"phone": "{{contact.number}}",
"message": "Hi {{contact.first_name}}, thanks for signing up!"
}
},
{
"id": "wait1",
"type": "wait",
"position": {
"x": 0,
"y": 440
},
"data": {
"waitType": "duration",
"delay": 86400000,
"delayValue": 1,
"delayUnit": "days"
}
},
{
"id": "tag",
"type": "addTag",
"position": {
"x": 0,
"y": 660
},
"data": {
"tags": [
"welcomed"
]
}
}
],
"edges": [
{
"id": "e-contactCreated-welcome",
"source": "contactCreated",
"target": "welcome",
"sourceHandle": "out"
},
{
"id": "e-welcome-wait1",
"source": "welcome",
"target": "wait1",
"sourceHandle": "out"
},
{
"id": "e-wait1-tag",
"source": "wait1",
"target": "tag",
"sourceHandle": "out"
}
],
"created_at": "2026-10-28T09:00:00.000Z",
"updated_at": "2026-10-28T09:00:00.000Z"
}
}| Status | When | Message |
|---|---|---|
| 201 | Created (draft) | |
| 400 | The plan has problems; nothing was created | The plan has 1 problem(s); nothing was created. |
| 400 | Neither or both of template_id and plan | Send either template_id or plan (not both) |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The template is not the installer's | Template not found or not accessible to this token |
Response fields
workflow. Fields:
| Field | Type | Description |
|---|---|---|
id | number | Workflow id. Example: 1201 |
name | string | Workflow name. Example: Welcome new contacts |
status | string | draft (not running) or active (running). Example: draft |
workspace_id | number | The workspace it runs in. Example: 7 |
stop_on_reply | boolean | A contact who replies leaves the workflow. |
allow_re_entry | boolean | A contact who finished can start it again. |
execution_window | object | The hours it may send in: enabled, timezone, start_time, end_time, skip_weekends. |
step_count | number | How many steps (canvas nodes) it has, the trigger included. Example: 4 |
nodes | array<object> | The steps as the canvas stores them (id, type, data, position). Get and create only. |
edges | array<object> | The connections between steps (source, target, sourceHandle). Get and create only. |
created_at | string (ISO 8601) | Created. |
updated_at | string (ISO 8601) | Last saved. |
Update workflow
PATCH https://api.bluereacher.com/v1/workflows/{id}Auth: Bearer access token. Scope: automations.write.
Rename it, or change stop on reply, re-entry or the sending hours.
Settings only: the steps are kept exactly as they are, so contacts already in the workflow carry on. Steps are edited in Automations on the dashboard, and status is changed with Activate / Deactivate workflow.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | number | yes | Workflow id. |
workspace_id | body | number | yes | A workspace of the installer. |
name | body | string | no | Workflow name, 1–255 characters. |
stop_on_reply | body | boolean | no | A contact who replies leaves the workflow. |
allow_re_entry | body | boolean | no | A contact who finished can start it again. |
execution_window | body | object | null | no | Only send between these hours: { "enabled": true, "timezone": "Australia/Sydney", "start_time": "09:00", "end_time": "18:00", "skip_weekends": true }. null (or enabled: false) turns it off. |
Request
curl -X PATCH "https://api.bluereacher.com/v1/workflows/1201" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": 7,
"name": "Welcome — new contacts",
"stop_on_reply": false,
"execution_window": {
"enabled": true,
"timezone": "Australia/Sydney",
"start_time": "09:00",
"end_time": "18:00",
"skip_weekends": true
}
}'Responses
A 200 reply (OK):
{
"success": true,
"message": "Workflow updated",
"data": {
"name": "Welcome — new contacts",
"stop_on_reply": false,
"execution_window": {
"enabled": true,
"timezone": "Australia/Sydney",
"start_time": "09:00",
"end_time": "18:00",
"skip_weekends": true
}
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 400 | Nothing to update, a bad value, or steps / status sent | Steps cannot be changed through the API; edit them on the dashboard |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The workflow does not exist, is not the installer's, or is in another workspace | Workflow not found or not accessible to this token |
Response fields
workflow. Fields:
| Field | Type | Description |
|---|---|---|
id | number | Workflow id. Example: 1201 |
name | string | Workflow name. Example: Welcome new contacts |
status | string | draft (not running) or active (running). Example: draft |
workspace_id | number | The workspace it runs in. Example: 7 |
stop_on_reply | boolean | A contact who replies leaves the workflow. |
allow_re_entry | boolean | A contact who finished can start it again. |
execution_window | object | The hours it may send in: enabled, timezone, start_time, end_time, skip_weekends. |
step_count | number | How many steps (canvas nodes) it has, the trigger included. Example: 4 |
created_at | string (ISO 8601) | Created. |
updated_at | string (ISO 8601) | Last saved. |
Activate workflow
POST https://api.bluereacher.com/v1/workflows/{id}/activateAuth: Bearer access token. Scope: automations.write.
Turn a workflow on.
From now on its triggers start it and it sends to real contacts. A workflow with an Auto Trigger runs once, right now, as it is switched on (activating one that is already active does not run it again).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | number | yes | Workflow id. |
workspace_id | body | number | yes | A workspace of the installer. |
Request
curl -X POST "https://api.bluereacher.com/v1/workflows/1201/activate" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": 7
}'Responses
A 200 reply (OK):
{
"success": true,
"message": "Workflow activated",
"data": {
"id": 1201,
"status": "active"
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The workflow does not exist, is not the installer's, or is in another workspace | Workflow not found or not accessible to this token |
Deactivate workflow
POST https://api.bluereacher.com/v1/workflows/{id}/deactivateAuth: Bearer access token. Scope: automations.write.
Turn a workflow off (back to draft).
Its triggers stop starting it, and the runs in progress are cancelled. A workflow an AI agent uses as a task cannot be turned off until it is removed from the agent (400).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | number | yes | Workflow id. |
workspace_id | body | number | yes | A workspace of the installer. |
Request
curl -X POST "https://api.bluereacher.com/v1/workflows/1201/deactivate" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": 7
}'Responses
A 200 reply (OK):
{
"success": true,
"message": "Workflow deactivated (draft). Runs in progress were cancelled.",
"data": {
"id": 1201,
"status": "draft"
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 400 | Used by an AI agent | This workflow is in use by AI agent (Revive). Remove it from the agent's tasks before you unpublish it. |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The workflow does not exist, is not the installer's, or is in another workspace | Workflow not found or not accessible to this token |
Delete workflow
DELETE https://api.bluereacher.com/v1/workflows/{id}Auth: Bearer access token. Scope: automations.write.
Delete a workflow.
Runs in progress are cancelled first. A workflow an AI agent uses as a task cannot be deleted until it is removed from the agent (400). Cannot be undone.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | number | yes | Workflow id. |
workspace_id | query | number | yes | A workspace of the installer. |
Request
curl -X DELETE "https://api.bluereacher.com/v1/workflows/1201?workspace_id=7" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK):
{
"success": true,
"message": "Workflow deleted",
"data": {
"id": 1201
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 400 | Used by an AI agent | This workflow is in use by AI agent (Revive). Remove it from the agent's tasks before you delete it. |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | workspace_id does not exist or is not the installer's (same response for both) | Workspace not found or not accessible to this token |
| 404 | The workflow does not exist, is not the installer's, or is in another workspace | Workflow not found or not accessible to this token |
Add contacts to a workflow
POST https://api.bluereacher.com/v1/workflows/{id}/contactsAuth: Bearer access token. Scope: automations.write.
Start a workflow for up to 100 contacts.
The contacts start after the workflow's trigger: its entry conditions are not checked, so the actions run for every contact you send.
A contact already running in the workflow (or that finished it, when re-entry is off) is skipped; enrolled says how many actually started. Everything the workflow sends goes to real people.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The workflow id from List workflows. |
workspace_id | body | number | yes | The workspace the workflow and contacts belong to. |
contact_ids | body | array<number> | yes | Up to 100 contact ids in that workspace. |
Request
curl -X POST "https://api.bluereacher.com/v1/workflows/wf_9a1/contacts" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": 7,
"contact_ids": [
1234,
1235
]
}'Responses
A 200 reply (OK):
{
"success": true,
"message": "2 contact(s) added to the workflow.",
"data": {
"workflow_id": "wf_9a1",
"requested": 2,
"enrolled": 2
}
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 400 | Missing workspace_id or contact_ids | contact_ids is required — an array of contact ids. |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | Workspace, workflow or a contact not found (or not yours) | Contact(s) not found in this workspace: 1236. |
| 502 | The automation service did not answer | The automation service could not add the contacts. Try again later. |
Remove a contact from a workflow
DELETE https://api.bluereacher.com/v1/workflows/{id}/contacts/{contact_id}Auth: Bearer access token. Scope: automations.write.
Stop a workflow for one contact.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | The workflow id. |
contact_id | path | number | yes | The contact id. |
Request
curl -X DELETE "https://api.bluereacher.com/v1/workflows/wf_9a1/contacts/1234" \
-H "Authorization: Bearer <ACCESS_TOKEN>"Responses
A 200 reply (OK):
{
"success": true,
"message": "Contact removed from the workflow",
"data": null
}| Status | When | Message |
|---|---|---|
| 200 | OK | |
| 401 | Missing or invalid token | Invalid or expired access token. |
| 403 | Missing scope | Missing scope(s): automations.write. This integration was granted: … |
| 404 | Workflow or contact not found (or not yours) | Workflow not found or not accessible to this token |

