Face Liveness & Face Authenticator

Enables integration of facial verification into applications, providing a secure and seamless user authentication experience.

The CafFaceLiveness Web SDK provides facial liveness detection with support for multiple providers, each offering different features and capabilities. The SDK automatically routes to the appropriate provider based on your mobile token configuration.

Supported providers

Provider
Description

Caf

Liveness 2D validation using Caf's solutions

FaceTec

FaceTec's 2D liveness detection technology

iProov

Liveness detection with GPA and LA technologies

Payface

Payface's facial verification technology

Quick start

1. Installation

Include the SDK script in your HTML file:

<script src="https://repo.combateafraude.com/javascript/release/caf-face-liveness/0.7.2/caf-face-liveness_0.7.2.umd.js"></script>

Or include it via JavaScript:

const sdkScript = document.createElement("script");
sdkScript.src = "https://repo.combateafraude.com/javascript/release/caf-face-liveness/0.7.2/caf-face-liveness_0.7.2.umd.js";
document.body.appendChild(sdkScript);

You can also download the SDK file from the Caf CDN and then include it directly in your project. This is useful if you prefer to host the SDK file or if you want to avoid loading it from a CDN.

2. Basic usage

const CafFaceLivenessSdk = window["CafFaceLiveness"];

// Initialize the SDK
await CafFaceLivenessSdk.init("your-sdk-token", "user-person-id", { htmlContainerId: "your-container-id" });

// Run face liveness detection
try {
  const result = await CafFaceLivenessSdk.run();
  console.log("Liveness result:", result);
} catch (error) {
  console.error("Liveness failed:", error);
} finally {
  // Clean up when finished successfully or on error
  CafFaceLivenessSdk.dispose();
}

Complete example

Here's a ready-to-use HTML example:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CafFaceLiveness Example</title>
  </head>
  <body>
    <h1>CafFaceLiveness SDK Example</h1>

    <div id="status"></div>

    <div>
      <button id="initBtn">Initialize SDK</button>
      <button id="runBtn" disabled>Run</button>
      <button id="disposeBtn" disabled>Dispose SDK</button>
    </div>

    <div id="your-container-id"></div>

    <script>
      // UI elements
      const statusDiv = document.getElementById("status");
      const initBtn = document.getElementById("initBtn");
      const runBtn = document.getElementById("runBtn");
      const disposeBtn = document.getElementById("disposeBtn");

      function setStatus(message) {
        statusDiv.textContent = message;
      }

      function updateButtons(init = false, run = false, dispose = false) {
        initBtn.disabled = !init;
        runBtn.disabled = !run;
        disposeBtn.disabled = !dispose;
      }

      // Initial button state
      updateButtons(false, false, false);

      // SDK installation
      let CafFaceLivenessSdk;
      const loadSdkScript = async (src) => {
        return new Promise((resolve, reject) => {
          const existingScript = document.querySelector(`script[src="${src}"]`);
          if (existingScript) {
            resolve();
            return;
          }

          const script = document.createElement("script");
          script.src = src;
          script.async = true;
          script.onload = resolve;
          script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
          document.body.appendChild(script);
        });
      };
      loadSdkScript("https://repo.combateafraude.com/javascript/release/caf-face-liveness/0.7.2/caf-face-liveness_0.7.2.umd.js")
        .then(() => {
          CafFaceLivenessSdk = window["CafFaceLiveness"];
          setStatus("SDK is loaded and ready to be initialized");
          updateButtons(true, false, false); // Enable init button
        })
        .catch((error) => {
          console.error("Error loading CafFaceLiveness SDK script:", error);
          setStatus(`Error loading SDK: ${error.message}`);
        })
      ;

      // Initialize SDK
      initBtn.addEventListener("click", async () => {
        try {
          setStatus("Initializing SDK...");
          updateButtons(false, false, false);

          await CafFaceLivenessSdk.init(
            "your-sdk-token-here", // Replace with your actual SDK token
            "user-person-id-here", // Replace with the person ID you want to use
            {
              htmlContainerId: "your-container-id", // Replace with the ID of your HTML container
              performFaceAuthentication: false, // Set to true if you want to perform face authentication along with liveness detection
            },
            { startButton: { label: "Start Face Scan", backgroundColor: "#154EF7", color: "#ffffff" } },
          );

          setStatus("SDK initialized successfully!");
          updateButtons(false, true, true);
        } catch (error) {
          setStatus(`Initialization failed: ${error.message}`);
          updateButtons(true, false, false);
          console.error("Initialization error:", error);
        }
      });

      // Run liveness detection
      runBtn.addEventListener("click", async () => {
        try {
          setStatus("Running liveness detection...");
          updateButtons(false, false, false);

          const result = await CafFaceLivenessSdk.run();

          setStatus("Liveness detection completed successfully!");
          updateButtons(false, false, true);

          console.log("Liveness result:", result);
        } catch (error) {
          setStatus(`Liveness detection failed: ${error.message}`);
          console.error("Liveness error:", error);

          CafFaceLivenessSdk.dispose(); // Dispose SDK on error

          updateButtons(true, false, false);
        }
      });

      // Dispose SDK
      disposeBtn.addEventListener("click", () => {
        try {
          CafFaceLivenessSdk.dispose();
          setStatus("SDK disposed successfully");
          updateButtons(true, false, false);
        } catch (error) {
          setStatus(`Dispose failed: ${error.message}`);
          console.error("Dispose error:", error);
        }
      });
    </script>
  </body>
