Speak with an Expert

Workflow API

Initialize verification workflows that combine document verification, selfie checks, fraud detection and AML screening in a single orchestrated flow.

SEON's Workflow API enables you to initialize and manage verification workflows that combine document verification, selfie checks, fraud detection, and AML screening in a single orchestrated flow. Use this endpoint to start a workflow session and receive a token for the frontend SDK.

For more context on how to begin your API integration check the Introduction section or the Integration Guide.

Good to know

  • The workflowId must be a valid UUID of an active workflow created in the Admin Panel (Admin Panel / Workflows).
  • The user_id field is always required in the inputs object to identify the end user.
  • Additional required inputs depend on your workflow configuration (e.g. email if Email check is enabled, phone_number if Phone check is enabled).
  • All SEON API requests are case-sensitive. Please follow the formatting below to avoid errors.
  • IP address is auto-captured from the end user's browser if not provided in the request.
  • Device fingerprinting is handled automatically by the SDK when Device check is enabled.
  • All Fraud API input fields are accepted. The Workflow API supports the complete set of fields from the Fraud API, plus additional orchestration-specific fields (e.g. reference_image, eKYC identifiers). See the Fraud API documentation for the full list of available fields.

Common Workflow Scenarios

Workflow typeRequired inputs
Document + Selfie (basic)user_id
Document + Selfie + Face Match (URL)user_id, reference_image
Document + Selfie + Proof of Address (Evidence Collection)user_id, user_address
Email + Phone fraud checkuser_id, email, phone_number
Full fraud check (Email + Phone + IP)user_id, email, phone_number (IP auto-captured)
AML screeninguser_id, user_fullname
NIN eKYC (Nigeria)user_id, user_firstname, user_lastname, user_dob, nin
BVN eKYC (Nigeria)user_id, user_firstname, user_lastname, user_dob, bvn
CPF eKYC (Brazil)user_id, cpf

Request

POSThttps://api.seon.io/orchestration-api/v1/init-workflow
Header x-api-key: Your SEON API key from Admin Panel / Settings / API Keys.
Regional endpoints: US https://api.us-east-1-main.seon.io/orchestration-api/v1/init-workflow · APAC https://api.ap-southeast-1-main.seon.io/orchestration-api/v1/init-workflow

Request attributes

workflowIdstring (uuid)required

The unique identifier of the workflow to execute. Obtain from Admin Panel / Workflows.

inputsobjectrequired

Workflow input parameters. user_id is always required; other required inputs depend on your workflow configuration.

34 child attributes
user_idstringrequired

Your user's unique identifier in your system. Always required.

emailstring (email)conditional

Full email address. Required if Email check is enabled in your workflow.

phone_numberstringconditional

Phone number with country code (max 19 chars). Required if Phone check is enabled.

max 19 chars
ipstring

User's IP address. Auto-captured from the browser if not provided.

user_fullnamestringconditional

User's full name. Required for AML check or Document verification if set to Sent with session trigger.

user_firstnamestringconditional

User's first name. Required for NIN/BVN eKYC checks.

user_middlenamestring

User's middle name.

user_lastnamestringconditional

User's last name. Required for NIN/BVN eKYC checks.

user_dobstring (date)conditional

Date of birth in YYYY-MM-DD format. Required for NIN/BVN/CURP/SSN eKYC checks.

reference_imagestring (uri)conditional

URL to a reference image for face match. Required if Face match is enabled and set to Sent with session trigger.

ninstringconditional

Nigerian National ID Number (11 digits). Required for NIN eKYC.

bvnstringconditional

Bank Verification Number (11 digits). Required for BVN eKYC.

cpfstringconditional

Brazilian tax identifier (format: 123.456.789-00). Required for CPF eKYC.

curpstringconditional

Mexican population ID (18 characters). Required for CURP eKYC.

ssnstringconditional

US Social Security Number (format: 123-45-6789). Required for SSN eKYC.

aadhaarstringconditional

Indian Aadhaar identifier (12 digits). Required for Aadhaar eKYC.

sessionstring

Device fingerprint. Auto-collected by the SDK.

device_idstring

Third-party device fingerprint ID.

user_pobstring

Place of birth.

user_photoid_numberstring

Photo ID number.

user_countrystring

ISO 3166-1 two-character country code.

user_citystring

