npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@datachecker/faceverify

v8.2.3

Published

This project contains Datachecker's FaceVerify tool, that captures images of faces to be used in liveness detection. The tool only takes a capture once the trigger mechanism is fired.

Readme

FaceVerify

📢 Upgrading from older versions? See the Migration Guides for breaking changes.

This project contains Datachecker's FaceVerify tool, that captures images of faces to be used in liveness detection. The tool only takes a capture once the trigger mechanism is fired.

To perform liveness detection, two slightly different images of the same person are required. For example, when a person moves his/her head slightly this will generate a different image. Therefore, the tool checks difference in movement between frames.

The tool features user challenge-response, namely head pose estimation, in order to prevent video injection attacks.

The tool will be run in the browser and is therefore written in JavaScript.

Trigger mechanism

The tool performs the following checks:

  • Is the environment not too dark (under exposure)?
  • Is there a face?
  • Is the face occluded?
  • Is the detected face not too far?
  • Is the detected face not too close?
  • Is the face centered?
  • Is the user holding still?

Holding still is required for every picture, including the first. The separate check that two pictures differ enough from each other applies only to the second picture of a challenge pair, since the first has nothing to compare against.

Prerequisites

Please visit Datachecker API documentation.

Compatibility

The SDK requires a browser that supports at least ECMAScript 12 (ES12). It is highly recommended to use the latest version of your preferred browser to ensure compatibility and access to the latest features and security updates.

Using the latest browser versions will ensure that all modern JavaScript features required by the SDK are supported.

Minimum requirements

The SDK runs its image processing and face detection in WebAssembly, and the bundled OpenCV build requires WebAssembly SIMD. There is no fallback for a device that lacks either: the SDK refuses to start rather than degrading.

| Requirement | Minimum version | | ----------------- | ------------------------------------------------------ | | iOS / iPadOS | 16.4 (all iOS browsers use WebKit, so this applies regardless of browser) | | Safari on macOS | 16.4 | | Chrome / Edge | 91 | | Firefox | 89 | | Android | Chrome 91 + / Samsung Internet 16 + (the browser version matters, not the Android version) |

Devices below these versions are refused with a device_error before the camera opens. See Unsupported devices.

iOS and Android fail differently, and the message you show should differ too.

  • On iOS, the browser is the operating system. Every iOS browser uses WebKit, so WebAssembly SIMD arrives with iOS 16.4 and cannot be obtained any sooner. Installing a different browser changes nothing. For hardware that cannot go past iOS 15 (iPhone 7 and older, still receiving 15.8.x security updates) this is permanent: no update will ever make the SDK work. "Update iOS, or use a different device" is the only honest message.
  • On Android, the browser updates independently of the operating system. Chrome and the Android System WebView update through the Play Store, so a phone on an old Android release usually still runs a current browser with SIMD. A 2016 handset that keeps receiving Chrome updates works fine. When Android does fail it is normally the browser that is stale, not the OS: most often on devices without Play Store access (some Huawei models, AOSP or regional builds), or an in-app browser sitting on an outdated System WebView. Here "update your browser, or open the link in Chrome" is usually actionable.
  • WebAssembly can be switched off on an otherwise-current device. iOS Lockdown Mode disables it, as do some managed-browser policies. These report 7002 rather than 7003, so you can tell them apart from old hardware. Unlike old hardware, the user can often fix it.

Supported browsers and devices

The SDK runs the face landmark model in a Web Worker (preferred) and falls back to the main thread when the worker path is unavailable. The decision is made at runtime by a WebGL2 capability probe, so support is decided by what the device can actually do — not by parsing the User-Agent.

| Platform | Full support (worker, ~30 FPS) | Degraded mode (main thread, throttled) | Refused | | ------------------------------------------------------- | ------------------------------ | -------------------------------------- | ------------------------------ | | Android Chrome | Last 2 major versions | Older devices that pass the probe | No WebGL2 in worker or main | | Desktop Chrome / Edge | Last 2 major versions | — | — | | Desktop Firefox | Last 2 ESR + current | — | — | | iOS Safari (and all iOS browsers, which all use WebKit) | iOS 17.0 + | iOS 16.4 to 16.7 (CPU delegate, ~10 FPS) | Below iOS 16.4, or the device fails the runtime probe | | macOS Safari | 17.0 + | 16.4 to 16.7 | Below 16.4, or the device fails the runtime probe |

