> 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/android/getting-started-with-the-sdk.md).

# Face Liveness

{% hint style="warning" %}
This guide covers version 7.14.0 and above. For versions below 7.14.0, please see the [legacy documentation](https://docs.caf.io/caf-sdk/android/getting-started-with-the-sdk-1).
{% endhint %}

## Prerequisites

Before proceeding, ensure the Certta SDK is properly installed. If you haven't done this yet, please refer to our Installation Guide.

{% content-ref url="/pages/wE8ByH57MIhDucnUQi54" %}
[Installation Guide](/caf-sdk/android/installation-guide.md)
{% endcontent-ref %}

## Starting Liveness

To start the Liveness flow, call `CerttaLiveness.instance.open()` and pass a `LivenessConfiguration` object.

{% hint style="info" %}
This method accepts a callback to handle the results and events triggered during the Liveness flow.
{% endhint %}

{% tabs %}
{% tab title="Kotlin" %}
{% code expandable="true" %}

```kotlin
val livenessConfig = LivenessConfiguration(
    maxRetryAttempts = 3,
    faceAuthEnabled = false,
    showLoading = true,
    useFaceLivenessUi = true
)
CerttaLiveness.instance.open(livenessConfig) { event ->
    when (event) {
        is LivenessEvent.Completed -> {
            when (val result = event.result) {
                is LivenessResult.Success -> {
                    // Handle Success
                }
                is LivenessResult.Failed -> {
                    // Handle Failed
                }
            }
        }
        is LivenessEvent.Error -> {
            // Handle Error
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

```java
LivenessConfiguration livenessConfiguration = new LivenessConfiguration(
    3,      // maxRetryAttempts
    false,  // faceAuthEnabled
    true,   // showLoading
    true    // useFaceLivenessUi
);
CerttaLiveness.getInstance().open(livenessConfiguration, new CerttaLivenessListener() {
    @Override
    public void onEvent(@NotNull LivenessEvent event) {
        if (event instanceof LivenessEvent.Completed) {
            LivenessResult result = ((LivenessEvent.Completed) event).getResult();    
            if (result instanceof LivenessResult.Success) {
                // Handle Success
            } else if (result instanceof LivenessResult.Failed) {
                // Handle Failed
            }    
        } else if (event instanceof LivenessEvent.Error) {
            // Handle Error    
        }
    }
});
```

{% endtab %}
{% endtabs %}

### `LivenessConfiguration` Parameters

| Parameter           | Default | Description                                                 |
| ------------------- | ------- | ----------------------------------------------------------- |
| `maxRetryAttempts`  | `3`     | Maximum retries after a failed capture attempt.             |
| `faceAuthEnabled`   | `false` | When **enabled**, the SDK performs **face authentication.** |
| `showLoading`       | `true`  | Shows loading indicators during processing when **true**.   |
| `useFaceLivenessUi` | `false` | If **enabled**, the SDK uses the built-in Certta UI.        |

## Understanding Liveness Events & Results

To handle the outcome of the Liveness flow, pass a callback to the `CerttaLiveness.instance.open()` method to listen for **success**, **failure**, or **error** events.

{% hint style="warning" %}
Ensure the JWT response is evaluated on the backend. This process must include validating the token's signature and verifying the `isAlive` and `isMatch` fields. Do not perform these validations on the client side.
{% endhint %}

### **`LivenessEvent.Completed(result: LivenessResult)`**

This event indicates that the UI flow has finished. It contains a `LivenessResult` which you must evaluate:

1. **`LivenessResult.Success(response: String)`:** The capture and liveness pipeline succeeded. **`response`** is a JWT containing the result data obtained during the Liveness execution. This data may include information relevant to the process, such as captured images or validation results.
2. **`LivenessResult.Failed(failure: LivenessFailure)`:** Liveness ran, but the outcome is a business failure. See **`LivenessFailure`** below.

### **`LivenessFailure`**

Indicates that the liveness check concluded with a failure. There are two variants:

1. **`LivenessFailure.imageCaptureFailure(cause: String)`:** Problems during capture, such as environment issues, timeout, no face detected, or provider-specific failure. The `cause` is intended for diagnostics or UX messaging.
2. **`LivenessFailure.faceRecognitionFailure(result: String, cause: String)`:** Capture succeeded, but **face recognition / backend** did not accept the result. `cause` explains the rejection, and `result` is the signed payload.

{% hint style="info" %}
To undestand and handle the `cause` of the failure, see Liveness Error
{% endhint %}

### **`LivenessEvent.Error(error: CerttaError)`**

Triggered when a technical blocker prevents the SDK from starting or finishing the process, such as denied camera permissions, no internet connection, or hardware initialization failures.

| Event                 | Typical cause                                                                                                                       |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `initializationError` | **`configure`** not called, empty token or user ID, or invalid **`maxRetryAttempts`**.                                              |
| `permissionError`     | Camera (or related) permission denied.                                                                                              |
| `networkError`        | Connectivity or server-side issues surfaced as network class errors.                                                                |
| `securityError`       | Security checks failed.                                                                                                             |
| `unknownError`        | Other failures not mapped to a specific case.                                                                                       |
| `cancelled`           | Occurs when the user abandons the flow before completion, such as by pressing the back button or sending the app to the background. |


---

# 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/android/getting-started-with-the-sdk.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.
