---
title: "Start a run of a saved workflow"
method: POST
path: "/v1/workflows/{workflow_id}/runs"
tags: ["workflows"]
---

# Start a run of a saved workflow

`POST /v1/workflows/{workflow_id}/runs`

Scope: `workflows:write`. Runs the saved workflow. Managed defaults charge 5 credits per completed `task` step on v3/v4/v5 and 8 on v1; other steps are free and budget_cents caps managed spend. With a live Coasty key, BYOK runs every task role on YOUR provider key, reserves/charges zero Coasty platform credits, and persists actual provider tokens; no silent fallback. Under test auth, managed-mode Workflow task children remain deterministic sandbox execution. Any BYOK header or provider metadata instead returns 422 LLM_PROVIDER_UNSUPPORTED before execution: BYOK is unavailable for synthetic test runs, workflows, and schedules. Use managed mode or a live Coasty API key. Test execution never decrypts or requires a stored provider key and does not call or bill Anthropic/OpenAI. Task steps do not inherit /v1/predict trajectory, HD-image, or combined-prompt surcharges. The live BYOK key snapshot is encrypted for recovery and scrubbed at terminal state.

## Headers

- `Idempotency-Key` string
- `X-LLM-Provider` 'anthropic' | 'openai'
- `X-LLM-Api-Key` string
- `X-LLM-Model` string

## Request body

- StartWorkflowRunRequest
  - `inputs` object, nullable — Bound input values.
  - `machine_id` string, nullable — Default managed or connected external machine for task steps.
  - `budget_cents` integer, nullable — Hard spend cap across all task steps; 0 or null = unlimited.
  - `max_iterations` integer, nullable
  - `deadline_seconds` integer, nullable
  - `webhook_url` string, nullable
  - `metadata` object, nullable
  - `definition` WorkflowDefinition — Workflow DSL version 2026-06-01. The schema encodes each strict step shape and recursive body. The server additionally enforces globally unique step ids, a configurable aggregate step count, definition byte size, and recursive workflow/output depth.
    - `steps` WorkflowStep[], required — unresolved $ref
    - `output` object, nullable
  - `inputs_schema` WorkflowInputsSchema — Typed input declarations. The server also enforces the configured serialized byte ceiling.
  - `llm` LlmConfig — Opt-in BYOK model selection. provider 'managed' (or omitting llm) keeps the platform default. There is deliberately no api_key field (422 if attempted): keys ride the X-LLM-Api-Key header or the encrypted /v1/llm/keys store only. Once BYOK is requested there is NO silent fallback to Coasty's platform LLM keys.
    - `provider` 'managed' | 'anthropic' | 'openai' — Whose LLM account runs the harness. Anything else is 422 LLM_PROVIDER_UNSUPPORTED.
    - `model` string, nullable — Main worker model. Defaults: claude-sonnet-5 (anthropic), gpt-5.6-sol (openai). Model ids are 1-256 characters, begin with a letter or number, and then use only letters, numbers, dot, underscore, colon, slash, plus, at-sign, or hyphen; invalid ids return 422 LLM_MODEL_INVALID. The selected provider can still reject an unknown or inaccessible model. It must be vision-capable.
    - `grounding_model` string, nullable — Override for pixel-coordinate grounding. Defaults to model. Grounding quality is tuned on the platform model; expect best results with the defaults.
    - `compaction_model` string, nullable — Override for trajectory compaction. Defaults to model. A cheaper model here is the classic cost tune.
    - `code_agent_model` string, nullable — Override for the code agent. Defaults to model.
  - `action_policy` ActionPolicy — Opt-in, fail-closed post-model action enforcement. The complete normalized batch is checked atomically before actions are returned or dispatched. allowed_actions and blocked_actions cannot overlap. Prediction, Session, and Parse surfaces use prediction action names such as type_text; direct Machine routes use command names such as type. Task, Workflow, and Schedule policies are create-time controls inherited across execution and recovery.
    - `allowed_actions` string[], nullable — Optional action allowlist. Values are trimmed and lowercased before validation; duplicates after normalization are rejected. Terminal done/fail/awaiting_human signals remain allowed.
    - `blocked_actions` string[] — Action denylist. Values are trimmed and lowercased before validation; duplicates after normalization are rejected.
    - `blocked_keys` string[] — Keys forbidden in key_press, key_combo, and modifier-bearing actions. Values are trimmed and lowercased; duplicates after normalization are rejected; esc aliases escape.
    - `block_window_close` boolean — Block explicit close commands and common Alt+F4, Ctrl/Cmd+W, and Cmd+Q shortcuts.
    - `max_actions` integer, nullable — Maximum number of actions admitted in one prediction/session step, parsed action batch, or direct Machine batch.
    - `coordinate_bounds` CoordinateBounds — Inclusive coordinate rectangle in the request screenshot's pixel space.
      - `min_x` integer
      - `min_y` integer
      - `max_x` integer, required
      - `max_y` integer, required

