Custom Flows

Build sophisticated verification experiences with FaceSign's node-based flow system. Create conditional verification paths, implement complex business logic, and design user experiences that adapt to different scenarios.

Overview

While the verification modules provide a simple way to configure common verification patterns, custom flows give you complete control over the verification process. Flows are built using a node-graph system where:

  • Nodes define verification steps and actions
  • Edges define the connections between nodes
  • Outcomes determine which path to take based on results

Flow Structure

A flow consists of two main components:

Nodes Array

Each node represents a step in your verification process. Nodes have specific types and configurations that determine what happens at that step.

Edges Array

Edges connect nodes together, defining the possible paths through your flow based on outcomes and conditions.

Available Node Types

FaceSign supports 11 different node types for building flows:

START

Entry point for the flow

END

Exit point for the flow

CONVERSATION

AI-powered conversational interactions

LIVENESS_DETECTION

Detect if user is real person

ENTER_EMAIL

Collect email address from user

DATA_VALIDATION

Validate and process data

DOCUMENT_SCAN

Scan and extract document data

RECOGNITION

Facial recognition against database

FACE_SCAN

Capture and analyze face images

TWO_FACTOR

Two-factor authentication via SMS/email

Basic Flow Example

Here's a simple flow that performs liveness detection followed by document scanning:

Basic Identity Verification Flow

A simple flow that checks for a live person, then scans their document

start
Start
liveness detection
Liveness Check
live person detected
document scan
Document Scan
document verified
end
Complete
Hover over nodes for more details

The corresponding JSON structure for this flow:

Basic Flow Structure

{
  "nodes": [
    { "id": "start", "type": "start" },
    { 
      "id": "liveness", 
      "type": "liveness_detection",
      "outcomes": {
        "livenessDetected": "document",
        "deepfakeDetected": "end",
        "noFace": "end"
      }
    },
    {
      "id": "document",
      "type": "document_scan",
      "scanningMode": "SINGLE_SIDE",
      "allowedDocumentTypes": ["MRTD_TYPE_PASSPORT"],
      "outcomes": {
        "scanSuccess": "end",
        "userCancelled": "end",
        "scanTimeout": "end"
      }
    },
    { "id": "end", "type": "end" }
  ],
  "edges": [
    { "id": "e1", "source": "start", "target": "liveness" },
    { "id": "e2", "source": "liveness", "target": "document" },
    { "id": "e3", "source": "liveness", "target": "end" },
    { "id": "e4", "source": "document", "target": "end" }
  ]
}

Using Custom Flows

Include your custom flow in the session creation request:

const session = await client.sessions.create({
  clientReferenceId: 'user-123',
  metadata: { userId: '123' },
  flow: myCustomFlow,
  // Don't include modules when using custom flows
})

Best Practices

  • Always start with a START node and end with an END node
  • Ensure all possible outcome paths are connected
  • Test flows thoroughly with different scenarios
  • Use meaningful node IDs for easier debugging
  • Consider user experience when designing conditional paths