GoRunner docs
Search or askSearch⌘K

List a workflow’s runs

GET/api/workflows/{id}/runs

Returns one workflow’s runs, newest first: production and test together.

Needs an API token with the Read permission for runs (run:read).

Parameters

Path

idRequired · UUID

The workflow’s ID.

Query

pageOptional · integer

The page, from 1.

limitOptional · integer

Runs a page, 1 to 100. The default is 20; anything else reads as 20, even 500.

Read it

There is no environment filter: tell runs apart by environment. Each row has its triggerData. A run waiting in line reads pending here.

versionId is the live version when the run started. For what actually ran (executedVersionId) and the steps, use Get a run.

Responses

  • 200OK

    A page of runs. None answers [].

  • id isn’t a UUID.

  • The token lacks the Read permission for runs.

  • No workflow with this ID in the token’s workspace.

  • The list couldn’t be read. Try again.

Any call can also answer: 401 UNAUTHORIZED · 401 TOKEN_ENDED · 403 TOKEN_SURFACE_OFF · 403 FEATURE_OFF · 403 EMBED_NOT_ALLOWED · 403 EMBED_NOT_AVAILABLE · 403 ACCOUNT_SUSPENDED · 429 RATE_LIMITED · 503 BUSY · 503 PAUSED · 503 SERVICE_UNAVAILABLE. See Errors.

Request

GORUNNER="https://api.gorunner.io"
GORUNNER_TOKEN="grt_…"  # needs Read for runs
WORKFLOW_ID="your-workflow-id"

curl "$GORUNNER/api/workflows/$WORKFLOW_ID/runs" \
  -H "Authorization: Bearer $GORUNNER_TOKEN"

Response · 200 OK, shortened

json
{
  "data": [
    {
      "id": "8f0c41d2-6b7e-4c1a-9d3f-2a5b7c9e1f04",
      "workflowId": "3b1e5c2a-7d4f-4e8b-a1c6-5f2d9b0e7a31",
      "status": "completed",
      "triggerType": "api",
      "startedAt": "2026-10-25T09:00:00Z",
      "finishedAt": "2026-10-25T09:00:01Z",
      "durationMs": 640,
      "environment": "production",
      "versionId": "f20f671a-2c8e-4b9d-a7f1-6e3b0d5c9a12",
      "versionNumber": 3
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "totalPages": 1
  }
}
Every field

It takes no body.

Response · 200 OK

dataarray of objects

The page’s runs; [] when it has none.

idUUID

The run id. This is what a 202 gives you to poll or stream.

workflowIdUUID
workspaceIdUUID
orgIdUUID
statusstring

pending = queued, nothing has executed. waiting (with ?wait=) = accepted and still waiting in line for a free slot after the wait: a runs-at-once limit holds it, and it starts in order. paused = suspended on a durable wait (delay/approval) and will continue — it is in flight, not finished.

One of pending, running, completed, failed, cancelled, paused, waiting.

triggerTypestring

How the run started. api = a production run through POST /api/workflows/{id}/run; mcp = the same door, by an AI app’s tool. manual = a TEST run through that same endpoint (kept as manual deliberately — the builder’s step-data picker matches it literally). Also webhook (a hosted form’s submission too), cron, poll, error, run_finished, subflow.

triggerData

The trigger payload this run received, in delivery shape (for a webhook: method/headers/query/body). This is exactly what {{trigger.…}} resolves against, and what you would replay as a __shaped body.

startedAttime

When the run was accepted. It may then wait in line for a free slot before a worker starts it (firstStartedAt).

firstStartedAttime or null

When a worker first started the run. durationMs counts from here, so the time from startedAt to this is the time the run waited in line. Null until a worker starts the run, and for a run started on v2026.10.5 or earlier or one that ran inline (a Sub-flow’s, an error handler’s), whose durationMs counts from startedAt.

finishedAttime or null

Absent while the run is in flight.

durationMsinteger or null

How long the run took, in milliseconds: from the first time a worker started the run (firstStartedAt, else startedAt) to its finish. Absent while the run is in flight.

errorMessagestring
tagsarray of strings or null

null on the 202 of a run just accepted, [] when a finished run has none.

environmentstring

Deliberately independent of triggerType — a listen-captured delivery is honestly a webhook run AND honestly a test. GET /api/runs defaults to production only; this workflow-scoped list returns both.

One of test, production.

versionIdUUID or null

The latest published version at the moment the run started — NOT necessarily what executed.

versionNumberinteger or null
executedVersionIdUUID or null

What ACTUALLY executed. Neither answer of this shape carries it, whatever ran (the 202 without ?wait=, GET /api/workflows/{id}/runs): read GET /api/runs/{id}, where absent means the DRAFT ran, so rendering versionId's snapshot would show a graph that never ran.

executedVersionNumberinteger or null

Display number of executedVersionId; carried only where it is.

startedFromStepstring or null

The step a PARTIAL (fromNode) run began at. Empty/absent means the run started at its trigger, which is every ordinary run — without it the trigger would be marked complete on a run that never executed it.

retryOfRunIdUUID or null

Lineage only, set from ?retryOf=.

stepsarray of objects

Per-step results. NOT populated by the run list or by the 202 from the run endpoint — fetch GET /api/runs/{id}. Each entry’s outputData is that step’s output, keyed to the step by nodeId.

paginationobject

Paging envelope returned alongside data on list endpoints.

pageinteger

The 1-based page that was returned.

limitinteger

Rows per page actually applied (not necessarily what you asked for — out-of-range values fall back to 20).

totalinteger

Total matching rows across all pages.

totalPagesinteger