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

# lua workflows

> Workflow definitions, runs, schedules and goals from the command line, with every flag and exit codes 0 to 11

`lua workflows` manages pushed [workflow](/concepts/workflows) definitions and their runs. `deploy` changes what runs for every end user; every other verb reads or steers one workflow, one run, one schedule or one goal.

*Verified against lua-cli 3.33.0.*

## Synopsis

```bash theme={null}
lua workflows [action] [target] [extra] [options]
lua workflows <list|view|versions|deploy|activate|deactivate|start|run|delete|env-overlay|export> <workflow>
lua workflows <status|watch|logs|cancel|resume|retry-step|resolve-step|raise-budget|approve|approval-payload|signal|replay|delete-run|workspace|jobs|job-logs> <runId>
lua workflows runs | archive-runs [options]
lua workflows schedules <list|create|patch|pause|resume|delete> [<workflow>|<jobId>]
lua workflows goals <list|get|create|edit|raise|pause|resume|close> [<workflow>|<goalId>]
```

## Description

A workflow version is uploaded with [`lua push workflow`](/reference/cli/push) and does nothing until `lua workflows deploy <name> -v <version|latest>` makes it active. That deploy is a scoped promote: it records a new [agent version](/concepts/releases-and-versions) and prints it as `agentVersion`, so `lua version promote <n>` is the rollback. A chat-composed (dynamic) workflow cannot be deployed by version; the verb refuses with `WORKFLOW_DYNAMIC` (exit 1).

Run verbs take a run id. `start --follow`, `watch` and `logs --follow` stream the run's events and exit when the run ends (0 completed, 4 failed or timed out, 5 canceled) or when it needs a person: an approval, an input, a signal, a billing, budget or exception park (exit 8, with the resuming verb printed) or a consent gate (exit 6). `--wait-for-human` prints that notice and keeps streaming until the run is terminal; `--timeout <s>` ends either mode with exit 7 while the run is still live.

`--json` prints the raw `{success,data}` envelope on stdout for every verb; a refused verb prints the server's error envelope and keeps its exit code. Without an action the command offers a menu (list, run, start, runs). Only `delete`, `delete-run` and `schedules delete` confirm; pass `--yes` under `--ci`, where any prompt fails with `✖ error: Interactive prompt required but --ci flag is set. Provide all required flags or arguments.` (exit 1). `run` is the offline driver; its flags are on [`lua test`](/reference/cli/test).

## Arguments

| Argument | Values                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `action` | A verb, or an alias                        | `ls` → `list`; `get`, `show`, `info` → `view`; `list-versions` → `versions`; `publish` → `deploy`; `on`, `enable` → `activate`; `off`, `disable` → `deactivate`; `test` → `run`; `history` → `runs`; `tail`, `follow` → `watch`; `stop` → `cancel`; `ok` → `approve`; `resolve` → `resolve-step`; `budget`, `raise` → `raise-budget`; `payload` → `approval-payload`; `rm`, `remove`, `del` → `delete`; `erase` → `delete-run`; `env`, `overlay` → `env-overlay`; `codegen`, `export-workflow` → `export`; `archive` → `archive-runs`; `ws` → `workspace`; `job` → `jobs`; `joblogs`, `job-log` → `job-logs`; `goal` → `goals`; `schedule`, `sched` → `schedules` |
| `target` | Workflow name or id, run id, or a sub-verb | Workflow for `list`, `view`, `versions`, `deploy`, `activate`, `deactivate`, `start`, `run`, `delete`, `env-overlay`, `export`; run id for the other run verbs; the sub-verb for `goals` and `schedules`. `-i <name>` and `-r <runId>` are the flag forms                                                                                                                                                                                                                                                                                                                                                                                                         |
| `extra`  | Signal name, goal id, job id or workflow   | `signal <runId> <name>`; `job-logs <runId> <stepId>`; `goals get\|edit\|raise\|pause\|resume\|close <goalId>`; `goals list\|create <workflow>`; `schedules create <workflow>`; `schedules patch\|pause\|resume\|delete <jobId>`                                                                                                                                                                                                                                                                                                                                                                                                                                   |