City name.

user_regionstring

ISO 3166-2 two-character region code.

user_zipstring

Postal/zip code.

user_streetstring

Street address line 1.

user_street2string

Street address line 2.

user_addressstringconditional

Full address. Required for Address verification if set to Sent with session trigger.

user_genderstring

User gender.

user_creatednumber

User registration date (UNIX timestamp).

transaction_idstring

Unique transaction identifier.

transaction_typestring

Transaction type (e.g. purchase).

transaction_amountnumber

Transaction amount (decimal, e.g. 539.99).

transaction_currencystring

ISO 4217 currency code (e.g. USD).

custom_fieldsobject

Key-value pairs for custom data points.

Code samples

curl -X POST "https://api.seon.io/orchestration-api/v1/init-workflow" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SEON_API_KEY" \
  -d '{
    "workflowId": "550e8400-e29b-41d4-a716-446655440000",
    "inputs": {
      "user_id": "user-12345",
      "email": "john.doe@example.com",
      "phone_number": "+14155551234"
    }
  }'
import os
import requests

response = requests.post(
    "https://api.seon.io/orchestration-api/v1/init-workflow",
    headers={
        "Content-Type": "application/json",
        "x-api-key": os.environ["SEON_API_KEY"],
    },
    json={
        "workflowId": "550e8400-e29b-41d4-a716-446655440000",
        "inputs": {
            "user_id": "user-12345",
            "email": "john.doe@example.com",
            "phone_number": "+14155551234",
        },
    },
)

data = response.json()["data"]
print(data["token"], data["executionId"])
const response = await fetch("https://api.seon.io/orchestration-api/v1/init-workflow", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": process.env.SEON_API_KEY,
  },
  body: JSON.stringify({
    workflowId: "550e8400-e29b-41d4-a716-446655440000",
    inputs: {
      user_id: "user-12345",
      email: "john.doe@example.com",
      phone_number: "+14155551234",
    },
  }),
});