## Response `200`

The started workflow run.

- WorkflowRunResponse
  - `id` string, required
  - `object` 'workflow.run', required
  - `status` 'queued' | 'running' | 'awaiting_human' | 'succeeded' | 'failed' | 'cancelled' | 'timed_out', required
  - `workflow_id` string, nullable
  - `workflow_version` integer, nullable
  - `machine_id` string, nullable
  - `inputs` object
  - `output` object, nullable
  - `error` object, nullable
  - `awaiting_human_reason` string, nullable
  - `awaiting_step_id` string, nullable
  - `iterations_used` integer
  - `spent_cents` integer
  - `budget_cents` integer, nullable
  - `llm` RunLlmInfo — Credential-free BYOK attribution returned by agent runs and workflow runs. Only these allowlisted fields are public.
    - `provider` 'anthropic' | 'openai', required
    - `model` string, required
    - `key_fingerprint` string, required
    - `key_source` 'header' | 'stored', required
    - `key_scrubbed` boolean, required
  - `webhook_url` string, nullable — Workflow lifecycle callback destination. Workflow callbacks are best-effort in-process notifications (up to 3 attempts), have no durable delivery UUID/outbox, and can be missed if the worker fails. Reconcile with GET /v1/workflows/runs/{run_id}.
  - `webhook_secret` string, nullable — Returned by create and its exact bounded Idempotency-Key replay; null on get/list. The pinned per-run secret is encrypted at rest through delivery/replay recovery and later scrubbed.
  - `metadata` object, nullable
  - `created_at` string, nullable
  - `started_at` string, nullable
  - `finished_at` string, nullable
  - `request_id` string, nullable

## Other responses

- `400` — Invalid request body or parameters.
- `401` — Missing, invalid, or revoked API key. Pass `X-API-Key: sk-coasty-live-...` (or test).
- `402` — Insufficient balance for this operation. Direct metered API calls and managed-machine runtime use the prepaid Developer API wallet; scheduled execution is the documented consumer subscription-credit exception. Follow the operation's billing fields and top up the matching balance in the dashboard.
- `403` — API key lacks the required scope or tier-feature is unavailable on the caller's plan.
- `404` — Resource not found in this key's namespace.
- `409` — The resource state conflicts with this operation.
- `413` — The request body exceeds the endpoint limit.
- `422` — The JSON shape is valid but one or more values violate the endpoint contract.
- `429` — Rate or concurrency limit exceeded.
- `500` — Unexpected server error. Retry with exponential backoff.
- `502` — An upstream dependency returned an invalid response.
- `503` — A required service is temporarily unavailable.
- `504` — An upstream dependency timed out.

---

[API](https://skmtc.net/coasty/apis/coasty-public-api.md) · [All operations](https://skmtc.net/coasty/apis/coasty-public-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/coasty/coasty-public-api/revisions/f50d93b0d8a1/schema)