</html>

SDK reference

Initialization

async init(sdkToken: string, personId: string, config?: object, customization?: object): Promise<void>

Initializes the SDK with the provided configuration.

Init parameter
Type
Required or Optional
Description

sdkToken

string

Required

SDK token for authentication

personId

string

Required

Unique identifier for the user

config

object

Optional

SDK configuration options.

Check the Configuration options section for more details.

customization

object

Optional

Appearance and text customization options.

Check the Customization options section for more details.

Configuration options

Config parameter
Type
Required or Optional
Description
Provider Support

htmlContainerId

string

Required

ID of the HTML container for the SDK UI

iProov, Caf, FaceTec

enableDebugMode

boolean

Optional

Enable debug mode for development

All Providers

performFaceAuthentication

boolean

Optional

Whether to perform face authentication along with liveness detection

Enabling face authentication requires a previously registered face for the given personId. Check the Face Authentication section for more details.

All Providers

language

string

Optional

Language for the UI. Supported values: "en_US", "es_MX", "pt_BR"

All Providers

disableAnalytics

boolean

Optional

Disable analytics tracking

All Providers

cameraPreviewFilter

string

Optional

Filter for the camera preview. Supported values: "shaded", "classic", "vibrant", "clear", "blur"

When using the "clear" camera filter with GPA enabled, the SDK will not be able to be executed and will throw an error. If GPA is enabled, make sure to use a different camera filter option.

iProov

reverseProxy

object

Optional

Reverse proxy configuration.

Check the Reverse proxy configuration section for more details.

iProov

Customization options

Customization parameter
Type
Description
Provider Support

appearance.captureButtonIcon

string

URL of the capture button icon

Caf, FaceTec

appearance.captureIconSize

string

Size of the capture button icon

Caf, FaceTec

appearance.captureButtonColor

string

Color of the capture button

Caf, FaceTec

appearance.fontFamily

string

Font family for the UI

Caf, FaceTec

startButton.label

string

Start button text

iProov

startButton.color

string

Start button text color

iProov

startButton.backgroundColor

string

Start button background color

iProov

startButton.borderRadius

string

Start button border radius

iProov

startButton.border

string

Start button border style

iProov

startButton.padding

string

Start button padding

iProov

startButton.margin

string

Start button margin

iProov

messages.title

string

Title text for the UI

Caf, FaceTec

