---
title: "Workflows"
description: "Durable workflows written as code in your own application, in TypeScript, Go or Python."
---

> 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.

# Workflows

EZGH Workflows runs durable workflows written as code in your own application. A workflow is an
ordinary TypeScript, Go or Python function whose side effects are wrapped in named steps. EZGH
records each step's result, so a run survives crashes, deploys and outages. It retries what
failed, sleeps for minutes or months, waits for callbacks, starts child workflows and runs steps
in parallel. Schedules start runs on a cron timetable.

Your code runs where you deploy it. EZGH either **pushes** signed requests to your HTTPS endpoint,
or your **pull workers** poll EZGH for work and need no public endpoint.

- [Quickstart: TypeScript](/workflows/quickstart-typescript) — Install the SDK, run a pull worker on your machine, and start a run.
- [Quickstart: Go](/workflows/quickstart-go) — The same quickstart with the Go SDK.
- [Quickstart: Python](/workflows/quickstart-python) — The same quickstart with the Python SDK.
- [Concepts](/workflows/concepts) — Apps, workflows, runs, steps and replay.
- [Push and pull apps](/workflows/push-and-pull) — Serve workflows from an HTTPS endpoint, or run workers that poll.
- [Schedules](/workflows/schedules) — Start runs on a cron timetable, with overlap, catch-up and jitter.
- [Search runs](/workflows/runs) — List a project's runs by app, workflow, status, schedule and time.
- [Limits and usage](/workflows/limits) — Project limits, quotas, fixed limits, usage meters, and deleting projects.

## SDKs

The SDKs are open source (Apache-2.0) on GitHub. They aren't published to npm or PyPI yet:
install them from GitHub by tag.

