Orchestration

This guide walks you through integrating the SEON Orchestration SDK into your application. You'll learn how to set up backend-to-SEON communication, initialize verification flows, launch the frontend SDK, and handle results via webhooks.


Table of Contents

  1. Overview
  2. Prerequisites
  3. Integration Flow
  4. Step 1: Backend Integration
  5. Step 2: Frontend Integration
  6. Step 3: Webhook Integration
  7. Testing Your Integration
  8. Going to Production
  9. Next Steps

1. Overview

The SEON Orchestration SDK enables you to integrate identity verification workflows into your web application. Workflows can combine document verification, selfie checks, liveness detection, fraud screening, AML checks, and eKYC validation in a single orchestrated flow.

 

How It Works

The integration follows a secure three-party flow:

  1. Your Frontend: Requests verification from your backend
  2. Your Backend: Securely calls SEON's Workflow API to get a session token
  3. SEON SDK: Handles the user-facing verification process
  4. SEON Webhooks: Delivers final results to your backend

2. Prerequisites

Before you begin, ensure you have:

 

SEON Account Setup

  • A SEON account with Workflows access
  • An API key from Admin Panel / Settings / API Keys
  • At least one workflow created in Admin Panel / Workflows

 

Development Environment

  • Node.js >=20.0.0 and npm >=7.0.0 (for frontend SDK)
  • A backend server (Node.js, Python, Java, etc.)
  • HTTPS endpoint for webhooks (required for production)

 

Browser Requirements

BrowserMinimum Version
Chrome96
Safari15
Firefox79
Opera82
iOS Safari15
Android Browser81
Chrome for Android96
Firefox for Android79

3. Integration Flow

Here's the complete integration sequence:

  1. User clicks "Verify" button in your app
  2. Frontend calls your backend API (e.g., POST {your_backend_url}/init-verification)
  3. Backend calls SEON's POST /v1/init-workflow with:
    1. Your API key (header)
    2. Workflow ID
    3. User inputs (user_id, email, phone, etc.)
  4. 4. SEON returns { executionId, token }
    1. Store executionId for correlation
    2. Return token to frontend
  5. Frontend initializes SDK with token
  6. SDK guides user through verification steps (document capture, selfie, liveness, etc.)
  7. SDK fires completion events (success/pending/failed)
    1. Update UI accordingly
  8. SEON sends webhook to your backend with final results
    1. Update user status in your database

4. Step 1: Backend Integration

Your backend acts as a secure bridge between your frontend and SEON's API. It:

  • Keeps your API key secret
  • Initializes workflow sessions
  • Stores execution IDs for result correlation
  • Receives webhook notifications

 

4.1 Environment Setup

Set these environment variables:

SEON_API_KEY=your_api_key_here
SEON_BASE_URL=https://orchestration.seondev.space  # Development
WORKFLOW_ID=your_workflow_uuid
SEON_WEBHOOK_SECRET=your_webhook_secret  # For signature verification

 

4.2 Create an Init Endpoint

Create an endpoint that your frontend will call to start verification:

Node.js (Express)

const express = require('express');
const app = express();
app.use(express.json());

const SEON_API_KEY = process.env.SEON_API_KEY;
const SEON_BASE_URL = process.env.SEON_BASE_URL;
const WORKFLOW_ID = process.env.WORKFLOW_ID;