messages.loading

string

Loading message during capture

Caf, FaceTec

messages.errors.captureFailed

string

Error message when capture fails

Caf, FaceTec

Error handling

The init method can throw various types of errors, including:

Error
Description
Provider Support

RequestTokenError

Thrown when session creation fails due to invalid tokens or server issues

All Providers

UnsupportedError

Thrown when device or browser features are not supported by the SDK

All Providers

Running

async run(options?: object): Promise<string>

Executes the face liveness detection process.

Run parameter
Type
Required or Optional
Description

options

object

Optional

Options for the run method.

Check the Run options section for more details.

Run options

Run option
Type
Description

cancelPromise

Promise<void>

Promise that resolves when the operation should be cancelled.

onCaptureProcessingStart

function

Callback that is called when capture processing starts.

onCaptureProcessingEnd

function

Callback that is called when capture processing ends.

Returns

The method returns a Promise<string> that resolves with a JWT token string containing the execution result.

Important: The fields described below are contained in the decoded payload of this JWT token. You must decode and verify the JWT token to access these fields.

JWT payload structure

After decoding the JWT, the payload contains an object with the following properties:

  • imageUrl (string): Temporary URL of the captured image

  • isAlive (boolean): Indicates if the liveness check was successful

  • isMatch (boolean): Indicates if the face authentication was successful (if enabled)

  • sessionId (string): Unique session identifier for the execution

  • personId (string): The person ID used for the execution

Error handling

The run method can throw various types of errors, including:

Error
Description
Provider Support

CameraUnsupportedError

Thrown when the browser does not support camera access

All Providers

CameraPermissionDeniedError

Thrown when the user denies camera permission access

All Providers

CameraPermissionError

Thrown for general camera permission errors (not denial-specific)

All Providers

FaceValidationError

Thrown when an error occurs during liveness or face authentication validation

All Providers

RenderCaptureWindowError

Thrown when the capture window cannot be rendered properly

iProov

CaptureError

Thrown when an error occurs during the capture process

iProov

Dispose

dispose(): void

Cleans up SDK resources. It should be called when the SDK is no longer needed.

Products

Face Liveness

The SDK provides face liveness detection to ensure that the user is alive and present during the process.

How Face Liveness works

  1. Camera access: The SDK requests access to the user's camera

  2. Face capture: The SDK captures a photo of the user's face

  3. Liveness validation: The SDK analyzes the captured face to check if the user is alive

  4. Result: The JWT token payload includes the isAlive field indicating if the user is alive

Face Liveness result interpretation

isAlive
Meaning

true

✅ User is alive and liveness check passed

false

❌ Liveness detection failed

Face Authentication

The SDK supports face authentication to be performed in addition to liveness detection. When enabled, after liveness validation, the SDK will compare the captured face against a previously registered face to verify the user's identity.

To enable face authentication, set the performFaceAuthentication parameter to true during SDK initialization:

await CafFaceLivenessSdk.init("your-sdk-token", "user-person-id",
  {
    htmlContainerId: "your-container-id",
    performFaceAuthentication: true, // Enable face authentication
  }
);

How Face Authentication works

  1. Face registration: The user's face must be previously registered using the personId

  2. Face Liveness: The SDK captures the user's face and performs liveness validation

  3. Face Authentication: The captured face is compared against the registered face for the given personId

  4. Result: The JWT token payload includes the isMatch field indicating if there is a match with the registered face

Face Authentication result interpretation

isAlive
isMatch
Meaning

true

true

✅ User is alive and face matches registered face

true

false

⚠️ User is alive but face does not match

false

-

❌ Liveness detection failed

Reverse proxy configuration

If you choose to use a reverse proxy, you must configure it to properly forward requests to the appropriate endpoints. Below is the mapping for redirection:

  • /v1/https://api.public.caf.io/v1/sdks/faces/

    • Consider using https://api.public.beta.caf.io/v1/sdks/faces/ for homologation.

  • /std/https://us.rp.secure.iproov.me/

  • /std/ws/wss://us.rp.secure.iproov.me/ws/

  • /assets/https://cdn.iproov.app/