### Run and deploy actions

| Action                                     | Description                                                                                                                           |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `list`                                     | Workflows: Name, Status, Active, Versions, Form, Id                                                                                   |
| `view <workflow>`                          | One workflow with its schedules, goals and versions                                                                                   |
| `versions <workflow>`                      | The versions table                                                                                                                    |
| `deploy <workflow> -v <ver>`               | Make a version active; prints `agentVersion` (with `--json`, `data.agentVersion` beside `data.workflowId` and `data.activeVersionId`) |
| `activate` / `deactivate <workflow>`       | Enable or pause its schedules and triggers                                                                                            |
| `start <workflow>`                         | Create a run                                                                                                                          |
| `run <workflow>`                           | Offline run of the compiled workflow; flags on [`lua test`](/reference/cli/test)                                                      |
| `runs`                                     | Runs: Run, Status, Trigger, Created, Correlation, Tags                                                                                |
| `status <runId>`                           | One run; `--steps` adds the step table                                                                                                |
| `watch <runId>`                            | Stream events until the run ends or waits for a person                                                                                |
| `logs <runId>`                             | Progress and lifecycle events, latest 500                                                                                             |
| `cancel <runId>`                           | Request or force a cancel                                                                                                             |
| `resume <runId> --step <id>`               | Deliver `resumeData` to a step parked for input                                                                                       |
| `retry-step <runId> --step <id>`           | Re-arm a failed, exception-parked or billing-parked step                                                                              |
| `resolve-step <runId> --step <id>`         | Skip, complete or fail a parked step by hand                                                                                          |
| `raise-budget <runId>`                     | Raise a budget-parked run's caps                                                                                                      |
| `approve <runId> --approval <id>`          | Approve or deny a pending approval                                                                                                    |
| `approval-payload <runId> --approval <id>` | The payload and `payloadFingerprint` for `approve --edit`                                                                             |
| `signal <runId> <name>`                    | Deliver a signal                                                                                                                      |
| `replay <runId> --local`                   | Re-derive the run locally and diff each step                                                                                          |
| `delete <workflow>`                        | Delete the workflow                                                                                                                   |
| `delete-run <runId>`                       | Erase a terminal run's outputs, artefacts and journal                                                                                 |
| `env-overlay <workflow>`                   | Presence of each `env.template()` key; values never printed                                                                           |
| `export <workflow>`                        | Write a version back as pushable source                                                                                               |
| `archive-runs --since <dur> --out <dir>`   | Terminal runs as `<runId>.zip` plus `archive-index.ndjson`                                                                            |
| `workspace <runId>`                        | Show or release the Job-tier workspace                                                                                                |
| `jobs <runId>`                             | The run's `tier: 'job'` steps                                                                                                         |
| `job-logs <runId> <stepId>`                | A Job-tier step's container log                                                                                                       |

A schedule is a workflow's cadence job (at most 5 trigger slots). A goal runs a workflow repeatedly until a judge says the objective is met; its cadence is a schedule tagged with the goal id: `schedules patch`, `pause` and `resume` refuse it with `goal_schedule` (exit 1), and `schedules delete` refuses it while the goal is active or paused. Schedule sub-verb aliases: `ls` → `list`; `new`, `add`, `set` → `create`; `update`, `edit` → `patch`; `hold`, `stop`, `disable` → `pause`; `unpause`, `enable`, `continue` → `resume`; `rm`, `remove`, `del`, `unschedule` → `delete`. Goal sub-verb aliases: `ls` → `list`; `view`, `show`, `info` → `get`; `new`, `add`, `set` → `create`; `update`, `patch`, `change` → `edit`; `bump`, `increase` → `raise`; `hold`, `stop` → `pause`; `unpause`, `continue` → `resume`; `end`, `finish` → `close`.

