Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.velt.dev/llms.txt

Use this file to discover all available pages before exploring further.

What is the Approval Engine?

Build approval flows as a graph. Define the workflow once, dispatch it against a trigger, and the engine runs everything: state, retries, fan-out, parallel review, SLAs, and webhooks. You write nodes (agent, human) and connect them with edges. You record reviewer decisions and agent resolutions through the REST API. The engine does the rest. Every state change is persisted, replayable, and (when you configure a webhook) pushed to your receiver in real time. This is the part of an approval system you don’t want to build yourself: the runtime that keeps state, handles concurrent reviewers, enforces quorum, fires events, and survives outages.

What you get

  • Agent + human steps in one flow. Run AI agents inline. Park them for human review when needed. Mix and match without writing glue code.
  • Parallel review with quorum. Run reviewers in parallel. Gate downstream work behind a quorum policy: wait for everyone, advance once N approve, or require specific people regardless of count.
  • Real-time webhooks. Every state change is POSTed to your receiver with an HMAC-SHA256 signature and exponential-backoff retry. Missed events are recoverable via /executions/getEvents.
  • Idempotent dispatch. Replay safely. Same idempotencyKey, same execution id, no duplicates. Even concurrent dispatches with the same key return the original id.
  • SLA-aware. Set a deadline per step. The engine transitions to breached and routes through dedicated breached edges.
  • Versioned definitions. Updates increment the version. In-flight executions stay pinned to the version they started on.
  • Static linting. Definitions are validated at write time for cycles, dangling edges, unreachable nodes, and quorum misconfiguration. No surprises at runtime.

Use cases

Marketing copy approval

An AI agent drafts copy. Legal and brand reviewers approve in parallel. A publish agent ships the asset once both approve.

AI agent + human review

Park a blocking agent step until N external resolutions arrive, then continue. Useful for agent-assisted moderation or QA pipelines where humans review specific outputs.

Regulated workflows

Multi-stakeholder sign-off where specific reviewers (compliance, legal) must approve even if a numeric quorum is otherwise met. Every decision is auditable with correlation IDs.

Multi-stakeholder review

3-of-5 quorum with cancelOnQuorum stops bothering remaining reviewers once the threshold is met. System-actor cancellation events go into the audit trail.

Contract sign-off

Sequential or parallel approval chains with SLAs. If a step breaches its deadline, route to an escalation node or fail-fast the execution.

Document approval

Scope workflows per-document so each instance is bound to a specific documentId, with per-execution webhook receivers for downstream integrations.

How it works

  1. Define the workflow. Register a definition with nodes, edges, and optional parallel groups. The engine lints it at write time.
  2. Dispatch an execution. POST a definitionId, an idempotency key, and optional triggerContext (exposed as execution.input.* in edge expressions). The engine pins the current version and enqueues the first step.
  3. The engine drives the flow. Agent nodes run immediately. Human nodes (and blocking agent nodes) park in waiting until decisions arrive.
  4. Record decisions. Call /steps/recordReviewerDecision for humans and /steps/recordAgentResolution for blocking agents. Matching edges fire. Quorum policies trigger their side effects.
  5. Consume events. Subscribe via webhook for real-time delivery. Poll /executions/getEvents with sinceSeq to reconcile after an outage.

Mental model

Definition

A definition is the blueprint. An execution is one live run of that blueprint. A step is one node executing inside an execution.

Nodes

Work units that can run.
TypeWhat it doesParks in waiting?
agentRuns an agent. Non-blocking by default. With blocking: true, parks until external resolutions arrive.Only when blocking: true
humanRequires reviewer approval. Use reviewers: [{ userId, mandatory }]. Legacy reviewerIds[] still works.Yes

Edges

Connections between nodes. Edges optionally carry a when expression like output.passesBrandCheck == true. Expressions compile at write time (pure AST, no eval) and walk at runtime. Supported operators: equality, comparison, boolean, regex, includes, startsWith, endsWith, length, isEmpty. Path roots: output.*, step.*, execution.input.*.

Execution

An execution is one live run of a definition. Dispatch pins the definition version, stamps a correlation ID and idempotency key, and enqueues the first step(s). Lifecycle:
pending → running → completed | failed | cancelled

Step

A step is one runtime instance of a node. Lifecycle:
pending → running → (waiting) → completed | failed | skipped | cancelled | breached
waiting only applies to human steps and blocking agent steps. Step IDs are deterministic, so retries land on the same doc:
  • Root steps (no incoming edges): step_<nodeId>_<timestamp>_<rand>
  • Per-edge fan-out: ${parentStepId}__to__${childNodeId}
  • joinOnQuorum fan-out: group_<groupId>__to__<childNodeId> (one instance regardless of how many group members ran)

Scope

Pick the level that matches how your product is structured.
LevelBound to
apiKeyWorkspace-wide
organizationA specific organizationId
documentA specific documentId under an org
Defaults to { level: "apiKey" }.

Idempotency

Dispatch is idempotent on idempotencyKey. Replay with the same key returns { deduplicated: true, executionId: <original> }. Safe to retry from clients and queues.

Events and webhooks

Every state change writes an event doc with a monotonic seq. Set webhookUrl and webhookSecret on dispatch and externally-visible events are POSTed to your receiver with an HMAC-SHA256 signature and exponential-backoff retry. Recover missed events via /executions/getEvents with sinceSeq.

Get started

Setup

Author a workflow definition, dispatch an execution, configure your webhook receiver, and record decisions end-to-end.

Customize Behavior

Node configuration, edge gating expressions, parallel groups and quorum policies, SLAs, linter rules, event reference, and the error vocabulary.