const { data } = await response.json();
console.log(data.token, data.executionId);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class InitWorkflow {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("SEON_API_KEY");

        String payload = """
            {
                "workflowId": "550e8400-e29b-41d4-a716-446655440000",
                "inputs": {
                    "user_id": "user-12345",
                    "email": "john.doe@example.com",
                    "phone_number": "+14155551234"
                }
            }
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.seon.io/orchestration-api/v1/init-workflow"))
            .header("Content-Type", "application/json")
            .header("x-api-key", apiKey)
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}
<?php
$apiKey = getenv('SEON_API_KEY');

$payload = [
    'workflowId' => '550e8400-e29b-41d4-a716-446655440000',
    'inputs' => [
        'user_id' => 'user-12345',
        'email' => 'john.doe@example.com',
        'phone_number' => '+14155551234',
    ],
];

$ch = curl_init('https://api.seon.io/orchestration-api/v1/init-workflow');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        "x-api-key: {$apiKey}",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true)['data'];
echo $data['token'] . "\n";
echo $data['executionId'] . "\n";

Response

The endpoint returns a JSON structured response.

dataobjectrequired
2 child attributes
executionIdstring (uuid)required

Unique identifier for this workflow execution. Use for debugging and correlation.

tokenstringrequired

JWT token to pass to the frontend SDK to start the verification flow.

{
  "data": {
    "executionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Error Responses

Both endpoints on this page return the same error responses.

HTTP statusError codeDescription
400MISSING_REQUIRED_INPUTS

Required workflow inputs not provided (e.g. missing user_id or workflow-specific fields).

INVALID_INPUT_FORMAT

An input field is malformed (e.g. invalid email format).

401UNAUTHORIZED

Invalid or missing API key.

403FORBIDDEN

API key doesn't have access to this workflow.

404WORKFLOW_NOT_FOUND

Workflow ID doesn't exist or the workflow is inactive.

429RATE_LIMITED

Too many requests. Implement exponential backoff.

500INTERNAL_ERROR

Internal server error. Contact SEON support with your workflowId.

The workflow-link endpoint provides an alternative to the standard Workflow API, allowing you to initiate workflow executions by generating shareable verification links instead of integrating with the SDK. This approach is ideal when you want to send verification URLs directly to end users via email, SMS, or other channels without the need of a frontend SDK integration.

  • This endpoint returns error responses identical to the Workflow API, and shares its request schema with three additional optional attributes specific to workflow links — expiresIn, completedUrl and incompleteUrl.
  • Webhook notifications and callbacks work in the same way as with the standard Workflow API endpoint.
  • The returned redirectUrl can be shared directly with end users — no frontend SDK integration required.
  • Workflow links are valid for 7 days by default. If the user does not complete the verification within this period, the execution status becomes EXPIRED.
  • Each API call creates a new workflow execution. To send verification links to multiple users, make separate API calls for each user.
  • You can return users to your own application when the flow ends by supplying completedUrl and incompleteUrl — see Redirecting users back to your application.
POSThttps://api.seon.io/orchestration-api/v1/workflow-link
Header x-api-key: Your SEON API key from Admin Panel / Settings / API Keys.
Regional endpoints: US https://api.us-east-1-main.seon.io/orchestration-api/v1/workflow-link · APAC https://api.ap-southeast-1-main.seon.io/orchestration-api/v1/workflow-link

The headers and all input fields are identical to the Workflow API. Workflow links additionally accept expiresIn, completedUrl and incompleteUrl:

workflowIdstring (uuid)required

The unique identifier of the workflow to execute. Obtain from Admin Panel / Workflows.

inputsobjectrequired

Workflow input parameters. user_id is always required; other required inputs depend on your workflow configuration.

34 child attributes
user_idstringrequired

Your user's unique identifier in your system. Always required.

emailstring (email)conditional

Full email address. Required if Email check is enabled in your workflow.

phone_numberstringconditional

Phone number with country code (max 19 chars). Required if Phone check is enabled.

max 19 chars
ipstring

User's IP address. Auto-captured from the browser if not provided.

user_fullnamestringconditional

User's full name. Required for AML check or Document verification if set to Sent with session trigger.

user_firstnamestringconditional

User's first name. Required for NIN/BVN eKYC checks.

user_middlenamestring

User's middle name.

user_lastnamestringconditional

User's last name. Required for NIN/BVN eKYC checks.

user_dobstring (date)conditional

Date of birth in YYYY-MM-DD format. Required for NIN/BVN/CURP/SSN eKYC checks.

reference_imagestring (uri)conditional

URL to a reference image for face match. Required if Face match is enabled and set to Sent with session trigger.

ninstringconditional

Nigerian National ID Number (11 digits). Required for NIN eKYC.

bvnstringconditional

Bank Verification Number (11 digits). Required for BVN eKYC.

cpfstringconditional

Brazilian tax identifier (format: 123.456.789-00). Required for CPF eKYC.

curpstringconditional

Mexican population ID (18 characters). Required for CURP eKYC.

ssnstringconditional

US Social Security Number (format: 123-45-6789). Required for SSN eKYC.

aadhaarstringconditional

Indian Aadhaar identifier (12 digits). Required for Aadhaar eKYC.

sessionstring

Device fingerprint. Auto-collected by the SDK.

device_idstring

Third-party device fingerprint ID.

user_pobstring

Place of birth.

user_photoid_numberstring

Photo ID number.

user_countrystring

ISO 3166-1 two-character country code.

user_citystring

City name.

user_regionstring

ISO 3166-2 two-character region code.

user_zipstring

Postal/zip code.

user_streetstring

Street address line 1.

user_street2string

Street address line 2.

user_addressstringconditional

Full address. Required for Address verification if set to Sent with session trigger.

user_genderstring

User gender.

user_creatednumber

User registration date (UNIX timestamp).

transaction_idstring

Unique transaction identifier.

transaction_typestring

Transaction type (e.g. purchase).

transaction_amountnumber

Transaction amount (decimal, e.g. 539.99).

transaction_currencystring

ISO 4217 currency code (e.g. USD).

custom_fieldsobject

Key-value pairs for custom data points.

expiresIninteger

Link lifetime in seconds. Minimum 3600 (1 hour), maximum 2592000 (30 days). Overrides the default 7-day expiration for this link only.

min 3600, max 2592000
completedUrlstring (uri)

Absolute URL the user is redirected to once the verification journey reaches a finished result.

incompleteUrlstring (uri)

Absolute URL the user is redirected to when the journey ends without reaching a finished result.

Your request should look like the following when using redirect URLs:

{
  "workflowId": "3f8c1e42-9b7a-4c25-8d61-0a2f5e7b9c14",
  "inputs": {
    "user_id": "user-12345",
    "email": "user@example.com"
  },
  "expiresIn": 172800,
  "completedUrl": "https://app.example.com/verification/complete",
  "incompleteUrl": "https://app.example.com/verification/incomplete"
}
curl -X POST "https://api.seon.io/orchestration-api/v1/workflow-link" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $SEON_API_KEY" \
  -d '{
    "workflowId": "3f8c1e42-9b7a-4c25-8d61-0a2f5e7b9c14",
    "inputs": {
      "user_id": "user-12345",
      "email": "user@example.com"
    },
    "expiresIn": 172800,
    "completedUrl": "https://app.example.com/verification/complete",
    "incompleteUrl": "https://app.example.com/verification/incomplete"
  }'
import os
import requests

response = requests.post(
    "https://api.seon.io/orchestration-api/v1/workflow-link",
    headers={
        "Content-Type": "application/json",
        "x-api-key": os.environ["SEON_API_KEY"],
    },
    json={
        "workflowId": "3f8c1e42-9b7a-4c25-8d61-0a2f5e7b9c14",
        "inputs": {"user_id": "user-12345", "email": "user@example.com"},
        "expiresIn": 172800,
        "completedUrl": "https://app.example.com/verification/complete",
        "incompleteUrl": "https://app.example.com/verification/incomplete",
    },
)

data = response.json()["data"]
print(data["redirectUrl"], data["executionId"])
const response = await fetch("https://api.seon.io/orchestration-api/v1/workflow-link", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": process.env.SEON_API_KEY,
  },
  body: JSON.stringify({
    workflowId: "3f8c1e42-9b7a-4c25-8d61-0a2f5e7b9c14",
    inputs: { user_id: "user-12345", email: "user@example.com" },
    expiresIn: 172800,
    completedUrl: "https://app.example.com/verification/complete",
    incompleteUrl: "https://app.example.com/verification/incomplete",
  }),
});

const { data } = await response.json();
console.log(data.redirectUrl, data.executionId);
<?php
$apiKey = getenv('SEON_API_KEY');

$payload = [
    'workflowId' => '3f8c1e42-9b7a-4c25-8d61-0a2f5e7b9c14',
    'inputs' => ['user_id' => 'user-12345', 'email' => 'user@example.com'],
    'expiresIn' => 172800,
    'completedUrl' => 'https://app.example.com/verification/complete',
    'incompleteUrl' => 'https://app.example.com/verification/incomplete',
];

$ch = curl_init('https://api.seon.io/orchestration-api/v1/workflow-link');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        "x-api-key: {$apiKey}",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true)['data'];
echo $data['redirectUrl'] . "\n";
dataobjectrequired
2 child attributes
executionIdstring (uuid)required

Unique identifier for this workflow execution.

redirectUrlstring (uri)required

URL to redirect the end user to for completing the flow.

{
  "data": {
    "executionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "redirectUrl": "https://transfer.seonidv.com/?t=euw1:1e1f66b0-cc43-429d-ba69-096daca813fd"
  }
}

Use cases

The Workflow Link endpoint is ideal for scenarios where you want to send verification links directly to end users without requiring frontend SDK integration:

Use caseDescription
Email verification linksSend verification URLs via email campaigns or transactional emails.
SMS verification linksSend short verification URLs via SMS to mobile users.
Customer support workflowsGenerate links for support agents to send to customers for manual verification.
Asynchronous verificationAllow users to complete verification at their convenience without real-time session management.

Comparison with the init-workflow endpoint

FeatureInit Workflow (/v1/init-workflow)Workflow Link (/v1/workflow-link)
Responsetoken (for SDK)redirectUrl (shareable link)
SDK integrationRequiredNot required
Default expiration1 hour7 days
Return to your applicationHandled by your frontend via SDK eventscompletedUrl / incompleteUrl
Best forReal-time in-app verificationAsynchronous/off-platform verification

SEON hosted verification flow

When using the Workflow Link endpoint, the redirectUrl directs end users to a SEON-hosted Orchestration SDK frontend. This means:

  • No SDK integration required: you don't need to embed or configure the SEON SDK in your application.
  • Fully managed user experience: SEON hosts and maintains the verification UI, ensuring it's always up-to-date with the latest features and security updates.
  • Cross-platform compatibility: the hosted verification flow works on any desktop, mobile or tablet device with a modern web browser.

This approach is ideal when you want to offload the verification experience entirely to SEON, rather than embedding the SDK directly into your own web or mobile application.

Redirecting users back to your application

By default, users remain on the SEON-hosted result screen when the verification journey ends. If you supply redirect URLs when creating the link, users are returned to your application automatically instead.

AttributeWhen the user is redirectedTiming
completedUrlThe journey reaches a finished result.Once the verification journey reaches a finished result.
incompleteUrlThe journey ends without reaching a finished result: an error during the flow, expiry of the session or link, or the user choosing to quit.Immediately.

Both attributes are optional and independent — you can supply either, both, or neither. Each must be a valid absolute URL, and we recommend HTTPS.

Orchestration SDK

You can integrate SEON's Orchestration module directly into a web app by using our JavaScript SDK. Please use our npm-hosted package to ensure you always load the latest available version. Visit the SEON Orchestration SDK npm page to see the latest version and its changelog.

  1. Install the SDK via npm or yarn and import it into your application.
  2. Initialize a workflow from your backend using the Workflow API described above to get a token.
  3. Call SeonOrchestration.start(config) with the token to launch the verification flow.
  4. Listen to events (completed, error, cancelled) to handle the verification result.
  5. Use webhooks or the Admin Panel to access detailed verification results and captured media.

Installation

npm install @seontechnologies/seon-orchestration
# or
yarn add @seontechnologies/seon-orchestration
import { SeonOrchestration } from '@seontechnologies/seon-orchestration';

Prerequisites

  • Node.js >= 20.0.0, npm >= 7.0.0
  • SEON account with workflow access
  • API key (obtain from Admin Panel / Settings / API Keys)
  • At least one workflow created (Admin Panel / Workflows)

Browser compatibility

BrowserMin version
Chrome96
Safari15
Firefox79
Opera82
iOS Safari15
Android Browser81
Chrome for Android96
Firefox for Android79
Internet ExplorerNot supported

Configuration parameters

To configure the Orchestration SDK, create a config object and pass it to SeonOrchestration.start(config).

tokenstringrequired

JWT token obtained from your backend via the Workflow API.

languagestring

UI language: en English, de German, es Spanish, fr French, it Italian, pt Portuguese, hu Hungarian, ar Arabic (UAE), zh Chinese. If not specified or unsupported, the SDK falls back to English.

One of en, de, es, fr, it, pt, hu, ar, zh · Default en
themeobject

Custom theming configuration. Accessibility: ensure colour contrast meets WCAG 2.1 AA (4.5:1 for normal text).

5 child attributes
lightobject

Colour scheme for one mode (light or dark).

5 child attributes
baseTextOnLightstring

Text colour on light backgrounds. Min 4.5:1 ratio.

baseTextOnDarkstring

Text colour on dark backgrounds. Min 4.5:1 ratio.

baseAccentstring

Primary accent/brand colour.

baseOnAccentstring

Text colour on accent backgrounds. Min 4.5:1 against baseAccent.

logoUrlstring (uri)

URL to a custom logo image (SVG preferred; PNG/JPEG supported).

darkobject

Colour scheme for one mode (light or dark).

5 child attributes
baseTextOnLightstring

Text colour on light backgrounds. Min 4.5:1 ratio.

baseTextOnDarkstring

Text colour on dark backgrounds. Min 4.5:1 ratio.

baseAccentstring

Primary accent/brand colour.

baseOnAccentstring

Text colour on accent backgrounds. Min 4.5:1 against baseAccent.

logoUrlstring (uri)

URL to a custom logo image (SVG preferred; PNG/JPEG supported).

fontFamilystring

Custom font family name (e.g. Inter).

fontUrlstring (uri)

URL to load the custom font from (Google Fonts URLs only, WOFF2 recommended).

fontWeightstring

Font weight (e.g. 400, 500, 600).

renderingModestring

How the SDK renders. fullscreen takes over the entire viewport — best for mobile web and single-purpose flows. popup opens a new browser window — desktop apps where the main UI should stay visible. inline renders inside a container element — embedded within your existing page layout.

One of fullscreen, inline, popup · Default fullscreen
containerIdstringconditional

DOM element ID for the SDK container. Required when renderingMode is inline.

Core methods

MethodDescription
SeonOrchestration.start(config)Start the verification flow with the provided configuration
SeonOrchestration.close()Close the current verification flow and clean up the UI
SeonOrchestration.on(event, handler)Subscribe to SDK events
SeonOrchestration.off(event, handler)Unsubscribe from SDK events

Events

EventCallback signatureDescription
opened() => voidFlow UI opened
closed() => voidFlow UI closed
started() => voidVerification started
completed(status: CompletionTypes) => voidVerification completed
cancelled() => voidUser cancelled
error(errorCode: ErrorCodes) => voidError occurred

Completion types: success, pending, failed, unknown

Error codes

Error codes received via the error event:

CodeDescription
error_code_1Device not supported — no capable camera/device found, or general error screen dismissed
error_code_3Authentication failed — unauthorized request (invalid/expired token)
error_code_4Document capture SDK error — failed to initialize document scanning
error_code_5Document capture retry limit exceeded — user exceeded max retries for document scanning
error_code_6Liveness check retry limit exceeded — user exceeded max retries for liveness detection
unknownUnhandled error — unexpected error or unhandled promise rejection

SDK exceptions

Exceptions thrown by SeonOrchestration.start() (catch via try/catch):

Error messageCause
IDV flow is already running.Calling start() when a flow is already active
Configuration is not set.Calling start() without passing config
Failed to initialize client: {status} {statusText}Backend init failed (e.g. invalid/expired token)
Invalid response from client init.Invalid account configuration
Container ID is required for inline rendering.Using renderingMode: 'inline' without containerId
Container element with id '{id}' not found.Container DOM element doesn't exist
Failed to open popup window. Please allow popups and try again.Browser blocked the popup window
Invalid rendering mode specified.Invalid renderingMode value

Example: minimal integration

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

// 1. Get token from YOUR backend (keeps API keys secure)
const { token } = await fetch('/api/init-verification', { method: 'POST' })
  .then(r => r.json());

// 2. Start verification
await SeonOrchestration.start({ token, language: 'en' });

Example: full configuration

// On page load: set up event listeners
SeonOrchestration.on('completed', (status) => {
  console.log('Verification completed:', status);
});
SeonOrchestration.on('error', (errorCode) => {
  console.error('Verification error:', errorCode);
});

const config = {
  token: 'eyJhbGciOiJIUzI1NiIs...', // from your backend
  language: 'en',
  renderingMode: 'fullscreen',
  theme: {
    light: {
      baseTextOnLight: '#1a1a1a',
      baseTextOnDark: '#ffffff',
      baseAccent: '#0066cc',
      baseOnAccent: '#ffffff',
      logoUrl: 'https://example.com/logo-dark.svg'
    },
    dark: {
      baseTextOnLight: '#e5e5e5',
      baseTextOnDark: '#1a1a1a',
      baseAccent: '#4d9fff',
      baseOnAccent: '#000000',
      logoUrl: 'https://example.com/logo-light.svg'
    },
    fontFamily: 'Inter',
    fontUrl: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap',
    fontWeight: '500'
  }
};

await SeonOrchestration.start(config);

Example: inline rendering

<!-- In your HTML -->
<div id="verification-container" style="width: 100%; min-height: 600px;"></div>
await SeonOrchestration.start({
  token,
  renderingMode: 'inline',
  containerId: 'verification-container'
});
RequirementDetails
Container elementMust exist in the DOM before start() is called
Minimum size400×600 px recommended for usability
ResponsiveContainer should be responsive; the SDK adapts to the available space

Example: React integration

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

export function VerificationComponent({ userId, onComplete, onError }) {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const handleCompleted = (status: CompletionTypes) => {
      onComplete(status);
    };
    const handleError = (errorCode: ErrorCodes) => {
      setError(`Error: ${errorCode}`);
      onError(errorCode);
    };
    const handleClosed = () => setIsLoading(false);

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

  const startVerification = async () => {
    setIsLoading(true);
    setError(null);
    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 (err) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div>
      {error && <div style={{ color: 'red' }}>{error}</div>}
      <button onClick={startVerification} disabled={isLoading}>
        {isLoading ? 'Starting...' : 'Start Verification'}
      </button>
    </div>
  );
}