### Schedule and goal actions

| Action                                      | Description                                                                                              |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `schedules list [-i <workflow>]`            | Every schedule on the agent, or one workflow's; goal-owned rows carry the goal id                        |
| `schedules create <workflow>`               | Create or replace the workflow's schedule; prints the job id, slots and next fire                        |
| `schedules patch <jobId>`                   | Pause or re-enable, and change the backfill rule                                                         |
| `schedules pause` / `resume <jobId>`        | `patch --paused true` / `false`                                                                          |
| `schedules delete <jobId>`                  | Delete the schedule; a done or closed goal's leftover cadence can be deleted here                        |
| `goals list [<workflow>]`                   | Goal, Workflow, Status, Runs, Iter, Judge, Cadence, Verdict, Updated; the next page's command is printed |
| `goals get <goalId>`                        | The goal card and its iteration runs with verdicts                                                       |
| `goals create <workflow>`                   | Create a goal                                                                                            |
| `goals edit <goalId>`                       | Change objective, judge, cadence, caps or note                                                           |
| `goals raise <goalId>`                      | Raise `--max-runs` or `--max-credits`; increases only; re-arms a goal parked at its cap                  |
| `goals pause` / `resume` / `close <goalId>` | `pause` keeps the cadence; `resume` does not backfill missed fires; `close` is final                     |

## Options

### Shared options

| Option                         | Description                                                                                                                                                               | Default                                                      |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `-i, --workflow-name <name>`   | Workflow name or id instead of the positional                                                                                                                             | —                                                            |
| `-r, --run-id <id>`            | Run id instead of the positional                                                                                                                                          | —                                                            |
| `-v, --workflow-version <ver>` | `deploy`, `activate`, `start`, `export`, `env-overlay`, `goals create`, `schedules create`: a semver, `latest` (newest push) or a version id; `activate -v` runs `deploy` | The active version (`latest` for `deploy` and `env-overlay`) |
| `--json`                       | Raw `{success,data}` envelope; `watch` prints one JSON frame per line                                                                                                     | Off                                                          |
| `--all`                        | `list`: include dynamic workflows                                                                                                                                         | Off                                                          |

### `start`

| Option                    | Description                                                          | Default              |
| ------------------------- | -------------------------------------------------------------------- | -------------------- |
| `--input <json\|@file>`   | Run input                                                            | `{}`                 |
| `--idempotency-key <key>` | A repeat returns the existing run instead of creating one            | —                    |
| `--correlation-key <key>` | Caller-chosen key for `runs --correlation-key`                       | —                    |
| `--tag <tag>`             | Repeatable, at most 10                                               | —                    |
| `--budget-credits <n>`    | Run budget in credits, 1 or more                                     | The definition's cap |
| `--wait <s>`              | Server long-poll, 0 to 55 seconds                                    | —                    |
| `--follow`                | Attach `watch`; `--timeout`, `--wait-for-human` and `--events` apply | Off                  |

Prints `✅ Run <runId> · <status>`; with `--json` the envelope's `data` holds `runId` and `status`, plus `deduplicated` or `idempotentReplay` when no new run was created. A run that starts `gated` exits 6; with `--follow` the attached `watch` reaches the same gate and also exits 6 unless `--wait-for-human`. A `concurrencyPolicy: 'forbid'` workflow with a run in flight prints the blocking run id and exits 1.

### `runs`

| Option                                   | Description                                                                                                                                  | Default      |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `--workflow <name>`                      | Only this workflow's runs                                                                                                                    | All          |
| `--status <status>`                      | `queued`, `running`, `cancellation_requested`, `gated`, `suspended`, `waiting`, `completed`, `failed`, `cancelled`, `abandoned`, `timed_out` | All          |
| `--correlation-key <key>`, `--tag <tag>` | Filter by correlation key or tag (repeatable)                                                                                                | —            |
| `--limit <n>`, `--cursor <c>`            | Page size and cursor; the next page's command is printed                                                                                     | —            |
| `--sort <field>`                         | `-createdAt`, `createdAt`, `-durationMs`, `durationMs`                                                                                       | `-createdAt` |

