List versions
GET/
Returns a workflow’s published versions, newest first, without their definitions.
Needs an API token with the Read permission for workflows (workflow:read).
Parameters
Path
idRequired · UUIDThe workflow’s ID.
Query
pageOptional · integerThe page, from 1.
limitOptional · integerVersions a page, 1 to 100. The default is 20; anything else reads as 20.
Read a row
Each publish that changed something makes one version. Publishing the same tree again makes none.
change says what changed since the version before, by step name; its summary is one line: “Added Log it · Edited Fetch customers”. changeMessage is empty: nothing writes it. publishedBy is missing when a token, not a person, published it.
onCanvas marks the one version, if any, that matches the draft. The live one is the workflow’s latestVersionId. For a version’s tree, get the version.
Responses
- 200OK
A page of versions. None answers
[]. idisn’t a UUID.- 403
FORBIDDENThe token lacks the Read permission for workflows.
- 404
NOT_FOUNDNo workflow with this ID in the token’s workspace.
The versions 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 workflows
WORKFLOW_ID="your-workflow-id"
URL="$GORUNNER/api/workflows/$WORKFLOW_ID/"
URL="${URL}versions?limit=20"
curl "$URL" \
-H "Authorization: Bearer $GORUNNER_TOKEN"const GORUNNER = "https://api.gorunner.io";
const TOKEN = process.env.GORUNNER_TOKEN;
const WORKFLOW_ID = process.env.WORKFLOW_ID;
const res = await fetch(
`${GORUNNER}/api/workflows/${WORKFLOW_ID}/` +
`versions?limit=20`,
{
headers: { Authorization: `Bearer ${TOKEN}` },
},
);
const { data } = await res.json();import os, requests
GORUNNER = "https://api.gorunner.io"
TOKEN = os.environ["GORUNNER_TOKEN"]
WORKFLOW_ID = os.environ["WORKFLOW_ID"]
res = requests.get(
f"{GORUNNER}/api/workflows/{WORKFLOW_ID}/"
f"versions",
params={"limit": 20},
headers={"Authorization": f"Bearer {TOKEN}"},
)
data = res.json()["data"]Response · 200 OK
{
"data": [
{
"id": "f20f671a-2c8e-4b9d-a7f1-6e3b0d5c9a12",
"workflowId": "3b1e5c2a-7d4f-4e8b-a1c6-5f2d9b0e7a31",
"versionNumber": 3,
"publishedBy": "5d8e1f3a-0b6c-4e2d-9f7a-1c3b5e8d2a40",
"changeMessage": "",
"createdAt": "2026-10-24T16:41:00Z",
"onCanvas": true,
"change": {
"changed": [
"Forward to fulfilment"
],
"summary": "Edited Forward to fulfilment"
}
},
{
"id": "1d7f3b9e-2c4a-4e6b-8d0f-5a3c9e1b7d26",
"workflowId": "3b1e5c2a-7d4f-4e8b-a1c6-5f2d9b0e7a31",
"versionNumber": 2,
"publishedBy": "5d8e1f3a-0b6c-4e2d-9f7a-1c3b5e8d2a40",
"changeMessage": "",
"createdAt": "2026-10-22T10:05:00Z",
"onCanvas": false,
"change": {
"changed": [
"Order received"
],
"summary": "Edited Order received"
}
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 2,
"totalPages": 1
}
}Every field
It takes no body.
Response · 200 OK
dataarray of objectsidUUIDworkflowIdUUIDversionNumberinteger1-based, increasing.
definitionobjectOMITTED from the versions LIST; present on the single-version read.
A workflow definition: its fields are in Workflow definition.
publishedByUUIDWho published it (a user id). Absent — never null — when a machine principal or the dev principal published it: a version names a person or nobody.
changeMessagestringKept for old clients: nothing writes it, so it is empty.
change.summary(on the list) says what changed.createdAttimeonCanvasbooleanMarks the AT MOST ONE version whose snapshot equals the current DRAFT. Computed only by the LIST (
falseon a single read). Distinct from LIVE, which is the workflow’slatestVersionId.changeobjectLIST only: what this version changed against the one before it, keyed on step name, as the list shows it. Absent on the single-version read, and on the last row of a page when the version before it is not in hand.
firstbooleanThe first version: nothing to compare with.
addedarray of stringsSteps added, by display name, in canvas order.
removedarray of stringsSteps removed, by display name.
changedarray of stringsSteps changed, by display name.
triggerstringHow the way it starts changed, in words ("Webhook replaced Schedule", "Webhook reconfigured"); absent when it did not.
settingsbooleanThe workflow-level settings changed (timeout, concurrency, error workflow).
summarystringThe one-line form the row shows.
paginationobjectPaging envelope returned alongside
dataon list endpoints.pageintegerThe 1-based page that was returned.
limitintegerRows per page actually applied (not necessarily what you asked for — out-of-range values fall back to 20).
totalintegerTotal matching rows across all pages.
totalPagesinteger