Monitoring
Inspect instances, retry failed nodes, drain the dead-letter queue, and stop everything at once.
Every workflow run is an instance you can inspect, pause, retry, or cancel. The console renders all of this; the API is the same surface for scripting it.
# Instances for one workflow, newest first
curl -G https://api.console.buildbase.app/api/workflows/$WORKFLOW_ID/instances \
-H "Authorization: $BUILDBASE_TOKEN" \
--data-urlencode 'filter={"status":"failed"}' \
--data-urlencode 'sort={"createdAt":-1}'Before you start
These endpoints are governed by workflows_instances, not workflows — runs
and definitions are separate grants. Listing and inspecting needs read;
pausing, resuming, retrying and cancelling are all POST, so they need
create.
Reading an instance's logs additionally needs read on workflows_logs, and
its per-node records read on workflows_actions. Admin-created tokens bypass
every check. See the admin API for the full resource
list.
Instance status
| Status | Meaning | Terminal |
|---|---|---|
running | Executing, or waiting on a delay or event | No |
paused | Halted, resumable | No |
completed | Finished successfully | Yes |
failed | A node exhausted its retries with no error path | Yes |
canceled | Stopped manually | Yes |
Individual action nodes carry their own finer-grained status: pending,
queued, running, waiting, completed, failed, skipped, canceled.
A node showing skipped inside a completed instance is normal — it means a
condition routed around it.
Inspecting
| Method | Path | Returns |
|---|---|---|
GET | /api/workflows/instances | All instances, paginated |
GET | /api/workflows/instances/counts | Counts by status, for dashboards |
GET | /api/workflows/:id/instances | Instances of one workflow |
GET | /api/workflows/instances/:instanceId | One instance |
GET | /api/workflows/instances/:instanceId/actions | Per-node state for the run |
GET | /api/workflows/instances/:instanceId/logs | Execution log |
GET | /api/workflows/:id/test-instances | Runs produced by /test |
Instances are also addressable by subject, which is how you answer "what is running for this customer":
/api/workflows/audience/:audienceId/instances/api/workflows/workspace/:workspaceId/instances/api/workflows/user/:userId/instances
Pausing and resuming
Pausing works at four scopes, and each records why it was paused —
manual, workflow, org, audience, workspace, or version.
| Scope | Endpoint |
|---|---|
| One instance | POST /api/workflows/instances/:instanceId/pause |
| One audience member | POST /api/workflows/audience/:audienceId/pause |
| One workspace | POST /api/workflows/workspace/:workspaceId/pause |
| Everything | POST /api/workflows/emergency-stop |
Each has a matching resume, and emergency-resume reverses the org-wide stop.
That pausedBy provenance matters: each resume filters on the scope that
paused the instance, so resuming a workspace does not restart instances paused
for a different reason. An instance paused by the org-wide stop stays paused
until emergency-resume, even if you resume its workspace.
The response reports what it acted on:
{ "success": true, "data": { "audienceId": "…", "resumedInstances": 42 } }Resume processes instances in batches, re-queueing each one's pending actions
as it goes, so a single call handles the whole scope however many are paused.
resumedInstances is the total it acted on.
Resuming a workflow offers two modes:
| Mode | Behavior |
|---|---|
all | Resume every paused instance |
new_only | Leave paused instances paused; only new events create instances |
GET /:id/resume/preview reports what each mode would affect before you commit.
Retrying
A failed node can be retried in place without re-running the whole instance:
curl -X POST \
https://api.console.buildbase.app/api/workflows/instances/$INSTANCE_ID/retry/$NODE_ID \
-H "Authorization: $BUILDBASE_TOKEN"Execution resumes from that node with the instance's existing context, so earlier nodes do not run twice.
To stop a run entirely, POST /api/workflows/instances/:instanceId/cancel.
The dead-letter queue
A trigger event that cannot be processed lands in the DLQ rather than being dropped. This is the layer before an instance exists — an event that never started a run.
| Method | Path | Purpose |
|---|---|---|
GET | /api/workflows/dead-letter-queue | List undelivered trigger events |
POST | /api/workflows/dead-letter-queue/:eventId/retry | Re-process one event |
Trigger events carry their own status — pending, processing, processed,
failed, skipped. Only failed events are retryable. The retry flips the
status atomically, so two concurrent retries cannot both start the same event.
A retry on any other status returns 400:
{ "success": false, "message": "Cannot retry event with status: processed" }An unknown event ID returns 404. Because the guard is atomic rather than a
read-then-write, that 400 is also what a losing race returns — retrying an
event twice is safe.
Check the DLQ when a workflow "did not fire at all". A missing instance points
at the trigger layer, whereas a failed instance points at a node.
Emergency stop
POST /api/workflows/emergency-stop halts every running instance across the
organization. Use it when a workflow is sending wrong mail — it is faster than
pausing workflows one at a time, and emergency-resume puts everything back.
Pausing does not cancel. In-flight instances hold their position and continue from where they stopped, which means a delay that expired during the pause fires immediately on resume.
Next Steps
- Webhook actions — the most common failure source.
- Workflows overview — lifecycle, versions, and re-entry.