| Language | Repository | Install | Requires |
| --- | --- | --- | --- |
| TypeScript | [ezgamehost/workflows-sdk-ts](https://github.com/ezgamehost/workflows-sdk-ts) | `npm install github:ezgamehost/workflows-sdk-ts#v0.1.1` | Node.js 20 or later, Bun, Deno, Cloudflare Workers |
| Go | [ezgamehost/workflows-sdk-go](https://github.com/ezgamehost/workflows-sdk-go) | `go get github.com/ezgamehost/workflows-sdk-go@v0.1.0` | Go 1.26 or later |
| Python | [ezgamehost/workflows-sdk-python](https://github.com/ezgamehost/workflows-sdk-python) | `pip install git+https://github.com/ezgamehost/workflows-sdk-python@v0.1.0` | Python 3.12 or 3.13 |

Each SDK has no runtime dependencies. Its README is the full reference for its API.

## Hosts

| Host | What it serves |
| --- | --- |
| `https://workflows-api.ezghcloud.com` | The [Workflows API](/workflows-api): apps, runs, schedules and callbacks |
| `https://workflows-live.ezghcloud.com` | Pull workers' polls, and the SDKs' calls while a run executes |

The SDKs know both hosts; you give them an API key, an organization ID and a project ID. The
[`ezgh workflows`](/cli/reference/workflows) commands manage apps, runs, schedules and callbacks
from the command line.

## Permissions

| Action | Allows | Checked against |
| --- | --- | --- |
| `workflows.apps.create` | Create apps | Project |
| `workflows.apps.list` | List apps | Project |
| `workflows.apps.get` | View an app | App |
| `workflows.apps.update` | Rename an app, or add partitions to a pull app | App |
| `workflows.apps.delete` | Delete an app | App |
| `workflows.apps.sync` | Sync a push app and change its endpoint; announce a pull worker's workflows | App |
| `workflows.apps.rotateSecret` | Rotate a push app's signing secret | App |
| `workflows.runs.list` | List and search runs | Project |
| `workflows.runs.start` | Start runs | Workflow |
| `workflows.runs.get` | View runs, their steps and history | Workflow |
| `workflows.runs.getPayload` | Read runs' inputs, outputs and step outputs | Workflow |
| `workflows.runs.cancel` | Cancel runs | Workflow |
| `workflows.runs.retry` | Retry failed runs | Workflow |
| `workflows.callbacks.complete` | Complete a run's callback as an authenticated caller | Workflow |
| `workflows.workers.poll` | Poll a pull app's task queue as a worker | App |
| `workflows.schedules.create` | Create schedules | Project |
| `workflows.schedules.list` | List schedules | Project |
| `workflows.schedules.get` | View a schedule | Schedule |
| `workflows.schedules.update` | Change a schedule | Schedule |
| `workflows.schedules.pause` | Pause and resume a schedule | Schedule |
| `workflows.schedules.trigger` | Start a schedule's workflow now | Schedule |
| `workflows.schedules.delete` | Delete a schedule | Schedule |
| `workflows.limits.get` | View the project's Workflows limits | Project |

- **An app** is the resource `ezgh:<region>:<org>:<project>:wfa_<slug>`. **Run actions are checked
  on the workflow:** the app's resource name with the workflow's name as its path,
  `…:wfa_<slug>/<workflow>`. So a policy on `…:wfa_*/billing-*` allows only the workflows whose
  names start with `billing-`. `workflows.runs.list` is checked on the project, so it lists every
  run in the project, without inputs or outputs.
- **A schedule** is the resource `…:wfs_<slug>`. Creating a schedule, changing anything but its
  name, resuming it and triggering it also need `workflows.runs.start` on its workflow. Reading a
  schedule's input needs `workflows.runs.getPayload` on its workflow.
- `workflows.runs.getPayload` is a write-level action, so `ReadOnlyAccess` never reads inputs or
  outputs.

| Managed policy | What it allows |
| --- | --- |
| `WorkflowsFullAccess` | Every `workflows.*` action. |
| `WorkflowsReadOnlyAccess` | View apps, runs, schedules and limits, without payloads: `workflows.apps.list`, `workflows.apps.get`, `workflows.runs.list`, `workflows.runs.get`, `workflows.schedules.list`, `workflows.schedules.get`, `workflows.limits.get`. |
| `WorkflowsWorkerAccess` | What a pull worker needs: `workflows.workers.poll`, `workflows.apps.sync`, `workflows.runs.start`, `workflows.runs.get`. |
| `WorkflowsRunnerAccess` | Start and manage runs: `workflows.runs.start`, `workflows.runs.list`, `workflows.runs.get`, `workflows.runs.getPayload`, `workflows.runs.cancel`, `workflows.runs.retry`, `workflows.schedules.trigger`, `workflows.callbacks.complete`. |

Each also allows `organizations.get`, `projects.list` and `projects.get`. `ReadOnlyAccess`
allows what `WorkflowsReadOnlyAccess` does. `AdministratorAccess` and the root user can do all of
these. API keys act with their owner's access: give a workload a key for a [bot](/iam/bots)
with only the access it needs. See [IAM](/iam).

**EZGH SSO:** Workflows actions can be granted to a directory's users by policy. An EZGH SSO
resource token with the `workflows:runs` scope is limited to the `workflows.runs.*` actions and
`workflows.callbacks.complete`, on top of the user's own policies.

## Data

- **Inputs, outputs and callback bodies** are your data: they're readable only with
  `workflows.runs.getPayload`, and never appear in Trails. A run's events contain IDs, counts and
  error codes, never payloads.
- **A run's data is deleted 30 days after the run ends:** its steps, history, inputs and outputs.
  Its run key can then be used again.
- **Deleting a project or organization** deletes its Workflows apps, schedules and run data within
  an hour; see [Limits and usage](/workflows/limits#deleting-a-project-or-an-organization).

## Trails

Workflows' events have the event source `workflows.ezghcloud.com`.

- **Recorded:** changes to apps and schedules (`CreateApp`, `UpdateApp`, `DeleteApp`, `SyncApp`,
  `RotateAppSecret`, `CreateSchedule`, `UpdateSchedule`, `DeleteSchedule`, `PauseSchedule`,
  `ResumeSchedule`, `TriggerSchedule`), `CancelRun`, `RetryRun`, and `AnnounceWorkflows` when a
  pull worker's announcement changes an app's workflows. Reads follow the
  [rules for reads](/trails#what-trails-records); listing runs (`ListRuns`) and reading limits
  (`GetLimits`) aren't recorded.
- **Recorded only when refused:** `StartRun`, `CompleteCallback` and `PollTasks`. Successful starts,
  completions and polls produce no event.
- **Never recorded:** runs started by schedules and child workflows (no request started them),
  callbacks completed by their URL (no credential), and the SDKs' calls while a run executes.

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