### `status`

| Option     | Description                                                    | Default |
| ---------- | -------------------------------------------------------------- | ------- |
| `--steps`  | Per-step table with attempts, failure cause, usage and billing | Off     |
| `--strict` | Exit 4 or 5 by terminal status instead of 0                    | Off     |

### `watch` and `logs`

| Option             | Description                                                           | Default             |
| ------------------ | --------------------------------------------------------------------- | ------------------- |
| `--after <seq>`    | `watch`: replay from this sequence number                             | Start of the ledger |
| `--timeout <s>`    | Give up after `s` seconds while the run is still live (exit 7)        | None                |
| `--wait-for-human` | Keep streaming through every human boundary until the run is terminal | Off                 |
| `--events`         | `watch`: print raw frames as `{ id, event, data }`                    | Off                 |
| `--step <id>`      | `logs`: only this step's events                                       | All                 |
| `--follow`         | `logs`: switch to `watch`                                             | Off                 |
| `--since <dur>`    | `logs`: accepted, but the latest 500 events are fetched regardless    | —                   |

Ctrl-C detaches without touching the run. A boundary the run has already moved past is printed as history and does not end the watch.

### `cancel`, `resume`, `retry-step`

| Option                 | Description                                                                       | Default |
| ---------------------- | --------------------------------------------------------------------------------- | ------- |
| `--reason <text>`      | `cancel`: recorded on the run                                                     | —       |
| `--force`              | `cancel`: force once the server says force is available (`next: force available`) | Request |
| `--step <id>`          | `resume`, `retry-step`: the parked step. Required                                 | —       |
| `--data <json\|@file>` | `resume`: `resumeData`, validated against the step's `resumeSchema`               | `{}`    |
| `--note <text>`        | `retry-step`: recorded with the retry                                             | —       |

`resume` on an approval step is refused with `APPROVAL_REQUIRES_HUMAN` and names the `approve` command; on a signal wait it is refused with `USE_SIGNAL_ROUTE` and names the `signal` command. `retry-step` refuses with `STEP_NOT_PARKED`, `RUN_TERMINAL` or `STEP_RETRY_CAP`.

### `resolve-step`

| Option                             | Description                                                                                                                                | Default |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `--step <id>`                      | The parked step. Required                                                                                                                  | —       |
| `--outcome <skip\|complete\|fail>` | `skip` continues without it, `complete` supplies its output, `fail` applies the step's `onError` policy. Required; `--action` is a synonym | —       |
| `--output <json\|@file>`           | Required with `complete`, refused otherwise; validated against the step's `outputSchema`, at most 262,144 bytes serialized                 | —       |
| `--note <text>`                    | Recorded with the decision                                                                                                                 | —       |

With an API key the verb refuses with `APPROVAL_REQUIRES_HUMAN`: sign in with a user session instead.

### `raise-budget`

| Option                                                                   | Description                               | Default |
| ------------------------------------------------------------------------ | ----------------------------------------- | ------- |
| `--credits <n>`                                                          | The new credit cap, above the current one | —       |
| `--max-steps <n>`, `--max-job-seconds <n>`, `--max-duration-seconds <n>` | The other raisable caps                   | —       |
| `--note <text>`                                                          | Recorded with the raise                   | —       |

At least one cap is required, every value is an integer of 1 or more, and increases only. A raise that does not cover the next step's reserve parks the run again (`resumed: false`).

### `approve` and `approval-payload`