Degraded mode runs FaceLandmarker.detectForVideo() synchronously on the main thread. The flow still completes but the camera preview is less smooth, because detectForVideo blocks the UI thread between frames. This is the only path that works on iOS 16.4 to 16.7 (iPhone 8 / 8 Plus / X, which reach 16.7), where Safari does not support WebGL2 inside Web Workers (added in Safari 17.0). Note the lower bound: below 16.4 there is no WebAssembly SIMD, so degraded mode is not available either.

Unsupported devices

A device that cannot run the SDK is refused on the onError callback before the camera opens or the detection loop starts. All three codes share the device_error category, so the simplest integration branches on the prefix; the individual codes let you tailor the message.

| Code | Meaning | What to tell the user | | ------------------- | ---------------------------------------------------- | --------------------------------------------------------- | | device_error:7001 | No WebGL2 in either a Web Worker or the main thread | Device not supported | | device_error:7002 | No WebAssembly at all | Usually a restricted browser mode. On iOS, check whether Lockdown Mode is on | | device_error:7003 | WebAssembly present but without SIMD | On iOS: update to 16.4 or later, otherwise the device is too old. On Android: update the browser, or open the link in Chrome |

Do not offer a retry for any of these. Nothing about the device changes between attempts. Recovery, where it exists, needs an action outside the page: an OS update, a browser update, or turning off Lockdown Mode.

7002 is the one case that may be user-fixable on current hardware, since Lockdown Mode and browser policies can be turned off. That is why it is reported separately rather than folded into 7003.

Steps

  1. Request OAUTH Token
  2. Put OAuth in header
  3. SDK configuration (add SDK token)
  4. Run SDK

OAuth Token

Datachecker uses OAuth authorization. In order to request the SDK token you will need to provide a valid OAuth token in the header.

Example header:

header = {'Authorization': `Bearer ${response.accessToken}`}

This OAuth token can be retrieved with the Datachecker OAuth Token API. The scope "productapi.sdk.read" needs to be present to make use of the SDK token. If this scope is missing you will not be able to retrieve an SDK token.

FaceVerify also requires the other following scopes to send and receive results: "productapi.faceverify.write", "productapi.poll.read", "productapi.result.read"

Example OAuth:

fetch(<BASE_ENDPOINT>+"/oauth/token", {
    method: 'POST',
    body: JSON.stringify({
        "clientId": <CLIENTID>,
        "clientSecret": <CLIENTSECRET>,
        "scopes": [
            "productapi.sdk.read",
            "productapi.faceverify.write",
            "productapi.poll.read",
            "productapi.result.read",
        ]
    })
})
.then(response => response.json())

Note: Contact Datachecker for client_id and client_secret.

SDK Token

The SDK is locked. In order to use the SDK in production a token is required. The application can only be started with a valid token. This token is a base64 string. The token can be generated by calling the Datachecker SDK Token API.

Example:

fetch(<BASE_ENDPOINT>+"/sdk/token?number_of_challenges=2&customer_reference=<CUSTOMER>&validateWatermark=true&services=FACE_VERIFY", {
    method: 'GET',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': `Bearer <ACCESSTOKEN>`
    }
})
.then(response => response.json())

Configuration

To run this tool, you will need initialise with the following variables.