app.post('/api/init-verification', async (req, res) => {
  const { userId, email, phoneNumber } = req.body;

  try {
    const response = await fetch(`${SEON_BASE_URL}/v1/init-workflow`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': SEON_API_KEY,
      },
      body: JSON.stringify({
        workflowId: WORKFLOW_ID,
        inputs: {
          user_id: userId,
          email: email,
          phone_number: phoneNumber,
        },
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      return res.status(response.status).json({ error: error.message });
    }

    const { data } = await response.json();
    
    // Store executionId for webhook correlation
    await storeExecutionId(userId, data.executionId);
    
    // Return only the token to frontend
    res.json({ token: data.token });
  } catch (error) {
    console.error('Failed to initialize workflow:', error);
    res.status(500).json({ error: 'Failed to initialize verification' });
  }
});

Python (Flask)

import os
import requests
from flask import Flask, request, jsonify

app = Flask(__name__)

SEON_API_KEY = os.environ.get('SEON_API_KEY')
SEON_BASE_URL = os.environ.get('SEON_BASE_URL')
WORKFLOW_ID = os.environ.get('WORKFLOW_ID')

@app.route('/api/init-verification', methods=['POST'])
def init_verification():
    data = request.get_json()
    
    response = requests.post(
        f'{SEON_BASE_URL}/v1/init-workflow',
        headers={
            'Content-Type': 'application/json',
            'x-api-key': SEON_API_KEY,
        },
        json={
            'workflowId': WORKFLOW_ID,
            'inputs': {
                'user_id': data.get('userId'),
                'email': data.get('email'),
                'phone_number': data.get('phoneNumber'),
            },
        },
    )

    if not response.ok:
        return jsonify({'error': response.json().get('message')}), response.status_code

    result = response.json()['data']
    
    # Store executionId for webhook correlation
    store_execution_id(data.get('userId'), result['executionId'])
    
    return jsonify({'token': result['token']})

 

4.3 Required Inputs

The inputs required depend on your workflow configuration:

Workflow TypeRequired Inputs
Document + Selfie (basic)user_id
Email + Phone fraud checkuser_id, email, phone_number
AML screeninguser_id, user_fullname
Face match with referenceuser_id, reference_image

 

4.4 Error Handling

Handle these common API errors:

HTTP StatusError CodeSolution
400MISSING_REQUIRED_INPUTSCheck your workflow config for required fields
401UNAUTHORIZEDVerify your API key is correct
404WORKFLOW_NOT_FOUNDCheck workflow ID exists and is active
429RATE_LIMITEDImplement exponential backoff

5. Step 2: Frontend Integration

Once your backend returns a token, use the Orchestration SDK to launch the verification flow.

 

5.1 Install the SDK

npm install @seontechnologies/seon-orchestration
# or
yarn add @seontechnologies/seon-orchestration

 

5.2 Basic Implementation

Minimal Example

import { SeonOrchestration } from '@seontechnologies/seon-orchestration';

async function startVerification(userId) {
  // 1. Get token from your backend
  const response = await fetch('/api/init-verification', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userId }),
  });
  const { token } = await response.json();

  // 2. Start the verification flow
  await SeonOrchestration.start({ token });
}

With Event Handling

import { SeonOrchestration } from '@seontechnologies/seon-orchestration';

// Set up event listeners (do this once on page load)
SeonOrchestration.on('completed', (status) => {
  // status: 'success' | 'pending' | 'failed' | 'unknown'
  console.log('Verification completed:', status);
  
  if (status === 'success') {
    showSuccessMessage();
  } else if (status === 'pending') {
    showPendingMessage();
  } else {
    showFailureMessage();
  }
});

SeonOrchestration.on('error', (errorCode) => {
  console.error('Verification error:', errorCode);
  showErrorMessage(errorCode);
});

SeonOrchestration.on('cancelled', () => {
  console.log('User cancelled verification');
});

// Start verification function
async function startVerification(userId) {
  try {
    const response = await fetch('/api/init-verification', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ userId }),
    });
    
    if (!response.ok) {
      throw new Error('Failed to initialize verification');
    }
    
    const { token } = await response.json();
    
    await SeonOrchestration.start({
      token,
      language: 'en',
      renderingMode: 'fullscreen',
    });
  } catch (error) {
    console.error('Failed to start:', error);
  }
}

 

5.3 React Integration

import { useEffect, useState } from 'react';
import { SeonOrchestration, CompletionTypes, ErrorCodes } from '@seontechnologies/seon-orchestration';

export function VerificationButton({ userId, onComplete, onError }) {
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const handleCompleted = (status: CompletionTypes) => {
      setIsLoading(false);
      onComplete(status);
    };

    const handleError = (errorCode: ErrorCodes) => {
      setIsLoading(false);
      onError(errorCode);
    };

    SeonOrchestration.on('completed', handleCompleted);
    SeonOrchestration.on('error', handleError);
    SeonOrchestration.on('closed', () => setIsLoading(false));

    return () => {
      SeonOrchestration.off('completed', handleCompleted);
      SeonOrchestration.off('error', handleError);
      SeonOrchestration.off('closed', () => setIsLoading(false));
    };
  }, [onComplete, onError]);

  const startVerification = async () => {
    setIsLoading(true);
    
    try {
      const response = await fetch('/api/init-verification', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId }),
      });
      const { token } = await response.json();
      
      await SeonOrchestration.start({ token, language: 'en' });
    } catch (error) {
      onError('init_failed');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <button onClick={startVerification} disabled={isLoading}>
      {isLoading ? 'Starting...' : 'Verify Identity'}
    </button>
  );
}

 

5.4 Configuration Options

OptionTypeDefaultDescription
tokenstringrequiredSession token from your backend
languagestringenUI language code
renderingModestringfullscreenfullscreen, inline, or popup
containerIdstringDOM element ID (required for inline mode)
themeobjectCustom branding configuration

 

