Run management.
Nine endpoints to start and operate workflow runs from your own code — start one, list them, fetch one, pause, resume, retry, or cancel, and resolve their pending approvals. All authenticated with the same Access Key as triggers.
These routes are workflow-only. Conversational agents have no runs, so
these endpoints return 400 runtime_not_applicable
for them.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /api/workflows/{agent_id}/trigger | Start a run |
| GET | /api/agents/{agent_id}/runs | List runs for an agent |
| GET | /api/agents/{agent_id}/runs/{run_id} | Fetch one run with signed output URLs |
| POST | /api/agents/{agent_id}/runs/{run_id}/cancel | Cancel an in-progress run |
| POST | /api/agents/{agent_id}/runs/{run_id}/pause | Pause a running run |
| POST | /api/agents/{agent_id}/runs/{run_id}/retry | Retry a failed run with the same inputs |
| POST | /api/agents/{agent_id}/runs/{run_id}/resume | Resume a paused run |
| GET | /api/agents/{agent_id}/runs/{run_id}/approvals | List a run's pending approvals |
| POST | /api/agents/{agent_id}/runs/{run_id}/approvals/resolve | Approve, reject, or modify one approval |
Start a run
Starts a run of the job's published version. The body is optional: payload is the
run's input (reference uploaded files as { "file_id": "fi_..." }), and
variables override the job's default variables for this run. Each run is a real,
billed run, and counts toward the job's daily run limit.
curl -X POST https://webhook.olbrain.com/api/workflows/agt_01HAKZ.../trigger \
-H "Authorization: Bearer ak_<your-access-key>" \
-H "Content-Type: application/json" \
-d '{"payload": {"order_id": "ord_8842"}}'
{ "run_id": "abfcbeef-6d3a-4ab3-aca7-516cbff72d01", "status": "triggered" }
List runs
Returns the job's runs, newest first. Only live runs are listed; Studio test runs are left out.
Query parameters
| Name | Type | Description |
|---|---|---|
limit | integer |
Max runs to return. Defaults to the runtime's own default. |
status | string |
Filter by run state — one of pending, running, completed, failed, needs_review, cancelled, paused. An unrecognised value returns 400 invalid_status. |
Any other query parameters are ignored.
curl "https://webhook.olbrain.com/api/agents/agt_01HAKZ.../runs?limit=20&status=failed" \
-H "Authorization: Bearer ak_<your-access-key>"
Fetch one run
Returns the run record — status, progress, timing, a roll-up summary,
per-state item_counts, and any output files. Output files come back as
output_files[], each with a V4 signed HTTPS URL valid for
15 minutes after the GET. Re-issue the GET to get fresh URLs. The list
endpoint above returns the same shape minus output_files (omitted so
listing many runs doesn't mint a signed URL per file).
{
"run_id": "abfcbeef-6d3a-4ab3-aca7-516cbff72d01",
"agent_id": "agt_01HAKZ...",
"status": "completed",
"progress_percent": 100.0,
"started_at": "2026-05-26T11:42:19Z",
"completed_at": "2026-05-26T11:43:07Z",
"duration_seconds": 48.0,
"trigger_type": "event",
"error": null,
"summary": { "total_processed": 100, "successful": 95, "failed": 3, "exceptions": 2, "skipped": 0 },
"item_counts": { "completed": 95, "failed": 3, "needs_review": 2, "total": 100 },
"output_files": [
{
"filename": "report.pdf",
"content_type": "application/pdf",
"size_bytes": 184320,
"url": "https://storage.googleapis.com/...",
"url_expires_at": "2026-05-26T12:00:00Z"
}
]
}
Control endpoints
The four control endpoints share the same shape: POST with an empty body, optionally
supply ?triggered_by= to attribute the action in audit logs.
Query parameters
| Name | Type | Description |
|---|---|---|
triggered_by | string |
Optional. Attribution string that appears on the run's audit trail (e.g. shopify-webhook-handler, ops-dashboard). |
State transitions
| Action | Allowed from | Transitions to |
|---|---|---|
pause | running, pending | paused |
resume | paused, needs_review, running | running |
cancel | running, pending, needs_review, paused | cancelled |
retry | failed | Re-runs the same run from the failed step |
An action against an incompatible state returns 409
invalid_state_transition. Re-fetch the run to see its current state before
retrying.
curl -X POST "https://webhook.olbrain.com/api/agents/agt_01HAKZ.../runs/run_01HZQ7K9.../cancel?triggered_by=ops-dashboard" \
-H "Authorization: Bearer ak_<your-access-key>"
Approvals
When a step needs a human decision, the run stops in needs_review with one or more
pending approvals. List them, resolve each one, and the run resumes on its own once the last
blocking approval is resolved.
Returns the run's unresolved approvals. An empty array means nothing is waiting.
[
{
"exception_id": "exc_7f3a...",
"step_id": "review_invoice",
"item_id": "item_42",
"data": { "vendor": "Acme", "amount": 18400 },
"error": "Amount exceeds the auto-approve limit",
"requires_human_review": true,
"blocking": true
}
]
Body
| Field | Type | Description |
|---|---|---|
exception_id | string |
Required. The approval to resolve, from the list above. |
resolution | string |
Required. One of approved, rejected, modified. |
modified_data | object |
Only with modified: the corrected data to continue with. |
Anything else returns 400 invalid_resolution.
The resolver is recorded as your Access Key; there is no field to name someone else.
curl -X POST "https://webhook.olbrain.com/api/agents/agt_01HAKZ.../runs/run_01HZQ7K9.../approvals/resolve" \
-H "Authorization: Bearer ak_<your-access-key>" \
-H "Content-Type: application/json" \
-d '{"exception_id": "exc_7f3a...", "resolution": "approved"}'
{
"exception_id": "exc_7f3a...",
"resolution": "approved",
"all_resolved": true,
"resumed": true
}
all_resolved is true once the run has no approvals left; resumed is
true when this call set the run going again. If every approval is resolved but
resumed is false, call resume to restart it.
For counts across runs (finished, failed, items processed, cost per day), use
GET /api/agents/{agent_id}/stats.
Scope
A run can only be read or controlled via the agent it belongs to. Calling a run-management
route with the wrong agent_id in the URL returns
404.