For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
  • Getting Started
    • Introduction
    • How Verifa Works
    • Quickstart
    • Choosing an Integration Method
  • Use Cases
    • KYC Onboarding
    • Age Verification
    • AML Compliance
    • Fraud Prevention
    • Marketplace Trust & Safety
  • Core Concepts
    • Overview
    • Sessions
    • Verifications & Checks
    • Workflows
    • Identities
    • Cases
    • Screening & Reports
    • Lists
  • Integration Guides
    • Overview
    • JavaScript SDK
    • Web Capture Flow
    • API-Only Integration
    • Mobile SDK
    • Webhooks Guide
    • MCP Server
    • Migrating from Persona
  • API Details
    • Overview
    • Authentication
    • Pagination
    • Rate Limiting
    • Versioning
    • Errors
    • Webhooks
    • Idempotency
    • Key Inflection
    • Data Access
    • Data Retention
  • Tutorials
    • Creating Your First Verification Session
    • Creating a Workflow
    • Receiving Webhooks & Validating Signatures
    • Handling Webhook Events
    • Custom Document Types & AI Extraction
  • Best Practices
    • Testing
    • Preventing Duplicates
    • Fraud Signals
    • Changelog
  • API Reference
On this page
  • How workflows work
  • Workflow lifecycle
  • Graph structure
  • Start node
  • Policy node
  • Conditional node
  • Terminal node
  • Wait node (external gate)
  • Example workflow
  • Data requirements
  • Rollout percentage
  • Default workflows
  • Workflow API
  • Create a workflow
  • List workflows
  • Publish a workflow
  • Set as default
  • Validation
  • Related
Core Concepts

Workflows

Was this page helpful?
Previous

Identities

Next
Built with

A workflow defines the verification pipeline for a session — which checks to run, in what order, and how to route based on results. Workflows are directed acyclic graphs (DAGs) where each node is a check, a conditional branch, or a terminal outcome.

How workflows work

When a session enters processing, the workflow engine:

  1. Loads the workflow graph assigned to the session (or the org’s default)
  2. Starts at the entry node
  3. Executes each check node, storing results as it goes
  4. Routes through conditional nodes based on check outcomes or extracted data
  5. Reaches a terminal node: approved, rejected, or needs_review

The engine supports automatic retries (up to 4 per check), external gates for human-in-the-loop decisions, and percentage-based rollout for canary deployments.

Workflow lifecycle

StatusDescription
draftUnder construction. Cannot be assigned to sessions.
publishedActive and available for session processing.

Workflows are versioned — every edit creates an immutable version snapshot for audit and rollback. Sessions always execute against the version that was active when processing began.

Graph structure

Workflows use a graph format with four node types:

Start node

The entry point. Every workflow has exactly one.

1{
2 "start": {
3 "type": "start",
4 "next": "document_ocr_step"
5 }
6}

Policy node

Executes a verification check. Routes to different nodes based on the outcome.

1{
2 "face_match_step": {
3 "type": "policy",
4 "policy": "face_match",
5 "config": {
6 "security_level": "standard"
7 },
8 "on_pass": "age_check_step",
9 "on_fail": "review_terminal",
10 "on_error": "review_terminal"
11 }
12}

Conditional node

Routes based on extracted data or check results. Evaluates conditions in order and takes the first matching route, with a default fallback.

1{
2 "age_gate": {
3 "type": "conditional",
4 "routes": [
5 {
6 "conditions": [
7 { "field": "extracted.age", "op": ">=", "value": 21 }
8 ],
9 "target": "screening_step"
10 },
11 {
12 "conditions": [
13 { "field": "extracted.age", "op": ">=", "value": 18 }
14 ],
15 "target": "limited_approve"
16 },
17 {
18 "conditions": [],
19 "target": "reject_underage"
20 }
21 ]
22 }
23}

Supported operators: >=, <=, >, <, ==, !=, in, not_in, contains, exists.

Terminal node

The final outcome. Every path through the graph must reach a terminal.

