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

# Review Workflow Builder (Beta)

> Run multi-step review and approval workflows where AI agents and people sign off together.

## What is the Review Workflow Builder?

The Review Workflow Builder runs review and approval processes for you. You describe the process once as a **definition**, a graph of steps. Whenever something in your app needs review, you start a **run** against it.

The engine walks the graph: it runs AI agents, waits for human approvals, evaluates branching rules, enforces deadlines, sends notifications, and tells you when the run finishes.

You never build the runtime. No state machine, no retry logic, no concurrent-reviewer bookkeeping.

## How it works

1. **Author a definition.** Nodes are the steps. Edges connect them. The engine validates the graph when you save it.
2. **Start a run.** Call the dispatch API, or let a webhook, cron schedule, or connected GitHub / Vercel app start it for you.
3. **The engine executes.** Agent, notification, and sync webhook steps finish without your involvement. Human steps wait for a decision.
4. **Record decisions.** Post each reviewer's approve or reject. Matching edges fire and the run advances.
5. **Consume the outcome.** Receive signed webhooks in real time, or poll the event stream.

## A minimal workflow

One reviewer approves. If they reject, the work goes back to an agent for rework.

```json theme={null}
{
  "definitionId": "doc-signoff",
  "name": "Document sign-off",
  "nodes": [
    {
      "nodeId": "manager-approval",
      "type": "human",
      "config": { "reviewers": [{ "userId": "u_manager_01", "mandatory": true }] }
    },
    {
      "nodeId": "rework-notice",
      "type": "agent",
      "config": { "agentId": "rework-agent-v1", "urlPath": "documentUrl" }
    }
  ],
  "edges": [
    { "from": "manager-approval", "to": "rework-notice", "on": "reject" }
  ]
}
```

That is a complete, valid workflow. [Run it end to end in Setup](/docs/ai/approval-engine/setup).

## Building blocks

| Term           | What it is                                                                                     |
| -------------- | ---------------------------------------------------------------------------------------------- |
| **Definition** | The blueprint: `nodes` + `edges` + optional `groups`. You give it a stable `definitionId`.     |
| **Node**       | One step. Four types: `agent`, `human`, `notification`, `webhook`.                             |
| **Edge**       | "When this node finishes, start that one." Carries an `on` role such as `approve` or `reject`. |
| **Group**      | A set of nodes that run in parallel and share an approval quorum.                              |
| **Execution**  | One live run of a definition. Has an `executionId` and a `steps[]` array.                      |
| **Step**       | One runtime instance of a node inside an execution.                                            |

Definitions are **versioned**. Editing one creates a new version, and runs already in flight finish on the version they started with. Old versions are not readable and there is no rollback, so see [Versioning](/docs/ai/approval-engine/patterns#versioning-and-what-it-does-not-do) before you rely on it.

The graph is a DAG. Revision loops are the one exception: a `reject` edge pointing back to an earlier node creates a bounded retry loop. A definition holds up to 100 nodes and 500 edges.

### Node types

| Type           | What it does                                                           | Parks in `waiting`?                            |
| -------------- | ---------------------------------------------------------------------- | ---------------------------------------------- |
| `agent`        | Runs a Velt agent against a URL, then routes on the result.            | Yes, while the agent runs. Resumes on its own. |
| `human`        | Waits for reviewers to approve or reject.                              | Yes, until you record decisions.               |
| `notification` | Sends an email or Slack message built from the previous step's output. | No.                                            |
| `webhook`      | Calls your own HTTPS endpoint.                                         | Only in `async` mode, until your callback.     |

Full config for each type is in [Customize Behavior](/docs/ai/approval-engine/customize-behavior#node-configuration).

### Lifecycles

```
Execution:  pending → running → completed | failed | cancelled
Step:       pending → running → (waiting) → completed | failed | skipped | cancelled | breached
```

`waiting` means the step is parked. Agent steps resume on their own when the agent finishes. Human and async webhook steps stay parked until you send a decision or a callback.

## Four ways to start a run

| Trigger             | How it starts                                                                                                  | Setup                                                                                     |
| ------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Dispatch API**    | Your backend calls `/executions/dispatch`.                                                                     | [Setup](/docs/ai/approval-engine/setup#step-2-dispatch-an-execution)                           |
| **Inbound webhook** | An external system POSTs to the engine. Supports GitHub, Vercel, and custom signature presets.                 | [Inbound webhook trigger](/docs/ai/approval-engine/customize-behavior#inbound-webhook-trigger) |
| **Cron schedule**   | A cron expression starts a run on a cadence, such as a nightly audit.                                          | [Scheduled trigger](/docs/ai/approval-engine/customize-behavior#scheduled-cron-trigger)        |
| **Installed app**   | Connect the Velt GitHub App or Vercel Integration once, then GitHub and Vercel events route to your workflows. | [App trigger](/docs/ai/approval-engine/customize-behavior#app-trigger)                         |

## Scope

Pick the level that matches how your product is structured. Scope does not select between definitions: you always dispatch a specific `definitionId`, and `definitions/list` returns every level. Scope sets the `organizationId` and `documentId` that trigger-started runs inherit.

| Level          | Bound to                                |
| -------------- | --------------------------------------- |
| `apiKey`       | Workspace-wide. This is the default.    |
| `organization` | One `organizationId`.                   |
| `document`     | One `documentId` under an organization. |

<Note>
  Review Workflow Builder state is partitioned per tenant. Each tenant's definitions, executions, and events live in that tenant's own database.
</Note>

## What the engine handles for you

* **Parallel review with quorum.** Wait for everyone, advance once N approve, or require specific people.
* **Idempotent dispatch.** The same `idempotencyKey` always returns the same `executionId`. Retries never duplicate a run.
* **SLA deadlines.** Set `slaMs` on a step. On breach the step becomes `breached` and routes down your escalation edge.
* **Signed webhooks.** Every state change is POSTed with an HMAC-SHA256 signature and retried with backoff.
* **Recoverable events.** Every event has a monotonic `seq`. Poll with `sinceSeq` to catch up after an outage.
* **Write-time validation.** Cycles, dangling edges, unreachable nodes, and bad quorum settings are rejected before you dispatch.

## Limitations in beta

* You author definitions as JSON. There is no visual builder yet.
* You host the reviewer UI. Render the waiting step and call `recordReviewerDecision`.
* Setting `blocking: true` on an agent node is rejected at runtime. Put a `human` node downstream of the agent instead.
* Editing a definition only affects new runs. In-flight runs are not migrated.

## Get started

<CardGroup cols={2}>
  <Card title="Setup" icon="gear" href="/docs/ai/approval-engine/setup">
    Author a definition, start a run, record a decision, and get the outcome.
  </Card>

  <Card title="Customize Behavior" icon="sliders" href="/docs/ai/approval-engine/customize-behavior">
    Node config, edge routing, quorum policies, triggers, SLAs, events, and errors.
  </Card>

  <Card title="Patterns" icon="list-check" href="/docs/ai/approval-engine/patterns">
    Which option to pick, and the mistakes that look reasonable but break.
  </Card>

  <Card title="REST API Reference" icon="code" href="/docs/api-reference/rest-apis/v2/approval-engine/definitions/create-definition">
    Every endpoint with full request and response schemas.
  </Card>

  <Card title="Review Agents" icon="robot" href="/docs/ai/agents/overview">
    The AI agents your `agent` nodes run.
  </Card>
</CardGroup>
