Find automation runs

automation.runs@1

Lists runs of your automations that you are allowed to see, newest first, a page at a time. Send nothing to list the latest runs, workflowRef or source to see the runs of one automation or version, or ownerFeatureRef with stageId to find your own runs for one step of a feature. It needs a key with Read automations.

List the latest runs

Replace YOUR_FEATURE_ID with the featureId this operation's catalogue entry gives.

# A new operationId for each new request; the same one to retry it.
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations \
  -H "Authorization: Bearer gl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "featureId": "YOUR_FEATURE_ID",
    "export": "runs",
    "contractRef": "automation.runs@1"
  },
  "operationId": "list-runs-1",
  "input": {
    "limit": 10
  }
}'
// A new operationId for each new request; the same one to retry it.
const response = await fetch(
  "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer gl_YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "target": {
        "featureId": "YOUR_FEATURE_ID",
        "export": "runs",
        "contractRef": "automation.runs@1"
      },
      "operationId": "list-runs-1",
      "input": {
        "limit": 10
      }
    }),
  },
);
const receipt = await response.json();
console.log(response.status, receipt);
import requests

# A new operationId for each new request; the same one to retry it.
response = requests.post(
    "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
    headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
    json={
        "target": {
            "featureId": "YOUR_FEATURE_ID",
            "export": "runs",
            "contractRef": "automation.runs@1",
        },
        "operationId": "list-runs-1",
        "input": {
            "limit": 10,
        },
    },
    timeout=30,
)
print(response.status_code, response.json())

Find your runs of one step

Name the feature and the step. states chooses between running and finished runs.

# A new operationId for each new request; the same one to retry it.
curl https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations \
  -H "Authorization: Bearer gl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "featureId": "YOUR_FEATURE_ID",
    "export": "runs",
    "contractRef": "automation.runs@1"
  },
  "operationId": "list-step-runs-1",
  "input": {
    "ownerFeatureRef": "YOUR_OWNER_FEATURE",
    "stageId": "YOUR_STEP_ID",
    "states": "active",
    "pageSize": 20
  }
}'
// A new operationId for each new request; the same one to retry it.
const response = await fetch(
  "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer gl_YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "target": {
        "featureId": "YOUR_FEATURE_ID",
        "export": "runs",
        "contractRef": "automation.runs@1"
      },
      "operationId": "list-step-runs-1",
      "input": {
        "ownerFeatureRef": "YOUR_OWNER_FEATURE",
        "stageId": "YOUR_STEP_ID",
        "states": "active",
        "pageSize": 20
      }
    }),
  },
);
const receipt = await response.json();
console.log(response.status, receipt);
import requests

# A new operationId for each new request; the same one to retry it.
response = requests.post(
    "https://api.growlocal.site/api/v1/profiles/YOUR_BUSINESS_ID/invocations",
    headers={"Authorization": "Bearer gl_YOUR_API_KEY"},
    json={
        "target": {
            "featureId": "YOUR_FEATURE_ID",
            "export": "runs",
            "contractRef": "automation.runs@1",
        },
        "operationId": "list-step-runs-1",
        "input": {
            "ownerFeatureRef": "YOUR_OWNER_FEATURE",
            "stageId": "YOUR_STEP_ID",
            "states": "active",
            "pageSize": 20,
        },
    },
    timeout=30,
)
print(response.status_code, response.json())

Parameters

What goes in input:

Name Type Required Description
ownerFeatureRef string No The feature whose step you are looking for your runs of. Send it together with stageId, and then with no workflowRef, source or limit.
stageId string No The step of that feature to find your runs of. Only runs you started are listed.
states one of active, recent, all No Which runs to list for a step: active (still going, the default), recent (finished) or all. Only with ownerFeatureRef and stageId.
pageSize integer No How many runs a page holds for a step, 1 to 100; 20 when left out. Only with ownerFeatureRef and stageId.
cursor string No The nextCursor of the page before, to read the next one (Pagination). Leave it out for the first page. Only with ownerFeatureRef and stageId.
workflowRef string No Only runs of this automation, by its reference.
source object No Only runs of this exact automation or built-in setup, at the version you name.
source.kind one of preset, workflow Yes preset for a built-in setup, workflow for an automation of your own.
source.ref string Yes The reference of that setup or automation.
limit integer No How many runs to list, 1 to 100. Not together with ownerFeatureRef.

Response

A call that worked answers 200 with an applied receipt; its output holds these fields. GET /catalog/automation.runs@1 answers the complete shape as JSON Schema.

Name Type Description
kind one of general, stage stage when you asked for a step's runs, general for any other list.
runs array of object The runs found. A step's list (kind stage) also tells each run's revision, createdAt, updatedAt and the recipe chosen; the fields below are the ones every list has.
runs[].runRef string The run's reference: use it in Automation run inspector and the run controls.
runs[].workflowRef string or null The automation it belongs to, or null.
runs[].state one of preparing, queued, running, waiting, needs-input, suspended, succeeded, completed-with-errors, failed, uncertain, cancelled Where the run is: preparing, queued, running, waiting, needs-input, suspended, succeeded, completed-with-errors, failed, uncertain or cancelled.
runs[].startedAt string When the run began.
runs[].finishedAt string or null When it ended, or null while it is still going.
runs[].initiator one of member, trigger, call, unknown What started it: member (a person), trigger (an event or schedule), call (another automation or an API call) or unknown.
runs[].nodesTotal integer How many steps the run has.
runs[].nodesDone integer How many of them have finished.
nextCursor string or null A step's list only: send this as cursor for the next page; null at the end.
{
  "status": "applied",
  "operationId": "list-runs-1",
  "output": {
    "kind": "general",
    "runs": [
      {
        "runRef": "11111111-2222-4333-8444-555555555555",
        "workflowRef": "YOUR_AUTOMATION_REF",
        "state": "running",
        "startedAt": "2026-11-13T09:30:00Z",
        "finishedAt": null,
        "initiator": "trigger",
        "nodesTotal": 4,
        "nodesDone": 2
      }
    ]
  }
}

Errors

It reads and changes nothing. Besides the answers every request can get (Errors), its receipt can say:

Status HTTP What it means
rejected 400, or 403 when it's a matter of access Not done. diagnostics says why: each has a code, a path into what you sent and a message.

The codes in diagnostics you're most likely to see:

Code Status What it means
AUTOMATION.FEATURE_NOT_FOUND rejected No such feature here for this key.
AUTOMATION.DEFINITION_NOT_FOUND rejected workflowRef names no automation of this feature.
AUTOMATION.VERSION_NOT_FOUND rejected source names no such version of an automation.
AUTOMATION.CURSOR_INVALID rejected cursor is invalid, has expired or belongs to another list. Start again without it.