| Option                        | Description                                                                                   | Default       |
| ----------------------------- | --------------------------------------------------------------------------------------------- | ------------- |
| `--approval <id>`             | The `wfa_…` id (`suspend.approvalId` in `status --steps --json`), never the step id. Required | —             |
| `--decision <approve\|deny>`  | `approve` only                                                                                | `approve`     |
| `--note <text>`               | `approve`: the approver's note                                                                | —             |
| `--edit <json\|@file>`        | `approve`: an edited payload; needs `--fingerprint`                                           | —             |
| `--fingerprint <f>`           | `approve`: the `payloadFingerprint` you read; a stale one is 409 `PAYLOAD_MISMATCH`           | —             |
| `--path <array.path>`         | `approval-payload`: one page of one array of a large payload                                  | Whole payload |
| `--cursor <c>`, `--limit <n>` | `approval-payload`: page inside `--path`; limit 1 to 100                                      | —             |

### `signal`

| Option                    | Description                                                                               | Default |
| ------------------------- | ----------------------------------------------------------------------------------------- | ------- |
| `--payload <json\|@file>` | Validated against the wait's `schema`; a rejected payload does not consume the dedupe key | None    |
| `--dedupe-key <key>`      | A redelivery with the same key is a no-op (`already delivered (duplicate)`)               | —       |

A payload member named like a credential (`token`, and the other reserved names the warning lists) is stored and shown as `[REDACTED]` downstream; the CLI warns and sends it anyway.

### `replay`

| Option      | Description                                                                | Default             |
| ----------- | -------------------------------------------------------------------------- | ------------------- |
| `--local`   | Required; server-side replay is not available                              | —                   |
| `-i <name>` | Pick the compiled workflow when more than one matches the run's graph hash | Match by graph hash |

Exit 4 on a divergence. Needs a compiled project in the current directory.

### `delete` and `delete-run`

| Option    | Description                                                                                | Default |
| --------- | ------------------------------------------------------------------------------------------ | ------- |
| `--yes`   | Skip the confirmation                                                                      | Prompt  |
| `--force` | `delete`: cancel in-flight runs first; without it, runs in flight are 409 `RUNS_IN_FLIGHT` | Refuse  |

`delete` is refused while a goal or schedule still references the workflow (409 `WORKFLOW_REFERENCED_BY_JOBS`, exit 1); the message names each job and the verb that stops it. `delete-run` refuses a live run: cancel it first.

### `env-overlay` and `export`

| Option        | Description                        | Default           |
| ------------- | ---------------------------------- | ----------------- |
| `--out <dir>` | `export`: target directory         | Current directory |
| `--force`     | `export`: overwrite existing files | Refuse            |

`export` compiles the written files before it exits 0; a file the compiler refuses is still written and the verb ends with `export_not_compilable` (exit 1). With `--json` the files are printed inline and nothing is written.

### `archive-runs`

| Option                             | Description                                                                              | Default  |
| ---------------------------------- | ---------------------------------------------------------------------------------------- | -------- |
| `--since <iso\|dur>`               | Window start (`8d`, `36h`, an ISO timestamp). Required                                   | —        |
| `--until <iso>`                    | Window end                                                                               | Now      |
| `--out <dir>`                      | Destination directory. Required; `s3://` and `gs://` are refused                         | —        |
| `--workflow <name>`, `--tag <tag>` | Only matching runs                                                                       | All      |
| `--concurrency <n>`                | Parallel exports, at most 5                                                              | 2        |
| `--no-inputs`, `--no-artefacts`    | Leave inputs or artefacts out                                                            | Included |
| `--retention-days <n>`             | Your run retention; `--since` must fit inside it minus 7 days (`ARCHIVE_WINDOW_TOO_OLD`) | 90       |
| `--connection <id>`                | Storage connection for remote sinks; not available yet                                   | —        |

### `workspace`, `jobs`, `job-logs`

| Option          | Description                                                                             | Default |
| --------------- | --------------------------------------------------------------------------------------- | ------- |
| `--release`     | `workspace`: release the run's workspace; 409 with the step id while a step is using it | Show    |
| `--note <text>` | `workspace --release`: recorded with the release                                        | —       |
| `--attempt <n>` | `job-logs`: attempt to read, 1 or more                                                  | Latest  |
| `--tail <n>`    | `job-logs`: log lines, 1 to 2000                                                        | 200     |
| `--follow`      | `job-logs`: poll every 5 seconds until the step is terminal                             | Off     |

