> For the complete documentation index, see [llms.txt](https://docs.caf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.caf.io/caf-sdk/web-javascript/getting-started/face-liveness-and-face-authenticator.md).

# Face Liveness & Face Authenticator

## Face Liveness & Face Authenticator

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:

```html
<script src="https://repo.combateafraude.com/javascript/release/caf-face-liveness/0.17.2/caf-face-liveness_0.17.2.umd.js"></script>
```

Or include it via JavaScript:

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

{% hint style="info" %}
You can also download the SDK file from the [Caf CDN](https://repo.combateafraude.com/javascript/release/caf-face-liveness/0.17.2/caf-face-liveness_0.17.2.umd.js) 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.
{% endhint %}

#### 2. Basic usage

```javascript
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:

```html
<!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.17.2/caf-face-liveness_0.17.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

```typescript
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             | <p>SDK configuration options.</p><p>Check the <a href="#configuration-options">Configuration options</a> section for more details.</p>                 |
| `customization` | object | Optional             | <p>Appearance and text customization options.</p><p>Check the <a href="#customization-options">Customization options</a> section for more details.</p> |

**Configuration options**

| Config parameter            | Type    | Required or Optional | Description                                                                                                                                                                                                                                                                                                 | Provider Support |
| --------------------------- | ------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `htmlContainerId`           | string  | Required (iProov)    | ID of the HTML container for the SDK UI. Required only when the selected provider is **iProov**.                                                                                                                                                                                                            | iProov           |
| `enableDebugMode`           | boolean | Optional             | Enable debug mode for development                                                                                                                                                                                                                                                                           | All Providers    |
| `performFaceAuthentication` | boolean | Optional             | <p>Whether to perform face authentication along with liveness detection</p><p>Enabling face authentication requires a previously registered face for the given <code>personId</code>. Check the <a href="#face-authentication">Face Authentication</a> section for more details.</p>                        | 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             | <p>Filter for the camera preview. Supported values: "shaded", "classic", "vibrant", "clear", "blur"</p><p>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.</p> | iProov           |
| `reverseProxy`              | object  | Optional             | <p>Reverse proxy configuration.</p><p>Check the <a href="#reverse-proxy-configuration">Reverse proxy configuration</a> section for more details.</p>                                                                                                                                                        | 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     |

**Handling initialization errors**

{% hint style="warning" %}
**Important**: Starting from version 0.13.0, the SDK's error handling has changed. Review and update your integration to align with the new error names and behavior.
{% endhint %}

Errors that can occur during the `init()` method:

| Error name           | Description                                                                                                                    |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `CafSdkInitError`    | An error occurred during the SDK initialization (e.g. missing required parameters).                                            |
| `CafSdkSessionError` | Error while creating session to perform liveness or face authentication. Check if the token provided is valid and not expired. |
| `CafUnknownError`    | An unknown internal error occurred                                                                                             |

{% hint style="info" %}
Any other unexpected errors will be thrown as JavaScript default `Error` class.
{% endhint %}

**Example:**

```javascript
try {
  await CafFaceLivenessSdk.init("your-sdk-token", "user-person-id", {
    htmlContainerId: "your-container-id",
  });
  console.log("SDK initialized successfully!");
} catch (error) {
  switch (error.name) {
    case "CafSdkInitError":
      console.error("SDK initialization error:", error.message);
      break;
    case "CafSdkSessionError":
      console.error("Session error:", error.message);
      break;
    case "CafUnknownError":
      console.error("Internal error:", error.message);
      break;
    default:
      console.error("Unexpected init error:", error.name, error.message);
  }
}
```

#### Running

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

Executes the face liveness detection process.

| Run parameter | Type   | Required or Optional | Description                                                                                                         |
| ------------- | ------ | -------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `options`     | object | Optional             | <p>Options for the run method.</p><p>Check the <a href="#run-options">Run options</a> section for more details.</p> |

**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

**Handling run errors**

{% hint style="warning" %}
**Important**: Starting from version 0.13.0, the SDK's error handling has changed. Review and update your integration to align with the new error names and behavior.
{% endhint %}

Errors that can occur during the `run()` method:

| Error name                             | Description                                                       |
| -------------------------------------- | ----------------------------------------------------------------- |
| `CafCameraPermissionError`             | Error getting camera permission                                   |
| `CafCameraPermissionDeniedError`       | Camera permission denied by the user                              |
| `CafCameraUnsupportedError`            | Camera is not supported by the browser/device                     |
| `CafSdkRunError`                       | An error occurred while running the SDK                           |
| `CafSdkCanceledError`                  | SDK run canceled by the user or `cancelPromise`                   |
| `CafFaceLivenessError`                 | Error during liveness validation                                  |
| `CafFaceAuthenticationError`           | Error during face authentication                                  |
| `CafFaceNotFoundError`                 | No registered face was found for the user                         |
| `CafUnknownError`                      | An unknown internal error occurred                                |
| `CafUnsupportedError`                  | SDK is not supported on this device, browser or operating system. |
| `CafDeviceMotionPermissionDeniedError` | Device motion permission denied by the user.                      |

{% hint style="info" %}
Any other unexpected errors will be thrown as JavaScript default `Error` class.
{% endhint %}

**Example:**

```javascript
try {
  const result = await CafFaceLivenessSdk.run();
  console.log("Liveness result:", result);
} catch (error) {
  switch (error.name) {
    case "CafCameraPermissionError":
      console.error("General camera permission error:", error.message);
      break;
    case "CafCameraPermissionDeniedError":
      console.error("Camera permission denied error:", error.message);
      break;
    case "CafCameraUnsupportedError":
      console.error("Camera not supported error:", error.message);
      break;
    case "CafSdkRunError":
      console.error("Error during SDK run:", error.message);
      break;
    case "CafSdkCanceledError":
      console.error("SDK cancellation error:", error.message);
      break;
    case "CafFaceLivenessError":
      console.error("Liveness error:", error.message);
      break;
    case "CafFaceAuthenticationError":
      console.error("Face authentication error:", error.message);
      break;
    case "CafFaceNotFoundError":
      console.error("No registered face found for the user:", error.message);
      break;
    case "CafUnsupportedError":
      console.error("Unsupported error:", error.message);
      break;
    case "CafDeviceMotionPermissionDeniedError":
      console.error("Device motion permission denied error:", error.message);
      break;
    case "CafUnknownError":
      console.error("Internal error:", error.message);
      break;
    default:
      console.error("Unexpected run error:", error.name, error.message);
  }
}
```

#### Dispose

```typescript
dispose(): void
```

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

**Example**

```javascript
try {
  CafFaceLivenessSdk.dispose();
  console.log("SDK disposed successfully");
} catch (error) {
  console.error("Dispose error:", error.name, error.message);
}
```

### 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:

```javascript
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://web.us.prd.caf.io/bff/`
* `/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:

```javascript
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

{% tabs %}
{% tab title="iframe" %}
To perform integration through an `iframe`, camera and fullscreen permissions must be provided.

```html
<iframe
  src="https://your-iframe-target.example"
  style="width: 100vw; height: 100vh; border: 0"
  allow="camera;fullscreen;accelerometer;gyroscope;magnetometer;"
  allowfullscreen="true"
></iframe>
```

#### iOS Sensor Permission Requirements

Recent iOS 26 releases introduced changes that broke the motion-sensor permission flow for iframe integrations. The workaround that relied on a pre-flight permission button stopped working and has been deprecated.

Starting in version `0.14.1`, the bundled **iProov** provider has been upgraded, which natively handles the new iOS requirements when the Web SDK runs inside an iframe. The only supported path is to upgrade your integration to CafFaceLiveness `0.14.1` (or newer). Earlier versions will not work on the latest iOS 26 devices, even if you keep the previous workaround in place.

After upgrading, you can embed the iframe exactly as shown above. No extra buttons or custom permission flows are necessary.
{% endtab %}

{% tab title="Webview" %}
To use the SDK through a Webview, camera permission must be granted in your native application.

Example implementation on Android:

`AndroidManifest.xml`

```java
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-feature
    android:name="android.hardware.camera"
    android:required="true" />
```

`MainActivity`

```java
  @Override
  public void onPermissionRequest(final PermissionRequest request) {
    request.grant(request.getResources());
  }
```

Sample [android](https://github.com/combateafraude/android-webview-example) project for webview implementation, in addition it is necessary to be able to open the application in full screen, the example shows how to configure it correctly.
{% endtab %}
{% endtabs %}

### 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:

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

{% hint style="info" %}
Currently, events are only available when using the **iProov** provider. Event support for other providers is planned for future releases.
{% endhint %}

{% tabs %}
{% tab title="iProov" %}

#### Available events

| Event Name           | Description                                    | Provider Support |
| -------------------- | ---------------------------------------------- | ---------------- |
| `started`            | Liveness detection process begins              | iProov           |
| `sdk-button-ready`   | SDK start button is ready for interaction      | iProov           |
| `sdk-button-clicked` | User clicked the SDK start button              | 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           |
| `unsupported`        | Browser does not support the SDK               | iProov           |

#### Event details: iProov "failed" event

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

```javascript
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:

```javascript
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  |
| {% endtab %}                       |                                                            |
| {% endtabs %}                      |                                                            |

## Release notes

### CafFaceLiveness v0.17.2

#### Fixes

* **iProov provider**: Fixed zoom behavior issue on tablets in landscape mode, ensuring proper display scaling across all devices.
* **Payface provider**: Extended SDK loading timeout window and added diagnostic logging to improve initialization reliability on slow network connections.

### CafFaceLiveness v0.17.1

#### Improvements

* **Dependencies updated**: Updated Payface provider with important security enhancements and improvements to facial capture.

#### Fixes

* **iProov provider**: Fixed an issue where the facial capture screen was not displayed correctly in fullscreen on iOS mobile devices.

### CafFaceLiveness v0.17.0

#### New Features

* **Specific handling for unregistered face**: Added `CafFaceNotFoundError`. When no face is registered for the given `personId`, the SDK now throws this specific error instead of a generic one, significantly improving error handling on the frontend.

#### Improvements

* Better handling of user failure errors, including face not found, camera permission denied, and device motion errors.
* **Dependencies updated**: Updated internal dependencies to enhance security and stability.
* **Logging**: Enhanced internal logging and analytics for better debugging and monitoring.

### CafFaceLiveness v0.16.0

#### Features

* **Start button click event**: Added a new `sdk-button-clicked` event, dispatched when the user clicks the iProov start button. Use it alongside the existing `sdk-button-ready` event to track user engagement during the verification flow.

#### Fixes

* Fixed an error that could occur when calling `dispose()` after the liveness flow had already completed.

### CafFaceLiveness v0.15.1

#### Improvements

* **Dependencies updated**: Updated iProov provider and internal dependencies to enhance performance and stability.
* **Error handling**: Improved error handling for the iProov provider.
* **Logging**: Enhanced internal logging and analytics for better debugging and monitoring.

#### Features

* **Analytics**: Added new events to the internal analytics system to better track browser compatibility and support.

### CafFaceLiveness v0.14.3

#### Fixes

* Added errors for unsupported browsers and device motion denied permissions: `CafUnsupportedError` and `CafDeviceMotionPermissionDeniedError`.
* Improved analytics by adding more specific logs for errors and failures using iProov provider.

### CafFaceLiveness v0.14.2

#### Enhanced SDK Analytics

* Improved logging by adding information about capture attempts and specific quality metrics.
* Added **abandonment tracking**: when a user abruptly leaves the journey before completion, such as closing the browser window, minimizing the tab, or navigating to a different page, the SDK will track this event to provide better insights about the user journey and possible reasons for abandonment.

### CafFaceLiveness v0.14.1

{% hint style="warning" %}
**Important for iProov provider**: Updating to version `0.14.1` or newer is required for iframe integrations on the latest iOS releases.
{% endhint %}

#### Fixes

* Upgraded the **iProov** provider engine, fixing iframe launches on devices running iOS 26.x and eliminating the previous motion-sensor permission workaround.

### CafFaceLiveness v0.14.0

#### Improvements

This version includes an update to our Payface provider that enhances the user experience, leading to higher success rates. Key improvements include:

* **Improved user guidance**: New lighting alerts help users find the ideal conditions for a successful capture.
* **Enhanced accessibility**: Clearer instructions create a smoother and more inclusive user journey.
* **More responsive experience**: Canceling the capture is now faster, improving usability.

#### Features

* **Device fingerprinting**: Collects device fingerprint during verification to strengthen fraud prevention and risk analysis. Disabled by default; contact our team to enable.

### CafFaceLiveness v0.13.0

{% hint style="warning" %}
**Breaking change**: Error names have changed in v0.13.0. We highly recommend reviewing the [SDK Reference](#sdk-reference) section before upgrading to this version to keep compatibility.
{% endhint %}

* **Simplified, name-based error handling**: Consolidated error types into clear, descriptive names to improve consistency.
* **Dependencies updated**: Enhanced SDK stability, security, and compatibility.

### CafFaceLiveness v0.12.1

* **More robust image capture system**: The SDK now features an intelligent fallback mechanism, ensuring that image capture works more reliably across different devices and browsers, even in scenarios with technical limitations.
* **Enhanced image quality validation**: New validations have been implemented to prevent low-quality images, increasing the reliability of the capture process.
* **Performance optimization on initialization**: The SDK initialization process is now faster and lighter, reducing the waiting time for the user.
* **Improved visual feedback**: New events and status messages allow the user interface to more accurately inform the user about the capture moment.

### CafFaceLiveness v0.12.0

#### Features

* **Enhanced Camera selection**: Intelligent label/facing-mode detection with heuristic best-camera selection (Caf and FaceTec).
* **Unified discovery and stream reuse**: Single user media discovery with stream reuse and automatic camera fallback, reducing permission prompts and speeding up initialization (Caf and FaceTec).
* **Faster camera switching**: Near-instant camera switching with cached selections (Caf and FaceTec).

### CafFaceLiveness v0.11.2

#### Improvements

**Enhanced user experience during interruptions**: Improved Face Liveness behavior when users experience focus changes or interruptions during face capture sessions using Payface provider.

* Added pause/resume functionality when browser focus is lost (tab switching, minimizing, etc.)
* Users can now recover from interruptions instead of restarting the entire capture process
* Reduced session abandonment rates due to accidental interruptions

### CafFaceLiveness v0.11.1

#### Fixes

**Improved device compatibility**: Enhanced Face Liveness stability and compatibility across various devices and browsers, significantly reducing session failures and improving user experience during the face verification process using Payface provider.

* Fixed compatibility issues that were causing "unsupported" errors on certain devices
* Improved camera initialization reliability across different mobile devices and browsers
* Reduced abandonment rates during Face Liveness sessions

### CafFaceLiveness v0.11.0

#### Features

**Improved camera initialization**: Refactored camera initialization when using Caf or FaceTec providers by moving camera setup from SDK initialization to execution phase, resulting in faster initialization and better resource management.

#### Fixes

* Fixed an issue where the camera stream wasn't playing automatically when initializing the SDK inside a mobile WebView.

### CafFaceLiveness v0.10.1

#### Fixes

* Ensures the SDK closes properly after capture errors when using the Caf or FaceTec providers, preventing inconsistent states and allowing the user to retry the process.

### CafFaceLiveness v0.10.0

#### Features

**Enhanced analytics tracking**: Improved analytics events tracking, providing better error monitoring and debugging capabilities of the SDK.

#### Fixes

* Fixed camera startup failures and fullscreen overlay issues when using Caf or FaceTec providers.
* Fixed reverse proxy configuration to properly forward requests to the desired endpoints.

### CafFaceLiveness v0.9.0

#### Features

* **Fullscreen mode**: Enable fullscreen mode when using Caf or FaceTec providers to enhance user experience.
* **Payface improvements**: Updated Payface provider to improve observability and Webview compatibility.

### CafFaceLiveness v0.7.3

#### Fixes

Fixed an issue where the SDK was not enabling face authentication when using the Payface provider. The SDK now correctly performs face authentication when the `performFaceAuthentication` option is set to `true` during initialization.

### CafFaceLiveness v0.7.2

Introducing **CafFaceLiveness**, a Web SDK for facial liveness detection and authentication in web applications.

#### Features

* **Face Liveness Detection**: Real-time validation to ensure user presence
* **Face Authentication**: Optional identity verification against registered faces
* **Multi-Provider Support**: Automatic routing between Caf, FaceTec, iProov, and Payface providers
* **Flexible Configuration**: Customization options for UI and behavior
* **Multi-Language**: Built-in support for English, Spanish, and Portuguese
* **Reverse Proxy**: Secure API traffic through reverse proxy configuration

{% hint style="info" %}
**Note**: This is the initial release of the CafFaceLiveness Web SDK. Future versions will include additional features, improvements, and expanded provider support.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.caf.io/caf-sdk/web-javascript/getting-started/face-liveness-and-face-authenticator.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