| ATTRIBUTE | FORMAT | DEFAULT VALUE | EXAMPLE | NOTES | | ------------------ | ----------------------- | -------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ASSETS_FOLDER | string | "" | "../" | optional Specifies location of locally hosted assets folder. (see Asset Fetching Configuration) | | ASSETS_MODE | string | "CDN" | "LOCAL" | optional Specifies mode of asset fetching, either through CDN or locally hosted assets. (see Asset Fetching Configuration) | | BACKGROUND_COLOR | string (Hex color code) | "#1d3461" | "#1d3461" | optional Specifies the background color using a hex color code. | | CONTAINER_ID | string | | "FV_mount" | required div id to mount tool on. | | DEBUG | bool | false | false | optional When debug is true more detailed logs will be visible. | | DESKTOP_MODE | bool | false | false | optional Enables all cameras for testing/development purposes. FOR TESTING ONLY - DO NOT USE IN PRODUCTION. This mode bypasses camera filtering to allow testing on desktop devices, including virtual cameras. Production environments should always use false to ensure only front-facing cameras (user) are available, preventing accidental use of back-facing cameras on mobile devices. | | LANGUAGE | string | "nl" | "nl" | required Notifications in specific language. | | LOGO | string / null | (embedded DataChecker logo) | "https://example.com/logo.png" | optional White-label the footer logo. Provide an https: image URL, a relative path to a self-hosted image (e.g. "assets/logo.png", resolved against your page), or an inline data:image/... URI, to show your own logo instead of the default DataChecker logo. Any web image format is accepted (PNG, JPG, WEBP, SVG, ...); the logo is rendered as an <img>, so an SVG file, URL, or data:image/svg+xml URI works like any other. Set to null to hide the footer logo entirely. Leave unset to keep the default. Unsafe values (http:, javascript:, protocol-relative //host, non-image data:) are ignored and the default is used. The logo is scaled to fit the footer, so a wide logo (similar to the default's proportions) displays best. | | onComplete | javascript function | | function(data) {console.log(data)} | required Callback function on complete. | | onError | javascript function | function(error) {console.log(error)} | function(error) {console.log(error)} | required Callback function on error. | | onUserExit | javascript function | function(error) {console.log(error)} | function(error) {window.history.back()} | required Callback function on user exit. | | TOKEN | string | | see SDK Token | required Datachecker SDK token. |

Asset fetching Configuration

FaceVerify requires fetching assets, which can be done either through a CDN or by hosting them locally. Configure this in the tool settings as follows:

CDN Configuration

// configuration
{
    ASSETS_MODE: "CDN",
    // other configurations
}

Locally Hosting Configuration

To host assets locally, first copy them to your desired location:

cp -r dist/assets/ path/to/hosted/assets/

Then, configure the tool to use these local assets:

// configuration
{
    ASSETS_MODE: "LOCAL",
    ASSETS_FOLDER: "path/to/hosted/assets/",
    // other configurations
}

For comprehensive integration examples, please refer to our Integration Examples.

Version Control

To ensure compatibility:

  • Separate Asset Versioning: The assets directory contains a version file, separate from the main file's version.
  • Compatibility Check: The main file will perform a version check and throw an error if the versions are incompatible.

Content Security Policy (CSP)

FaceVerify is designed to work with Content Security Policy (CSP) enabled. The SDK requires specific CSP directives to load assets (e.g., scripts, models, images) and execute WebAssembly for face detection.

Required CSP Directives

Ensure your CSP policy includes the following directives. Adjust domains based on your environment (e.g., use https://developer.datachecker.nl for Datachecker production api).

  • default-src 'self';
  • script-src 'self' https://cdn.jsdelivr.net 'wasm-unsafe-eval' 'unsafe-inline' blob:;
  • style-src 'self' 'unsafe-inline';
  • connect-src 'self' https://developer.datachecker.nl https://cdn.jsdelivr.net data:;
  • img-src 'self' data: blob: https://cdn.jsdelivr.net;
  • worker-src 'self' blob:;
  • object-src 'self' blob:;
  • frame-src 'self' blob:;
  • base-uri 'none';

Handling callbacks

Within the application, you can take advantage of three callback functions to enhance the user experience and manage the flow of your process.

Note: When integrating the application into Native Apps using web views, it's essential to adapt and utilize these callback functions according to the conventions and requirements of the native platforms (e.g., iOS, Android). Native app development environments may have specific ways of handling JavaScript callbacks, and you should ensure seamless communication between the web view and the native code.

Example Web (JS):

let FV = new FaceVerify();
FV.init({
    CONTAINER_ID: 'FV_mount',
    LANGUAGE: 'en',
    TOKEN: '<SDK_TOKEN>',
    onComplete: function(data) {
        console.log(data);
    },
    onError: function(error) {
        console.error(error.code, error.stack)
    },
    onUserExit: function(error) {
        console.log(error);
        window.history.back()
    }
});

| ATTRIBUTE | FORMAT | DEFAULT VALUE | EXAMPLE | NOTES | | ------------- | ------------------- | ------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | onComplete | javascript function | | function(data) {console.log(data)} | required Callback that fires when all interactive tasks in the workflow have been completed. | | onError | javascript function | function(error) {console.log(error.code)} | function(error) {console.log(error.code)} | required Callback that fires when an error occurs. Receives { code, message, stack, chain }. See Error Codes. | | onUserExit | javascript function | function(error) {console.log(error)} | function(error) {window.history.back()} | required Callback that fires when the user exits the flow without completing it. |

onComplete

This callback function will be called once all the tasks within the workflow succesfully have been completed. This callback function is required. The data parameter within the function represents the output of the completed process. You can customize this function to handle and display the data as needed.

Example Web (JS):

Within the example below we are logging the output (data) to console.

let FV = new FaceVerify();
FV.init({
    ...,
    onComplete: function(data) {
        console.log(data);
        // FV.stop() is called automatically - no need to call it here
    }
});

onError

This callback fires when an error occurs during the SDK lifecycle. This callback function is required. The error parameter is an object with two properties:

  • code — A structured error code (e.g., capture_error:4004). Use the category prefix to determine the appropriate UI response. See Error Codes for the full list of categories.
  • stack — A stack trace string. Include this when reporting issues to support for faster diagnosis.

Example Web (JS):

let FV = new FaceVerify();
FV.init({
    ...,
    onError: function(error) {
        console.error(error.code, error.stack);

        if (error.code.startsWith('capture_error')) {
            // Camera issue — show retry UI or prompt for camera permission
        } else if (error.code.startsWith('init_error')) {
            // Initialization failed — prompt user to refresh the page
        } else if (error.code.startsWith('detect_error')) {
            // Face detection failed — prompt user to try again
        }
    }
});

onUserExit

This callback can be used to implement actions like returning users to the previous page or prompting them for confirmation before exiting to ensure they don't lose any unsaved data or work. This callback function is required. The error parameter within the function contains information about the specific error encountered, allowing you to log or display error messages for debugging or user guidance. The error that is thrown is "exit".

Example Web (JS):

Within the example below we are logging the output (error) to console. Finally, we move back one page in the session history with window.history.back().

let FV = new FaceVerify();
FV.init({
    ...,
    onUserExit: function(error) {
        console.log(error);
        window.history.back()
    }
});

Usage/Examples

The tool first needs to be initialised to load all the models. Once its initialised, it can be started with the function FV.start();

let FV = new FaceVerify();
FV.init({
    CONTAINER_ID: ...,
    LANGUAGE: ...,
    TOKEN: ...,
    onComplete: ...,
    onError: ...,
    onUserExit: ...,
}).then(() => {
    FV.start();
});

Cleanup and Removal

The SDK automatically cleans up resources (stops the camera and removes UI elements) when the onComplete, onError, or onUserExit callbacks are triggered.

If you need to completely remove the SDK instance and its container from the DOM (e.g., when unmounting a component or navigating away), use the remove() method:

FV.remove();

This will stop all SDK processes and remove the entire container from the page. This is particularly useful in Single Page Applications (SPAs) or when you need to reinitialize the SDK later.

Example below:

let FV = new FaceVerify();
FV.init({
    CONTAINER_ID: 'FV_mount',
    LANGUAGE: 'nl',
    TOKEN: '<SDK_TOKEN>',
    onComplete: function(data) {
        console.log(data);
    },
    onError: function(error) {
        console.error(error.code, error.stack)
    },
    onUserExit: function(error) {
        console.log(error);
        window.history.back();
    },
});

Importing SDK

Import the SDK with one of the three methods: Script tag, ES6 or CommonJS.

Script Tag

Easily add FaceVerify to your HTML files using the Script Tag method.

<!-- Add FaceVerify directly in your HTML -->
<script src="dist/faceverify.obf.js"></script>

NPM

For projects using NPM and a module bundler like Webpack or Rollup, you can import FaceVerify as an ES6 module or with CommonJS require syntax.

// Import FaceVerify in your JavaScript file

// ES6 style import
import FaceVerify from '@datachecker/faceverify';

// CommonJS style require
let FaceVerify = require('@datachecker/faceverify')

Demo

<!DOCTYPE html>
<html>
<head>
<title>FaceVerify</title>
</head>

<body>
    <div id="FV_mount" style="height:100vh">
    </div>
</body>

<script src="faceverify.obf.js" type="text/javascript"></script>
<script>
    let FV = new FaceVerify();
    FV.init({
        CONTAINER_ID: 'FV_mount',
        LANGUAGE: 'en',
        TOKEN: '<SDK_TOKEN>',
        onComplete: function(data) {
            console.log(data)
        },
        onError: function(error) {
            console.log(error)
        },
        onUserExit: function(error) {
            console.log(error);
            window.history.back();
        },
    });    
</script>

</html>

Languages

Notifications can be loaded in two ways: from a language file or from a JSON object.

Loading from a file

Language files are located in assets/language/. The currently supported languages are:

  • Bulgarian (bg)
  • Czech (cz)
  • German (de)
  • English (en)
  • Spanish (es)
  • French (fr)
  • Hungarian (hu)
  • Italian (it)
  • Lithuanian (lt)
  • Dutch (nl)
  • Papiamento (pa)
  • Polish (pl)
  • Portuguese (pt)
  • Romanian (ro)
  • Slovak (sk)
  • Ukrainian (uk)

Additional languages can be added if needed.

You can load a language in the configuration by setting the LANGUAGE option:

let FV = new FaceVerify();
FV.init({
    LANGUAGE: 'en',
    ...

To create support for a new language, a js file needs to be created with specific keys. The keys can be derived from the current language js files (assets/language/en.js).

Example:

var LANGUAGE = {
    "start_prompt": "Tap to start",
    "no_face": "No face detected",
    "nod_head": "Please nod your head",
    "face_thresh": "Face covered",
    "face_far": "Move closer",
    "face_close": "Move back",
    "exp_dark": "Image is too dark",
    "blur": "Hold your phone still",
    "stay_in_frame": "Keep your face in the frame",
    "capture_error": "Camera access is required",
    "challenge_0": "Center your face",
    "detect_error": "Face detection failed. Please try again.",
    "device_error": "This device is not supported.",
    "init_error": "Initialization failed. Please refresh the page.",
    "model_error": "Failed to load required resources. Please check your connection.",
    "runtime_error": "Something went wrong. Please try again.",
    "opencv_error": "A required component failed to load. Please refresh the page.",
    "settings_error": "Configuration error. Please contact support.",
    "token_error": "Authorization failed. Please try again later.",
    "challenge_out": "Turn back a little",
    "challenge_1": "Look up",
    "challenge_2": "Look right",
    "challenge_3": "Look down",
    "challenge_4": "Look left",
    "tutorial": "Follow the instructions",
    "continue": "Continue"
}

Object (json)

Notifications can also be loaded as a json object like the following:

let FV = new FaceVerify();
FV.init({
    LANGUAGE: JSON.stringify(
        {
            "start_prompt": "Tap to start",
            "no_face": "No face detected",
            "nod_head": "Please nod your head",
            "face_thresh": "Face covered",
            "face_far": "Move closer",
            "face_close": "Move back",
            "exp_dark": "Image is too dark",
            "blur": "Hold your phone still",
            "stay_in_frame": "Keep your face in the frame",
            "capture_error": "Camera access is required",
            "challenge_0": "Center your face",
            "detect_error": "Face detection failed. Please try again.",
            "device_error": "This device is not supported.",
            "init_error": "Initialization failed. Please refresh the page.",
            "model_error": "Failed to load required resources. Please check your connection.",
            "runtime_error": "Something went wrong. Please try again.",
            "opencv_error": "A required component failed to load. Please refresh the page.",
            "settings_error": "Configuration error. Please contact support.",
            "token_error": "Authorization failed. Please try again later.",
            "challenge_out": "Turn back a little",
            "challenge_1": "Look up",
            "challenge_2": "Look right",
            "challenge_3": "Look down",
            "challenge_4": "Look left",
            "tutorial": "Follow the instructions",
            "continue": "Continue"
        }
    ),
    ...

Error Codes

The onError callback receives an object with four properties:

| Property | Description | | --------- | ----------- | | code | Structured code in the form category:NNNN, e.g. capture_error:4004. Branch on the category prefix | | message | Human-readable description of the failure | | stack | Stack trace string. Include it when reporting to support | | chain | Array tracing the causal chain, outermost first and root cause last. Each entry has name, message, optional code and stack |

Use the category prefix to determine the type of error and the appropriate response.

| Category | Description | Recommended Action | | ---------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | | capture_error | Camera failure | Show camera retry UI or prompt for permission | | detect_error | Face detection failed after repeated attempts | Prompt user to try again or refresh | | device_error | Device cannot run the SDK: no WebGL2 (7001), no WebAssembly (7002), or no WebAssembly SIMD (7003). Surfaced before start. | Show "device not supported" message. Do not offer a retry; nothing will change. See Unsupported devices | | init_error | Initialization failed | Prompt user to refresh the page | | model_error | ML model failed to load | Check network connection, retry initialization | | opencv_error | Required component failed to load | Prompt user to refresh or try a different browser | | runtime_error | Uncategorised failure — no more specific category applies (catch-all of last resort) | Show generic retry UI | | settings_error | Invalid configuration or version mismatch | Verify SDK configuration and assets | | token_error | Token missing, invalid, or not permitted | Verify token credentials |

Note that runtime_error does not mean "an error that happened at runtime" — most categories above can fire mid-session. It is the catch-all of last resort, reported only when the SDK cannot attribute a failure to any of the specific categories. Specific runtime failures keep their specific category (e.g. repeated detection failures are detect_error, camera loss is capture_error).

When reporting issues to support, include both error.code and error.stack — the numeric identifier in the code and the stack trace allow for precise diagnosis.

The user-facing alert message shown in the SDK overlay is determined by the category prefix, which maps to a key in the Languages dictionary (e.g., capture_error maps to the capture_error language key). If a custom language file does not include a key for a new category (e.g., init_error), the SDK falls back to its built-in English default.

Models

The tool uses a collection of neural networks located in the assets/ directory.

Asset Configuration: Models are part of the assets and can be fetched via CDN (default) or hosted locally. See Asset Fetching Configuration for details.

Challenges

User challenges are implemented to prevent video injection attacks. These challenges are randomly chosen and thereby, processes are different from one another. The challenges consist of head pose estimation. The performed head poses will be compared with the challenges and that result will be returned as bool in output. (see Output)

There are four poses that will be detected:

  • up
  • right
  • down
  • left

Challenges are managed exclusively through the SDK token. Specify the number of challenges when requesting your SDK token:

fetch(BASE_ENDPOINT + "/sdk/token?number_of_challenges=2&customer_reference=<CUSTOMER>&validateWatermark=true&services=FACE_VERIFY", {
    method: 'GET',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': `Bearer <ACCESSTOKEN>`
    }
})
.then(response => response.json())

The challenges are embedded in the TOKEN and are not directly configurable in the SDK initialization.

Output

The SDK will output in the following structure:

{   
    "images": [
        {
            "data":"<BASE64_IMG>", 
            "type":"LIVE"
        },
        "..."
    ],
    "meta": [
        {
            "x":"", 
            "y":"", 
            "width":"", 
            "height":"", 
            "device":""
        },
        "..."
    ],
    "token": "<SDK_TOKEN>",
    "transactionId": "<TRANSACTION_ID>",
    "valid_challenges": "true|false"
}

Each data field is a base64-encoded image. As of v8, the first LIVE image (the identity image) is JPEG and the subsequent images are PNG; detect the content type from the data rather than assuming a format. Forward the output to the DataChecker API unmodified — re-encoding or editing the images will cause the request to be rejected.

Each meta entry describes the corresponding capture: x/y/width/height locate the face region and device names the camera used.

Example:

{   
    "images": [
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }, 
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }, 
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }
    ],
    "meta": [
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }, 
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }, 
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }
    ],
    "token": "<SDK_TOKEN>",
    "transactionId": "<TRANSACTION_ID>",
    "valid_challenges": true
}

FaceVerify API call

If you want to send the images to the Datachecker FaceVerify API you must add a comparison image. This comparison image can either be a portrait picture from an identity card or a selfie. To add this image, you need to use type: "COMPARE".

Example JS:

let faceverify_output = {   
    "images": [
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }, 
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }, 
        {
            "data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", 
            "type":"LIVE"
        }
    ],
    "meta": [
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }, 
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }, 
        {
            "x": 33, 
            "y": 182, 
            "width": 265, 
            "height": 354, 
            "device": "Front camera"
        }
    ],
    "token": "<SDK_TOKEN>",
    "transactionId": "<TRANSACTION_ID>",
    "valid_challenges": true
}
let images = faceverify_output.images
let portrait_image = {"data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...", "type":"COMPARE"}

images.unshift(portrait_image)
let data = {"images": images, "transaction_id":faceverify_output.transactionId}


fetch(<BASE_ENDPOINT>+"/faceverify", {
        method: 'POST',
        headers: <HEADERS>,
        body: JSON.stringify(data)
        })
        .then(response => response.json())