### `schedules create`

| Option                                 | Description                                                                               | Default        |
| -------------------------------------- | ----------------------------------------------------------------------------------------- | -------------- |
| `--cadence <cron\|json\|@file>`        | Repeatable, at most 5: a bare cron expression, a JSON slot, an array of slots, or `@file` | —              |
| `--every <interval>`                   | Interval instead of `--cadence`: `900`, `15m`, `2h`; whole minutes, at least 60 s         | —              |
| `--timezone <tz>`                      | IANA timezone for bare cron entries                                                       | —              |
| `--input <json\|@file>`, `--tag <tag>` | Run input and tags (at most 10) for every fire                                            | —              |
| `--notify <emailApp\|email\|app\|off>` | Where each fire notifies                                                                  | —              |
| `--budget-credits <n>`                 | Per-run budget                                                                            | —              |
| `--backfill-on-enable <n>`             | Replay up to `n` missed fires on re-enable                                                | Off            |
| `-v <ver>`                             | Pin the version each fire runs                                                            | Active version |

### `schedules patch`, `pause`, `resume`, `delete`

| Option                           | Description                                                                       | Default   |
| -------------------------------- | --------------------------------------------------------------------------------- | --------- |
| `--paused <true\|false>`         | `patch`: pause or re-enable                                                       | —         |
| `--backfill-on-enable <n\|none>` | Change the re-enable backfill; `none` clears it                                   | Unchanged |
| `--backfill-now`                 | One-shot backfill on this re-enable; only with `resume` or `patch --paused false` | Off       |
| `--yes`                          | `delete`: skip the confirmation                                                   | Prompt    |

### `goals create`

| Option                                                                    | Description                                                                                      | Default        |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------- |
| `--objective <text>`                                                      | At most 2000 characters. Required                                                                | —              |
| `--max-runs <n>`                                                          | Iteration cap, 1 to 100. Required                                                                | —              |
| `--judge-predicate <spec>`                                                | Deterministic judge: `'<path> <op> [value]'` (`output.signups gte 50`), a JSON object or `@file` | —              |
| `--judge-agent <agentId\|'$self'>`                                        | Agent judge instead of a predicate; write `'$self'` quoted or `self`                             | —              |
| `--judge-role <json\|@file>`                                              | `{ name, instructions, tools }`; required for a `$self` judge                                    | —              |
| `--schema <json\|@file>`                                                  | Required with an agent judge: a JSON Schema with a boolean `done` at the root                    | —              |
| `--cadence`, `--timezone`                                                 | As for `schedules create`; no cadence evaluates the goal right after each run                    | Immediate      |
| `--input`, `--budget-credits`, `--max-total-credits`, `--idempotency-key` | Run input, per-run budget, lineage-wide credit gate, idempotency                                 | —              |
| `-v <ver>`                                                                | Pin the iteration version                                                                        | Active version |

One of `--judge-predicate` or `--judge-agent` is required; `--schema` and `--judge-role` belong to `--judge-agent` only.

### `goals edit` and `goals raise`

| Option                                                                     | Description                                                           | Default   |
| -------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------- |
| `--objective`, `--judge-predicate`, `--cadence` or `--every`, `--timezone` | `edit`: replace that part of the goal                                 | Unchanged |
| `--max-runs <n>`                                                           | `edit`, `raise`: iteration cap, 1 to 100                              | Unchanged |
| `--max-credits <n\|none>`                                                  | `edit`, `raise`: lineage-wide credit gate; `none` clears it on `edit` | Unchanged |
| `--note <text>`                                                            | `edit`: an empty note clears it; `raise` and `close`: recorded        | —         |
| `--if-match <updatedAt>`                                                   | Refuse the write if the goal changed since this `updatedAt`           | —         |

