Coasty/

Developer API

Workflows

Saved runs, ad-hoc runs, and guards

Running workflows

Running workflows, at a glance

Saved runs, ad-hoc runs, and guards

POST /v1/workflows/{id}/runs
Saved and ad-hoc workflow runs share the same guards, ordered events, human-resume path, and terminal-state contract.

Start a saved workflow with POST /v1/workflows/{id}/runs, or run a definition inline (without saving) with POST /v1/workflows/runs by adding a definition (and optional inputs_schema) to the same body. Both return a workflow.run. The body accepts inputs, a default managed-or-external machine_id for task steps, and the budget_cents, max_iterations, and deadline_seconds guards. Optional action_policy is inherited by every task step, retry, recovery, and nested delegation. An Idempotency-Key header is honoured here too, but it deduplicates workflow-run creation only; it does not make every nested machine action exactly once.

Saved and ad-hoc Workflow Runs accept a create-time action_policy. It is atomically persisted and passed unchanged through task steps, retries, worker recovery, and nested CUA delegation. Budgets, assertions, deadlines, and approvals remain independent controls.
Workflow task steps inherit the same external machine id without changing the DSL. Serialize parallel task branches that share one physical display; independent parallel control requires separately enrolled displays. Control-flow-only steps do not need the driver and remain free.
import os, requests

BASE = "https://coasty.ai/v1"
HEADERS = {"X-API-Key": os.environ["COASTY_API_KEY"]}

# POST /v1/workflows/runs runs a definition inline, without saving a workflow.
run = requests.post(
    f"{BASE}/workflows/runs",
    headers=HEADERS,
    json={
        "machine_id": "mch_test_0123456789abcdef",
        "inputs": {"url": "https://status.example.com"},
        "max_iterations": 5,
        "definition": {
            "steps": [
                {
                    "id": "open",
                    "type": "task",
                    "save_as": "page",
                    "task": "Open {{inputs.url}} and report whether all systems are operational",
                },
                {
                    "id": "gate",
                    "type": "assert",
                    "condition": {"op": "truthy", "value": "{{page.passed}}"},
                },
            ],
        },
    },
    timeout=30,
).json()
print(run["id"], run["status"])      # object == "workflow.run"
EndpointPurpose
POST /v1/workflows/{id}/runsStart a run of a saved workflow.
POST /v1/workflows/runsRun an inline definition without saving a workflow.
GET /v1/workflows/runsList workflow runs. Filter with ?workflow_id= and ?limit=.
GET /v1/workflows/runs/{id}Fetch a single workflow run.
GET /v1/workflows/runs/{id}/eventsOrdered at-least-once SSE for successfully persisted frames; GET the workflow run for authoritative state.
POST /v1/workflows/runs/{id}/cancelCancel a workflow run.
POST /v1/workflows/runs/{id}/resumeApprove or reject a human_approval pause with { approved, note? }.
Workflow event appends, including terminal frames, and Workflow lifecycle callbacks are currently best-effort in-process notifications. They can be absent if storage or the worker fails after the durable workflow state transition. Reconcile with GET /v1/workflows/runs/{id}instead of waiting indefinitely for an event or callback.
JSON
{
  "id": "wfr_5e6f7a8b",
  "object": "workflow.run",
  "status": "running",
  "workflow_id": "wf_1a2b3c",
  "workflow_version": 3,
  "machine_id": "mch_test_0123456789abcdef",
  "inputs": {
    "order_id": "ord_4821"
  },
  "output": null,
  "error": null,
  "awaiting_human_reason": null,
  "awaiting_step_id": null,
  "iterations_used": 0,
  "spent_cents": 0,
  "budget_cents": 500,
  "created_at": "2026-06-01T12:00:00Z",
  "started_at": "2026-06-01T12:00:01Z",
  "finished_at": null,
  "request_id": "req_9c8b7a6d"
}
FieldTypeDescription
idstringUnique workflow-run id, prefixed wfr_.
objectstringAlways "workflow.run".
statusstringqueued, running, awaiting_human, succeeded, failed, cancelled, or timed_out.
workflow_idstringThe workflow this run belongs to (null for inline runs).
workflow_versionintThe version of the workflow definition that ran.
machine_idstringDefault machine for task steps that omit machine_id.
inputsobjectThe inputs you passed in, available as {{inputs.*}}.
outputobjectThe output produced by a succeed step (nullable).
errorobject{ code, message } when the run failed (nullable).
awaiting_human_reasonstringWhy the run paused (nullable).
awaiting_step_idstringThe step id awaiting human approval (nullable).
iterations_usedintLoop iterations consumed against max_iterations.
spent_centsintTotal spend so far, in USD cents.
budget_centsintSpend cap, in USD cents (0 means unlimited).
created_atstringISO-8601 creation timestamp.
started_atstringWhen execution began (nullable).
finished_atstringWhen the run reached a terminal state (nullable).
request_idstringId of the create request, for support and tracing.
API reference — Coasty Computer Use API | Coasty - AI Computer-Use Agent