1{
2 "approve": {
3 "type": "terminal",
4 "outcome": "approved"
5 },
6 "reject": {
7 "type": "terminal",
8 "outcome": "rejected"
9 },
10 "review": {
11 "type": "terminal",
12 "outcome": "needs_review"
13 }
14}

Wait node (external gate)

Pauses the workflow and waits for an external decision via API callback. Useful for integrating with your own decision engine.

1{
2 "external_check": {
3 "type": "wait",
4 "policy": "external_gate",
5 "config": {
6 "timeout_hours": 24,
7 "on_timeout": "review_terminal"
8 }
9 }
10}

When the workflow pauses, the session status changes to awaiting_external and a session.awaiting_external webhook is fired. Your server can then call the resume endpoint with the decision.

Example workflow

A standard KYC workflow that extracts document data, verifies biometrics, screens against watchlists, and auto-approves or routes to review:

1{
2 "entry": "start",
3 "nodes": {
4 "start": {
5 "type": "start",
6 "next": "ocr"
7 },
8 "ocr": {
9 "type": "policy",
10 "policy": "document_ocr",
11 "on_pass": "face_match",
12 "on_fail": "reject"
13 },
14 "face_match": {
15 "type": "policy",
16 "policy": "face_match",
17 "config": { "security_level": "standard" },
18 "on_pass": "age_check",
19 "on_fail": "review"
20 },
21 "age_check": {
22 "type": "policy",
23 "policy": "age_verification",
24 "config": { "min_age": 18 },
25 "on_pass": "screening",
26 "on_fail": "reject"
27 },
28 "screening": {
29 "type": "policy",
30 "policy": "aml_screening",
31 "on_pass": "auto_decision",
32 "on_fail": "review"
33 },
34 "auto_decision": {
35 "type": "policy",
36 "policy": "auto_approve",
37 "on_pass": "approve",
38 "on_fail": "review"
39 },
40 "approve": { "type": "terminal", "outcome": "approved" },
41 "reject": { "type": "terminal", "outcome": "rejected" },
42 "review": { "type": "terminal", "outcome": "needs_review" }
43 }
44}

Data requirements

Workflows can declare which data they need from the capture flow:

1{
2 "data_requirements": {
3 "selfie": true,
4 "back_side": true,
5 "proof_of_address": false
6 }
7}

The capture UI automatically adjusts to collect the required data. If a workflow requires proof of address, the capture flow adds an additional upload step.

Rollout percentage

Deploy workflow changes gradually with percentage-based rollout:

1{
2 "rollout_percentage": 25
3}

25% of new sessions will use this workflow version; the remaining 75% continue using the previous version. The routing is deterministic per session ID, so the same session always gets the same version.

Default workflows

Each organization has one default workflow per environment (sandbox and live). When a session is created without a workflow_id, the default workflow is used.

Workflow API

Create a workflow

$curl -X POST https://api.withverifa.com/api/v1/workflows \
> -H "X-API-Key: vk_live_your_key_here" \
> -H "Content-Type: application/json" \
> -d '{
> "name": "Standard KYC",
> "description": "Document + face match + AML screening",
> "graph": { ... }
> }'

List workflows

$curl https://api.withverifa.com/api/v1/workflows \
> -H "X-API-Key: vk_live_your_key_here"

Publish a workflow

$curl -X POST https://api.withverifa.com/api/v1/workflows/workflow_abc123/publish \
> -H "X-API-Key: vk_live_your_key_here"

Set as default

$curl -X POST https://api.withverifa.com/api/v1/workflows/workflow_abc123/set-default \
> -H "X-API-Key: vk_live_your_key_here"

Validation

The workflow engine validates graphs before publishing:

  • All nodes referenced in routing must exist
  • The entry node must exist and be a start node
  • Policy nodes must have on_pass and on_fail routes
  • Conditional nodes must have at least one route with a default fallback
  • No cycles (the graph must be a DAG)
  • No duplicate policies (unless explicitly allowed)
  • Every path must reach a terminal node

Invalid workflows cannot be published.

Related

  • Verifications & Checks — Available check types for workflow nodes
  • Sessions — How sessions trigger workflow execution
  • Cases — What happens when a workflow routes to needs_review