List workflows
GET/
Returns a page of the workspace’s workflows, with filters and a sort.
Needs an API token with the Read permission for workflows (workflow:read).
Parameters
Query
pageOptional · integerThe page, from 1. Below 1, or not a number, reads as 1.
limitOptional · integerWorkflows a page, 1 to 100. The default is 20; anything else reads as 20.
qOptional · stringFinds words in the name, description, tags and the apps used, by id or name (
stripe,Google Sheets). Ignores case. Not step names.statusOptional · stringdraft,active,pausedorfailing: live, and its latest finished production run failed.tagOptional · stringKeeps workflows with this tag, ignoring case. One tag a call.
folderOptional · stringA folder’s ID, or
nonefor workflows in no folder. Only workflows filed directly in it.sortOptional · stringupdated(the default, newest first),name(A to Z),lastrun(latest run first) orstatus(paused, live, then drafts).viewOptional · stringsummaryleaves out each row’sdefinitionandruns7d. Every row hassummary: the trigger, the apps, the step count and the steps to set up.
What are the rarely used parameters?
lastRunStatusOptional · stringKeeps workflows whose latest production run is in this state:
completed,failed,running,pending,cancelledorpaused.idsOptional · stringUp to 100 workflow IDs, separated by commas. Answers just those, as one page, and ignores every other filter.
countsOptional · stringtrueaddscounts: the matching workflows by state, and how many are failing. Not withids.
What a row holds
Without view=summary, each row holds its whole draft definition, so a page can run to hundreds of kilobytes. Ask for the summary when you only list them.
lastRun is the latest production run, and test runs never count. A failing row adds failingSince and failingRun, the run that made it fail.
A token without the Read permission for runs gets only status and startedAt of those runs, and no failingSince.
No row holds webhookToken. Read it with Get a workflow.
Responses
- 200OK
A page of workflows. A page past the end has no rows, and
paginationis still filled in. folderisn’t a folder ID ornone,idsisn’t a list of up to 100 IDs, orstatus,lastRunStatus,sortorviewisn’t one of its values.- 403
FORBIDDENThe token lacks the Read permission for workflows.
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 workflows
URL="$GORUNNER/api/"
URL="${URL}workflows?status=active&view=summary&limit=50"
curl "$URL" \
-H "Authorization: Bearer $GORUNNER_TOKEN"const GORUNNER = "https://api.gorunner.io";
const TOKEN = process.env.GORUNNER_TOKEN;
const res = await fetch(
`${GORUNNER}/api/` +
`workflows?status=active&view=summary&limit=50`,
{
headers: { Authorization: `Bearer ${TOKEN}` },
},
);
const { data } = await res.json();import os, requests
GORUNNER = "https://api.gorunner.io"
TOKEN = os.environ["GORUNNER_TOKEN"]
res = requests.get(
f"{GORUNNER}/api/workflows",
params={
"status": "active",
"view": "summary",
"limit": 50,
},
headers={"Authorization": f"Bearer {TOKEN}"},
)
data = res.json()["data"]Response · 200 OK, shortened
{
"data": [
{
"id": "3b1e5c2a-7d4f-4e8b-a1c6-5f2d9b0e7a31",
"name": "Order intake",
"status": "active",
"triggerType": "webhook",
"hasUnpublishedChanges": false,
"folderId": "7a2c9e41-5b3d-4f08-a6e1-2d9c4b7f0e13",
"tags": [
"orders"
],
"createdByName": "Ada Lovelace",
"updatedAt": "2026-10-24T16:40:00Z",
"failing": false,
"summary": {
"trigger": {
"pieceId": "webhook",
"actionId": "catch_webhook",
"displayName": "Catch Webhook"
},
"pieces": [
{
"id": "webhook",
"name": "Webhook"
},
{
"id": "http",
"name": "HTTP Request"
}
],
"stepCount": 1,
"needsSetup": 0
},
"lastRun": {
"id": "8f0c41d2-6b7e-4c1a-9d3f-2a5b7c9e1f04",
"status": "completed",
"startedAt": "2026-10-25T08:59:58Z",
"finishedAt": "2026-10-25T09:00:00Z"
}
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 1,
"totalPages": 1
}
}Every field
It takes no body.
Response · 200 OK
dataarray of objects[]when the requested page is past the last one.idUUIDnamestringdescriptionstringdefinitionobjectThe workflow definition, and the single most important shape in this API.
A workflow definition: its fields are in Workflow definition.
statusstringdraft= never published.active= live, triggers registered and the webhook URL reachable.paused= was live, now switched off. Server-owned: it moves only through publish/unpublish, never through a create or update body.One of
draft,active,paused.triggerTypestringMirrors
definition.trigger.typefor dispatch. Derived server-side from the definition by every update and publish, so treat it as read-only in practice. A create that sends its own value keeps it until then, unchecked.One of
manual,cron,webhook,callable,event,error,run_finished,poll.cronExpressionstring or nullNothing derives or reads this: the schedule runs from the trigger’s own
config, andnextRunAtprojects from it too. Null unless a caller wrote one withPUT /api/workflows/{id}.webhookTokenstring or nullThe secret segment of the public webhook URL. Made by the first update of a webhook workflow, or at publish; absent until then (so absent in the answers of create, duplicate and import). Returned ONLY to a caller holding
workflow:run: byGET /api/workflows/{id}and in the answers of update, publish, unpublish and restore (rotate answers it to its caller). It is never present on a list row, an export or a version snapshot. It is a bearer capability against an unauthenticated endpoint — possessing it is the ability to fire this workflow in production. Rotate it withPOST /api/workflows/{id}/webhook/rotate.latestVersionIdUUID or nullThe published snapshot production executes. Absent means nothing has ever been published.
definitionRevintegerOptimistic-lock revision, bumped by every definition save. Populated by
GET /api/workflows/{id}, by the update response and by the answers of create, duplicate and import; absent (0) on list rows. Send it back asexpectedRevon an update to refuse a clobbering write.hasUnpublishedChangesbooleanThe draft has moved ahead of the published version. Computed on the single-workflow read and on every list row; always
falsefor a workflow never published.folderIdUUID or nullAbsent/null = uncategorized. Changed only through
PUT /api/workflows/{id}/folder.tagsarray of stringsChanged only through
PUT /api/workflows/{id}/tagsor the bulkaddTagsoperation — never through the workflow update body.testPayloadsobject or nullThe saved test-fixture library, stored outside the definition so publish and version restore never reset it.
pinnedDataobject or nullThe pin library (
{"pins": {"<stepName>": {"data": …, "pinnedAt": …, "configHash": …, "staleAt": …, "pieceId": …}}}). A pinned step emits its fixture instead of executing, and only on test runs.configHash,staleAtandpieceIdare the server’s: a step whose config changed keeps its pin marked stale, and a stale pin is not replayed (the step runs); a step whose app was replaced loses it.workspaceIdUUIDStamped from the credential’s scope; never accepted from a request body.
orgIdUUIDcreatedByUUID or nullcreatedByNamestringList rows only: the creator’s name, else their email address. Absent when the creator is unknown or not a member of the organization (staff who built it on a support visit, someone since removed), and on every row for an embedded person whose installation switched
presenceoff (an embedded person is never told an address).createdAttimeupdatedAttimeWhen the workflow itself was last edited. Publishing, pausing, tagging and filing it are not edits and leave it alone.
failingbooleanList rows only: the workflow is live (
status: active) and its latest FINISHED production run (one that worked or failed) failed. A later run that is waiting, running, held or was cancelled changes nothing, and test runs never count. A paused or draft workflow is never failing.failingSincetimeOnly on a failing row: when the first production run failed after the last one that worked (runs cancelled, held or running in between neither break nor begin the streak). Left out for a caller without
run:read.failingRunobjectOnly on a failing row: the run that decided it, its latest finished production run, with why it failed. It is
lastRununless a later run is waiting, running, held or was cancelled. Withoutrun:readit carriesstatusandstartedAtalone.idUUIDstatusstringOne of
failed.startedAttimefinishedAttime or nullerrorobjectWhy it failed, as
lastRun.errorsays it.stepstring or nullstepKeystring or nullmessagestringsummaryobjectList rows only: what a list draws instead of the definition.
triggerobject or nullThe chosen trigger; null while none is chosen.
pieceIdstringactionIdstringdisplayNamestringpiecesarray of objectsThe apps the workflow uses, each once, in walk order (the trigger first), with their display names.
idstringnamestringstepCountintegerSteps after the trigger, across branch arms, loop bodies and error paths.
needsSetupintegerSteps (and a chosen trigger) the editor marks to configure:
valid: false, or no app and action chosen.runs7darray of integersList rows without
view=summaryonly: counted runs per UTC day over the last seven days, oldest first (production runs that are not a sub-flow’s, cancelled runs left out).nextRunAttimeNext fire time of an active schedule workflow, projected from its cron in the trigger’s own timezone. Populated by the list endpoint.
lastRunobject or nullThe most recent PRODUCTION run’s outcome (test runs never count). Populated on list rows only. Without
run:readit carriesstatusandstartedAtalone.idUUIDfinishedAttime or nullerrorobjectOnly when
statusisfailed: why.stepstring or nullThe display name of the step it failed at; null when the reason names no step.
stepKeystring or nullmessagestringThe reason’s first clause, at most 160 characters.
statusstringOne of
pending,running,completed,failed,cancelled,paused.startedAttimepaginationobjectPagination block returned alongside a workflow list.
pageintegerlimitintegerThe limit ACTUALLY applied after coercion, not necessarily the one you asked for.
totalintegerTotal matching workflows across all pages.
totalPagesintegercountsobjectOnly with
counts=true: the list’s workflows by state, and how many of them are failing (live, and the latest finished production run failed), under the same filters as the list.activeintegerpausedintegerdraftintegerfailinginteger
What else is on each row?
createdByName is who made it, by name or email. It is missing when that person is unknown or has left. nextRunAt is the next time a live schedule fires. runs7d counts production runs for each of the last 7 days, oldest first, in UTC; cancelled runs and sub-flow runs aren’t counted.