## Examples

Deploy the newest pushed version and start a run that follows to completion, exiting 8 if a person is needed.

```bash theme={null}
lua workflows deploy lead-outreach -v latest --ci
lua workflows start lead-outreach --input @leads.json --follow --ci
```

Follow unattended through approvals for up to an hour.

```bash theme={null}
lua workflows start lead-outreach --input '{"leads":[]}' --follow --wait-for-human --timeout 3600 --ci
```

Read one run and its steps, then answer the approval it is parked on.

```bash theme={null}
lua workflows status wfr_0e0c582b-bf36-4f8a-8ab7-81134f53f802 --steps
lua workflows approve wfr_0e0c582b-bf36-4f8a-8ab7-81134f53f802 --approval wfa_1234 --decision approve --note "Go ahead"
```

List the workflows on the agent.

```bash theme={null}
lua workflows list --ci
```

```text Output theme={null}
🧭 Workflows

┌───────────────┬────────┬────────┬──────────┬────────┬──────────────────────────────────────┐
│ Name          │ Status │ Active │ Versions │ Form   │ Id                                   │
├───────────────┼────────┼────────┼──────────┼────────┼──────────────────────────────────────┤
│ lead-outreach │ active │ 1.0.3  │ 3        │ static │ a95a5d5d-2529-460c-aadb-ec5fb6926000 │
└───────────────┴────────┴────────┴──────────┴────────┴──────────────────────────────────────┘
```

Schedule the workflow weekly and create a goal with a deterministic judge.

```bash theme={null}
lua workflows schedules create lead-outreach --cadence '0 9 * * 1' --timezone Europe/London --input '{"segment":"trial"}' --ci
lua workflows goals create lead-outreach --objective "Reach 50 signups" --judge-predicate 'output.signups gte 50' \
  --cadence '0 9 * * 1' --timezone Europe/London --max-runs 12 --input '{"segment":"trial"}' --ci
```

Delete a schedule without a prompt.

```bash theme={null}
lua workflows schedules delete <jobId> --yes --ci
```

## Exit codes

| Code | Meaning                                                                                        |
| ---- | ---------------------------------------------------------------------------------------------- |
| `0`  | Success, or a followed run completed                                                           |
| `1`  | API refusal (a 4xx other than 404, including a 424 provider refusal), or an unclassified error |
| `2`  | Usage: a bad flag value, an unknown action, no project                                         |
| `3`  | Workflow, run, version, goal or schedule not found                                             |
| `4`  | The run ended `failed` or `timed_out`; a replay divergence                                     |
| `5`  | The run ended `cancelled` or `abandoned`                                                       |
| `6`  | The run is gated awaiting consent                                                              |
| `7`  | `--timeout` reached while the run was still live                                               |
| `8`  | The run is parked waiting for a person (approval, input, signal, billing, budget, exception)   |
| `9`  | Not signed in (401)                                                                            |
| `10` | Forbidden (403)                                                                                |
| `11` | Unavailable: 5xx, connection refused, timeout                                                  |

Which 4xx is which: a 401 or 403 never reaches the verb, because the HTTP client raises it as `auth` (9) or `forbidden` (10) before the verb sees a response, while every other 4xx the server answers with (400, 409, 422, 424) is the verb's own refusal and exits 1 with the server's code on the line. Every escaped error is one line, `✖ <code>: <message>`, plus a hint; `LUA_DEBUG=1` prints the stack.

## See also

* [Operate runs](/build/workflows/operate-runs) — the how-to behind the run verbs
* [Goals and schedules](/build/workflows/goals-and-schedules) — cadences and judges
* [Test workflows offline](/build/workflows/test-offline) and [`lua test`](/reference/cli/test) — the `run` flags
* [`lua push`](/reference/cli/push) — uploading a workflow version
* [Errors and exit codes](/reference/cli/errors-and-exit-codes)
