GoRunner

Start a run of this workflow

Requires scope workflow:run
POST
/api/workflows/{id}/run

Creates a run and hands it to a worker. This returns 202 Accepted — the run has been ACCEPTED, not finished. Nothing has executed when you get the response: the run comes back with status: "pending" and no finishedAt, no durationMs, no steps. Take data.id — that is the run id — and then either poll GET /api/runs/{id} or subscribe to GET /api/runs/{id}/stream (SSE) for progress. Step output lands at steps[].outputData, keyed by steps[].nodeId (the step's stable name), on the run detail.

The request BODY is the trigger payload. Whatever JSON object you POST is handed to the flow as its trigger data and reshaped to look like a real delivery from that trigger's kind, so a webhook flow reads it as {{trigger.body.…}}, gains {{trigger.headers}}/{{trigger.query}}/{{trigger.method}}, and a schedule flow gets a schedule-shaped payload. The body is optional; an empty/absent body runs with an empty payload. To bypass reshaping and supply trigger data ALREADY in delivery shape (replaying a past run's exact triggerData, or a saved test payload), include "__shaped": true at the top level — that key is stripped and the rest is passed through verbatim.

That is exactly why environment is a QUERY parameter and not a body field. The body belongs to the caller; a top-level environment key in it would collide with the caller's own payload, and a __shaped replay carrying that key would both lose the key and silently flip the run's environment.

environment

  • production — executes the PUBLISHED snapshot (latestVersionId), records triggerType: "api", obeys the workflow's concurrencyLimit, and appears in GET /api/runs by default. Publishing is required first: if the workflow is not active, or has no published version, the call is 409 CONFLICT with the message "Publish this workflow before running it in production". If the published version exists but cannot be loaded, it is also 409 ("…could not be loaded — republish it") rather than silently falling back to the draft.
  • test — executes the live DRAFT, records triggerType: "manual", ignores the concurrency limit (so the editor stays responsive), and is filtered out of the default GET /api/runs.
  • Omitted — resolves to production when the workflow is active AND has no unpublished changes; otherwise test. Passing fromNode or versionId forces the default to test, because both are rehearsals by construction.
  • Any other value is a 400.

fromNode / versionId / retryOf

  • fromNode — a PARTIAL run: execution starts at that step, with upstream values seeded from earlier test data rather than executed. It must name a step on the TOP-LEVEL chain (not inside a branch arm or loop body) — an interior or unknown name is 422. It is test-only: combined with environment=production it is a 400. The run records it as startedFromStep.
  • versionId — replays a specific published snapshot instead of the draft ("retry as it ran"). The version must belong to THIS workflow or it is 404. Under environment=production it must be omitted or equal latestVersionId; anything else is 400, because a production run always executes the published version.
  • retryOf — records lineage: this run is a retry of that run. The referenced run must belong to THIS workflow or it is 404. It changes nothing about what executes — pass versionId, fromNode and the original triggerData yourself to actually reproduce a run.

The definition is parsed and every piece it names is checked against what the live worker fleet can run BEFORE a run row is created, so an unrunnable flow is 422 and leaves no pending run behind.

Pass ?wait= to receive the finished run in this same call rather than a run id to poll.

Authorization

bearerAuth
AuthorizationBearer <token>

An API token: Authorization: Bearer grt_…. Mint one in the app under Settings → Workspace → API tokens; the raw value is shown once. Scopes confine the token — see x-permission on each operation.

In: header

Path Parameters

id*string

Workflow id (UUID).

Formatuuid

Query Parameters

environment?string

Which definition executes and how the run is labelled. Omit to let the server choose (production for a clean published workflow, test otherwise). It is a query parameter because the request body is the trigger payload and a body field would collide with it.

Value in

  • "test"
  • "production"
fromNode?string

Start a PARTIAL run at this step instead of the trigger. Must be a top-level step name (nextAction chain of the trigger), not a step inside a branch arm or loop body. Test-only — rejected with environment=production.

versionId?string

Execute this published version's snapshot instead of the draft. Must be a version of this workflow. Under environment=production it must be omitted or equal the workflow's latestVersionId.

Formatuuid
retryOf?string

Record this run as a retry of that run id (lineage only — it does not copy the original's payload, version or start step). Must be a run of this workflow.

Formatuuid
wait?integer

Hold the connection for up to this many seconds (0-30) and answer with the FINISHED run instead of a 202. Omit it, or send 0, for the historical behaviour.

200 means the run reached a terminal state inside the budget — the body is the run with every step's output, so a failure needs no separate shape: read status and the failing step. 202 means it is still going, including when it PAUSED on a delay or an approval; poll GET /api/runs/{id}. The run itself is never bounded by this — it keeps executing past the budget.

Range0 <= value <= 30

Header Parameters

Idempotency-Key?string

Opt-in replay protection, ≤255 characters. A retry carrying the same key and the same method+path+query+body replays the original 202 (same run id) with Idempotency-Replayed: true instead of starting a second run. The QUERY STRING is part of the fingerprint, so the same key with ?environment=production and ?environment=test is a different request and is refused with 422 rather than replayed. Records live 24h.

Lengthlength <= 255

Request Body

application/json

The trigger payload. Any JSON object; it is reshaped into the delivery shape of this workflow's trigger kind unless __shaped is true.

TypeScript Definitions

Use the request body type in TypeScript.

The trigger payload for a run. Any JSON object; it is reshaped to the trigger's delivery shape unless __shaped is true. There is NO environment field here — that is a query parameter precisely so it cannot collide with your payload.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/workflows/497f6eca-6276-4993-bfeb-53cbbbba6f08/run" \  -H "Content-Type: application/json" \  -d '{    "orderId": "A-1001",    "amount": 42.5  }'
{  "data": {    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",    "workflowId": "43c4fa9b-0cbc-4b57-a121-9d7d46a3eaa4",    "workspaceId": "ef0efa32-d1c1-43d4-a5e2-fe7b4f00403c",    "orgId": "25b2c2d5-a7fc-47d0-89e4-8709a1560bfa",    "status": "pending",    "triggerType": "api",    "triggerData": null,    "startedAt": "2019-08-24T14:15:22Z",    "finishedAt": "2019-08-24T14:15:22Z",    "durationMs": 0,    "errorMessage": "string",    "tags": [      "string"    ],    "environment": "test",    "versionId": "14707576-2549-4848-82ed-f68f8a1b47c7",    "versionNumber": 0,    "executedVersionId": "4d3e9121-6455-4ca4-b3e7-67df52d19c9f",    "executedVersionNumber": 0,    "startedFromStep": "string",    "retryOfRunId": "d0a9e625-c445-46be-b052-60aba1a6d053",    "steps": [      {}    ]  }}