---
title: "Search runs"
description: "List a project's runs, newest first, filtered by app, workflow, status, schedule, parent, run key and creation time."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ezghcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search runs

[ListRuns](/workflows-api/ListRuns/) lists a project's runs, newest first, with any of these
filters. Filters combine with AND.

| Parameter | Matches |
| --- | --- |
| `appId` | Runs of this app (its ID) |
| `workflow` | Runs of this workflow |
| `status` | Runs with this status: `running`, `cancelling`, `completed`, `failed`, `cancelled` or `timedOut`. Repeat it to match any of several |
| `scheduleId` | Runs this schedule started |
| `parentRunId` | Child runs of this run |
| `runKey` | The run with this run key |
| `createdAfter`, `createdBefore` | Runs created after or before this time, not including it: RFC 3339, to the millisecond at most |
| `limit` | Runs per page, 1 to 100 (default 50) |
| `cursor` | The previous page's `nextCursor` |

```sh
curl "https://workflows-api.ezghcloud.com/v1/organizations/$EZGH_ORG_ID/projects/$EZGH_PROJECT_ID/runs?status=failed&status=timedOut&createdAfter=2026-10-11T00:00:00Z" \
  -H "Authorization: Bearer $EZGH_API_KEY"
```

Or with the CLI, where `--created-after` and `--created-before` also take a date or a duration ago
(`15m`, `2h`, `7d`), and `--app` and `--schedule` also take names:

```sh
ezgh workflows runs list --status failed,timedOut --created-after 24h
ezgh workflows runs list --app web --workflow onboard --all -o json
```

## What a list returns

`{runs, nextCursor}`. Each run in it has:

| Field | Meaning |
| --- | --- |
| `id`, `runKey` | The run's ID, and its run key or `null` |
| `appId`, `workflow` | What it runs |
| `status`, `attempt` | Its status, and how many times it was [retried](/workflows/retrying-runs) plus one |
| `createdAt`, `updatedAt`, `endedAt` | When it was created, when one of these fields last changed (not every step changes it), and when it ended (`null` until then) |
| `scheduleId`, `scheduledTime` | The schedule that started it and its cron time, or `null` |
| `parentRunId` | The run that started it as a child workflow, or `null` |
| `error` | For a `failed`, `cancelled` or `timedOut` run, its error's `code` and `name`, else `null`. [GetRun](/workflows-api/GetRun/) has the whole error |

- **Paging:** when there are more runs, `nextCursor` is set: pass it as `cursor`, with the same
  filters, for the next page. There are no total counts.
- **A cursor belongs to its filters.** Using it with other filters is `400 invalid_cursor`.
- **Lists lag changes by about a second.** [GetRun](/workflows-api/GetRun/) always returns a
  run as it is now.
- **Runs whose data was deleted** (30 days after they ended) aren't listed.

## Permissions

Listing needs `workflows.runs.list` on the project. It lists every run in the project, whatever
workflows the caller's other permissions are limited to. Lists never include inputs or outputs.
Listing isn't recorded in [Trails](/trails).

## Errors

| Status | Meaning |
| --- | --- |
| `400 invalid_request` | A parameter isn't valid, isn't known, or is given twice (only `status` can repeat). `limit` outside 1 to 100 is refused, not adjusted |
| `400 invalid_cursor` | The cursor isn't from this list with these filters |
| `503` | The list is briefly unavailable; retry after `Retry-After`. Everything else in Workflows keeps working |

Source: https://docs.ezghcloud.com/workflows/runs/index.mdx