5.5 Rendering Modes

Fullscreen (Default) — Best for mobile and single-purpose flows

await SeonOrchestration.start({
  token,
  renderingMode: 'fullscreen'
});

Popup — Opens in a new window, keeps main UI visible

await SeonOrchestration.start({
  token,
  renderingMode: 'popup'
});

Inline — Embeds within your page layout

<div id="verification-container" style="min-height: 600px;"></div>
await SeonOrchestration.start({
  token,
  renderingMode: 'inline',
  containerId: 'verification-container'
});

 

5.6 SDK Events

EventCallbackDescription
opened() => voidSDK UI opened
started() => voidVerification process started
completed(status) => voidVerification finished (success, pending, failed, unknown)
cancelled() => voidUser cancelled
error(errorCode) => voidError occurred
closed() => voidSDK UI closed

6. Step 3: Webhook Integration

While SDK events provide immediate feedback, webhooks deliver the authoritative final result. Always use webhooks to update your database.

 

6.1 Workflow & IDV Webhook Events

Subscribe to these events in Admin Panel / Settings / Webhooks:

EventDescription
orchestration/workflow_execution_finishedWorkflow execution completed (any terminal status)
orchestration/workflow_execution_updatedWorkflow status manually changed by admin
idv/session_finishedIDV session completed with detailed check results

 

6.2 Workflow Execution Payload

{
  "event": "orchestration/workflow_execution_finished",
  "timestamp": "2025-01-12T14:30:00Z",
  "data": {
    "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
    "workflow": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "KYC Onboarding Flow"
    },
    "status": "APPROVED"
  }
}

Workflow Status Values

StatusDescription
APPROVEDUser passed all checks
REVIEWRequires manual review
DECLINEDUser failed verification
EXPIREDSession timed out
ERRORSystem error occurred

 

6.3 IDV Session Payload

The idv/session_finished event includes detailed check results:

{
  "event": "idv/session_finished",
  "timestamp": "2025-01-12T14:30:00Z",
  "data": {
    "status": "APPROVED",
    "sessionId": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
    "executionId": "f0e9d8c7-b6a5-4321-fedc-ba9876543210",
    "userId": "user-98765",
    "documentCheckResult": {
      "overallResult": "APPROVED",
      "documentValidityCheckResult": "PASSED",
      "imageQualityCheckResult": "PASSED"
    },
    "documentCheckExtractedData": {
      "fullName": "Jane Doe",
      "birthDate": "1990-05-15",
      "documentType": "PASSPORT",
      "country": "US"
    },
    "selfieVerificationResult": {
      "overallResult": "APPROVED",
      "livenessCheckResult": "PASSED",
      "faceMatchingResult": "PASSED"
    }
  }
}

7. Testing Your Integration

 

7.1 Development Checklist

  • Backend endpoint returns token successfully
  • Frontend SDK launches without errors
  • SDK events fire correctly (opened, started, completed, closed)
  • Webhook endpoint receives and verifies payloads
  • Database updates correctly based on webhook status

 

7.2 Debugging Tips

Store execution IDs for correlation:

const { executionId, token } = data;
console.log(`Started verification: execution ${executionId}`);
// Store executionId alongside userId in your database

Log all SDK events during development:

['opened', 'closed', 'started', 'completed', 'cancelled', 'error'].forEach(event => {
  SeonOrchestration.on(event, (...args) => {
    console.log(`[SEON] ${event}:`, ...args);
  });
});

Review in Admin Panel:

  1. Go to Transactions / Workflow Runs
  2. Search by user_id or executionId
  3. View step-by-step execution details

 

7.3 Common Issues

IssueCauseSolution
"IDV flow is already running"Called start() twiceWait for flow to complete or call close() first
401 on init-workflowInvalid API keyCheck x-api-key header
Webhook not receivedEndpoint not HTTPSUse HTTPS in production
Duplicate webhooksNormal behaviorImplement idempotency handling

 


 

8. Going to Production

 

8.1 Pre-Launch Checklist

  • Switch to production API URL (contact SEON for access)
  • Update API keys to production keys
  • Configure production webhook URL (HTTPS required)
  • Test complete flow end-to-end
  • Set up monitoring and alerting
  • Implement proper error handling and logging

 

8.2 Security Checklist

  • API key stored in environment variables (never in code)
  • Webhook signature verification enabled
  • HTTPS used for all endpoints
  • Rate limiting implemented on your endpoints
  • Input validation on all user-provided data

 


 

9. Next Steps

 

Documentation Links

 

Additional Topics

 

For Additional support, contact your SEON representative.