Reverse proxy configuration example

Supposing your domain is my.proxy.io, your SDK configuration would look like this:

reverseProxy: {
  authenticationBaseUrl: "https://my.proxy.io/v1/",
  faceLivenessBaseUrl: "https://my.proxy.io/std/",
  assetsBaseUrl: "https://my.proxy.io/assets/"
}

Note: The paths provided in this example are just for reference. You can configure your proxy and paths according to your best practice standards.

Integration options

To perform integration through an iframe, camera and fullscreen permissions must be provided.

<iframe
  src="https://caf.example"
  allow="camera;fullscreen;accelerometer;gyroscope;magnetometer;"
></iframe>

SDK events

The SDK dispatches various events during its lifecycle to be able to handle different scenarios of the liveness detection process and provide a better user experience.

Listen for events using the DOM event listener pattern:

document.addEventListener("event-name", (event) => {
  console.log("Event data:", event.detail);
});

Currently, events are only available when using the iProov provider. Event support for other providers is planned for future releases.

Available events

Event Name
Description
Provider Support

started

Liveness detection process begins

iProov

sdk-button-ready

SDK start button is ready for interaction

iProov

streaming

Streaming has started, remaining in fullscreen

iProov

streamed

End of streaming and exited fullscreen

iProov

passed

Liveness detection is successful

iProov

failed

Liveness detection fails

iProov

canceled

User cancels the process

iProov

error

An error occurred during the process

iProov

permission

Camera permission is requested

iProov

permission_denied

Camera permission is denied by the user

iProov

unsupported

Browser does not support the SDK

iProov

Event details: iProov "failed" event

When liveness detection fails, the failed event provides specific feedback:

document.addEventListener("failed", (event) => {
  console.log("Reason: ", event.detail.reason);
  console.log("Feedback: ", event.detail.feedback);
});

The table below summarizes the possible failed event details:

Feedback
Reason
LA
GPA

eyes_closed

Keep your eyes open

face_too_far

Move your face closer to the screen

face_too_close

Move your face farther from the screen

misaligned_face

Keep your face in the oval

multiple_faces

Ensure only one person is visible

obscured_face

Remove any face coverings

sunglasses

Remove sunglasses

too_bright

Ambient light too strong or screen brightness too low

too_dark

Your environment appears too dark

too_much_movement

Please keep still

unknown

Try again

Event details: iProov "error" event

When an error occurs during the liveness detection process, the error event provides additional details about the error:

document.addEventListener("error", (event) => {
  console.log("Reason: ", event.detail.reason);
  console.log("Feedback: ", event.detail.feedback);
});

The table below summarizes the possible error event details:

Feedback
Reason

unknown

Try again

client_camera

There was an error getting video from the camera

client_error

An unknown error occurred

error_asset_fetch

Unable to fetch assets

error_camera

The camera cannot be started for unknown reasons

error_camera_in_use

The camera is already in use and cannot be accessed

error_camera_not_supported

The camera resolution is too small

error_camera_permission_denied

The user denied our camera permission request

error_device_motion_denied

The user denied our device motion permission request

error_device_motion_unsupported

Your device does not seem to fully report device motion

error_fullscreen_change

Exited fullscreen without completing iProov

error_invalid_token

The sdk internal token is invalid

error_network

Network error

error_no_face_found

No face could be found

error_not_supported

The device or integration isn't able to run the Web SDK

error_server

An error occurred when communicating with iProov's servers

error_token_timeout

The token was claimed too long after being created

error_too_many_requests

The service is under high load and the user must try again

error_user_timeout

The user started the claim but did not stream in time

integration_unloaded

The SDK was unmounted from the DOM before it finished

sdk_unsupported

The SDK has passed end of life and is no longer supported

Last updated