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

# Workflows

> Durable graph workflows on Restate: the node types that exist, how waiting works, and what survives a crash

A **workflow** is a graph of steps that runs durably. Where a tool call is a single attempt that either succeeds or does not, a workflow's progress is checkpointed — it survives a process restart, and it can sit waiting for a human or a webhook for as long as it needs to.

Workflows are orchestrated by **Restate**. Each run is a keyed durable object; completed steps are not re-executed on recovery.

## When a workflow instead of an agent

An agent decides what to do next. A workflow already knows.

Reach for a workflow when the sequence is fixed and the guarantees matter: a step must not run twice, a human must sign off in the middle, the process must survive a deploy. Reach for an agent when the path depends on what it finds.

They compose: a workflow can call an agent as a step, and an agent can invoke a workflow as a tool.

## Node types

Sixteen step types exist.

| Group          | Types                                              |
| -------------- | -------------------------------------------------- |
| Entry and exit | `start`, `end`                                     |
| Call something | `capability`, `agent`, `workflow` (a sub-workflow) |
| Control flow   | `branch`, `parallel`, `loop`, `foreach`            |
| Wait           | `approval`, `pause`, `schedule`, `webhook`         |
| I/O            | `http`, `notify`                                   |

### The designer palette

The Portal's visual designer offers a subset. Its left panel has sections for **Agents**, **Capabilities**, and **Workflows** — populated by what you attach — plus:

* **Control Flow**: Branch, Parallel, Loop, For Each, Notify, End
* **Wait States**: Approval, Pause, Schedule, Webhook

<Note>
  `http` is a real, working node type with a properties panel and a runner, but it is **not in the palette**. It can only enter a graph through AI generation or an imported definition. Prefer an attached connector for HTTP calls — see the credentials warning below.
</Note>

## How waiting works

Waiting is the part that distinguishes a workflow from a script. A workflow can sit idle for days without holding a process open, and pick up exactly where it left off.

### Approval

An approval node creates a durable wait. The run sits in the waiting state until somebody resolves it.

Resolution happens on the workflow **run detail** page in the Portal, which renders a "Pending approvals" block with **Approve** and **Deny** buttons.

Workflow-run approvals accept approve or deny only. The broadening verbs available in agent chat — approve for this thread, approve always — are rejected here: a workflow run has no thread and no user to broaden over.

Who may resolve one: an account Admin or Owner, or the user who created the run. An agent or service principal that started a run **cannot** resolve its own gate.

### Webhook

A webhook node waits for an inbound call, racing a timer. Default timeout: **24 hours** (expressed as a value plus a unit — minutes, hours, or days).

On timeout the node does **not** fail. It returns `{ "webhook_received": false, "timed_out": true, … }` and the graph continues. Branch on that if a timeout should change the path.

The resume URL carries a random per-wait bearer token. A bad or expired token gets a deliberately vague "Invalid or expired webhook" — it does not confirm whether the run exists.

### Schedule

`schedule` waits until a datetime or a cron occurrence, with an IANA timezone that defaults to UTC.

### Notify

The notify node sends **email only**. Any other channel is a terminal error, and a recipient is mandatory.

## Run states

| State       | Meaning                             |
| ----------- | ----------------------------------- |
| `pending`   | Accepted, not yet started           |
| `running`   | Executing                           |
| `suspended` | Durably waiting (approval, webhook) |
| `paused`    | Explicitly paused                   |
| `success`   | Completed                           |
| `failed`    | Terminated with an error            |
| `canceled`  | Cancelled                           |
| `bailed`    | Abandoned                           |

## Retries

Retry behavior is a **policy you set**, at the workflow level or overridden per node. When neither is set, Restate's own default applies.

A policy carries an initial delay, an exponential factor, a maximum delay, a maximum number of attempts, and a maximum total duration. A node-level or workflow-level timeout overrides the policy's maximum duration, so a node cannot outlive its timeout by retrying.

## Templating

Values flow between steps with `${…}` expressions evaluated as JSONata over `input`, `source`, and `steps` — plus `item` and `index` inside a loop.

## Credentials in a workflow

<Warning>
  Headers and bodies you type into an `http` node are stored **in the workflow definition** and are readable by anyone with write access to that workflow. There is no secrets bag in a workflow definition. Attach a connector and call it as a capability step instead — connector credentials are encrypted at rest and never appear in the graph.
</Warning>

## Building one

Three ways, all from the Portal's Workflows section:

* **Empty graph** — the visual designer.
* **Generate with AI** — describe what the workflow should do in one field; generation takes minutes and lands in a build queue you can inspect.
* **Build queue** — the history of generated builds.

The designer blocks a save on: a missing name, an edge pointing at a node that does not exist, no steps, an unconfigured step, or no End node. An End node that is unreachable is a warning, not an error.

Manual runs open a form built from the Start node's input schema, with a raw-JSON mode as a fallback.

## Where workflows attach

A workflow can be bound to an agent (it appears as a tool the agent can invoke) and to an MCP gateway (the workflow system tools are, in fact, the only system tools a gateway exposes).

***

Next: [WebAssembly Plugins](/docs/learn/concepts/webassembly) — custom logic in a sandbox.
