# QI Tech — Risk Solutions › Facial Recognition

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
31 página(s).

Índice:
- Handling Responses (/en/documentation/caas/face_recognition/android/collecting_response)
- Introduction (/en/documentation/caas/face_recognition/android/introduction)
- Native Integration (/en/documentation/caas/face_recognition/android/native_java)
- Authentication (/en/documentation/caas/face_recognition/api/authentication)
- Face Registration (1:1) (/en/documentation/caas/face_recognition/api/face_registration)
- HTTP Status (/en/documentation/caas/face_recognition/api/http_status)
- Image (/en/documentation/caas/face_recognition/api/image)
- Introduction (/en/documentation/caas/face_recognition/api/introduction)
- Standards (/en/documentation/caas/face_recognition/api/standards)
- Collecting the Responses (/en/documentation/caas/face_recognition/flutter/collecting_response)
- Compatibility (/en/documentation/caas/face_recognition/flutter/compatibility)
- Implementation (/en/documentation/caas/face_recognition/flutter/example)
- The FaceReconOptions object (/en/documentation/caas/face_recognition/flutter/face_recon_options)
- Installation (/en/documentation/caas/face_recognition/flutter/installation)
- Introduction (/en/documentation/caas/face_recognition/flutter/introduction)
- Collecting SDK Returns (/en/documentation/caas/face_recognition/ios/collecting_response)
- QITechIosFaceRecognitionConfiguration (/en/documentation/caas/face_recognition/ios/configuration)
- Introduction (/en/documentation/caas/face_recognition/ios/introduction)
- Importing the SDK (/en/documentation/caas/face_recognition/ios/native_swift)
- Collecting the Responses (/en/documentation/caas/face_recognition/react_native/collecting_response)
- Compatibility (/en/documentation/caas/face_recognition/react_native/compatibility)
- Implementation (/en/documentation/caas/face_recognition/react_native/example)
- The FaceReconOptions object (/en/documentation/caas/face_recognition/react_native/face_recon_options)
- Installation (/en/documentation/caas/face_recognition/react_native/installation)
- Introduction (/en/documentation/caas/face_recognition/react_native/introduction)
- Collecting SDK Returns (/en/documentation/caas/face_recognition/web/collecting_response)
- Implementation (/en/documentation/caas/face_recognition/web/example)
- The QITechWebFaceRecon.WebFaceRecon() constructor (/en/documentation/caas/face_recognition/web/example_zaigwebfacerecon)
- Importing the library (/en/documentation/caas/face_recognition/web/import)
- Introduction (/en/documentation/caas/face_recognition/web/introduction)
- Face Registration and 1:1 Validation (/en/documentation/caas/face_recognition/web/registration_and_validation)

---

# Handling Responses

URL: /en/documentation/caas/face_recognition/android/collecting_response

To obtain the **FaceReconResponse** object, which contains the results of captures obtained by the SDK, including the identifiers of images sent to the QI Tech system, override the *onActivityResult* method in the same activity where you started **FaceReconActivity**:

```java
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            if (resultCode == RESULT_OK && data != null) {
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
                image_key = faceReconResponse.image_key;
                device_scan_session_id = faceReconResponse.device_scan_session_id;
                Log.i(TAG_LIVENESS, "FACE RECON RESPONSE: " + faceReconResponse.image_key);
            }
            else if (resultCode == RESULT_CANCELED && data != null) {
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
                Log.i(TAG_LIVENESS, "FACE RECON RESPONSE: " + faceReconResponse.status_code + " - " + faceReconResponse.reason + " - " + faceReconResponse.description);
            }
        }
    }
```

## Description of FaceReconResponse Object Attributes

:::info Warning: 
Device Scan Integration Starting from version 5.2.0, the Face Recognition service will automatically perform an internal call to Device Scan. With this, the success response will include the `device_scan_session_id` field. This key identifies the device scan session performed internally and can be used in an integrated manner in other QI Tech ecosystem services. 
:::

Attribute | Description | Result | Versions
--------- | --------- | --------- | ---------
image_key | Identification key of the provided image that can be used in any other QI Tech system service. | **RESULT_OK** | **All**
device_scan_session_id | Identification key of the device scan session performed internally that can be used in any other QI Tech system service. | **RESULT_OK** |  **5.2.0+**
status_code | Request status code. | **RESULT_CANCELED** | **5.0.0+**
reason | Error identifier | **RESULT_CANCELED** | **5.0.0+**
description | Error description. | **RESULT_CANCELED** | **5.0.0+**

## Error Structure (SDK 5.0.0+)

:::danger Important Warning! 
Starting from version **5.0.0**, the error structure has been reformulated to provide more detailed and diagnostic information.
:::

### Example: InvalidToken

```java
{
   status_code = 401
    reason = "INVALID_TOKEN"
    description = "Authentication token expired or invalid"
}
```
### Example: UserCanceled

```java
{
    status_code = 0
    reason = "USER_CANCELED"
    description = "User pressed the back button."
}
```

## Previous Versions

```java
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        FaceRecognition.RequestResponseObject result;
        if (requestCode == REQUEST_CODE){
            if (resultCode == RESULT_OK && data != null){
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
            }
        }
    }
```

---

# Introduction

URL: /en/documentation/caas/face_recognition/android/introduction

Welcome to QI Tech's Android Face Recognition SDK. This SDK performs face capture and sends it to the QI Tech Face Recognition API . You can use it to capture a customer's face image through your application and reference it by a key in other QI Tech system products.

## Problems?

We are not a company that hides behind an API! Contact our [support](mailto:suporte.caas@qitech.com.br) and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We Love Feedback

Even if you have already solved your problem or it is very simple (Even a typo or inadequate organization that you already understood), send us an email, so we make the documentation increasingly practical and the next person won't have to suffer the pains you suffered!

:::danger Important Warning!
Real data from individuals and/or legal entities should not be used in QI Tech's Sandbox environments.  
:::

---

# Native Integration

URL: /en/documentation/caas/face_recognition/android/native_java

To import our SDKs, it is necessary to make changes to the Project and Application _build.gradle_.

## Adding to Project

Add our maven repository address to the project's _build.gradle_ (in Android Studio this file appears as: **"Project: \{project_name\}"**), as shown in the example below.

```java
maven { url 'https://sdks.qitech.com.br/' }
```

## Adding to Application

After that, add the library you want to import to your app's build.gradle (in Android Studio this file appears as: **"Module: \{project_name\}.app"**), including the dependency shown below.

```java
dependencies {
    implementation 'com.qitech.android:facerecon:v7.1.0'
}
```

:::warning
Since **April 2025**, new Google Play policies require **Android API Level 35** for applications to be published
or updated on the Google Play Store. Therefore, we strongly recommend using **targetSdkVersion version 35** at least.
:::

:::info
Using **targetSdkVersion 35** implies using **compileSdkVersion 35**, which triggers some **minimum requirements** for tools
in the Android ecosystem:
* compileSdkVersion 35 --> AGP 8.6.0
* AGP 8.6.0 --> Gradle 8.7
* AGP 8.6.0 --> Java 17 (JDK 17)
* AGP 8.6.0 --> Kotlin 2+
:::

## Starting the SDK

:::danger Important Warning!
As of version 5.0.0, the authentication system was updated to use **clientSessionKey** instead of **mobileToken**. In addition, new configuration options were added for feedback screens.
:::

### Obtaining the Client Session Key

Before configuring the SDK, you must generate a temporary **clientSessionKey** through a server-to-server request to our face recognition API.

### Endpoint

| Environment | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Production** | `https://api.zaig.com.br/face_recognition/client_session` |

### Request

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Optional, but recommended):**
```json
{
  "user_id": "unique_user_identifier" // If available, use the user's CPF!
}
```

> **Important:** The `user_id` field is **highly recommended** for security and anti-fraud measures. Use a unique identifier for your application's user.

### Response

The successful response will contain the `client_session_key` that should be passed to the SDK configuration.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

To incorporate the SDK into your application, you must configure your custom capture application through a Builder component and submit it as a parameter via Intent Extra to FaceReconActivity.

### SDK initialization example
```java
  Intent intent = new Intent(getApplicationContext(), FaceReconActivity.class);

  var onboardingTextConfiguration = new OnboardingTextConfiguration(
        "Relevant tips",
        "Keep your face visible",
        "Fit your face in the oval",
        "Remove accessories that cover your face"
  );

  FaceRecognition mFaceRecognition = new FaceRecognition.Builder(clientSessionKey)
        .setSessionId("SESSION_ID")
        .setDocumentNumber("111.111.111-11")
        .setFontColor("#FFFFFF")
        .setBackgroundColor("#000000")
        .setFontFamily(FaceRecognition.FontFamily.futura)
        .showIntroductionScreens(true)
        .setShowSuccessScreen(true)
        .setShowInvalidTokenScreen(false)
        .setOnboardingTextConfiguration(onboardingTextConfiguration)
        .audioConfiguration(AudioConfiguration.enable)
        .setLogLevel(FaceRecognition.LogLevel.debug)
        .build();

  intent.putExtra("settings", mFaceRecognition);
  startActivityForResult(intent, REQUEST_CODE);
```

**Versions prior to v6.0.0**
```java
  Intent intent = new Intent(getApplicationContext(), FaceReconActivity.class);

  VisualConfiguration visualConfiguration = new VisualConfiguration()
          .setOnboardingDrawable(R.drawable.introscreen,500);

  TextConfiguration textConfiguration = new TextConfiguration()
          .setCustomText(TextConfiguration.CustomLabel.onboardingTitle, "To take a good photo:")
          .setCustomText(TextConfiguration.CustomLabel.onboardingFirstLabel, "- Go to a well-lit place")
          .setCustomText(TextConfiguration.CustomLabel.onboardingSecondLabel, "- Remove accessories and show your face clearly")
          .setCustomText(TextConfiguration.CustomLabel.onboardingThirdLabel, "- Insert your face into the frame, waiting for it to turn green to capture");

  FaceRecognition mFaceRecognition = new FaceRecognition.Builder(clientSessionKey)
          .showIntroductionScreens(true)
          .setVisualConfiguration(visualConfiguration)
          .setTextConfiguration(textConfiguration)
          .setBackgroundColor("#000000")
          .setFontColor("#FFFFFF")
          .setFontFamily(FaceRecognition.FontFamily.futura)
          .setSessionId("SESSION_ID")
          .setLogLevel(FaceRecognition.LogLevel.debug)
          .setShowSuccessScreen(false)
          .build();
  intent.putExtra("settings", mFaceRecognition);
  startActivityForResult(intent, REQUEST_CODE);
```

## FaceRecognition.Builder
| Parameter | Function | Required |
|------------|--------------|--------------|
|clientSessionKey |Client key that identifies that the collected data comes from your application. Obtained through a request to the Face Recognition API|Yes.|
|.setSandboxEnvironment()|If this parameter is used in the constructor, the library will be configured to send data to the sandbox environment. If absent, requests are sent to the production environment.|No.|
|.showIntroductionScreens(Boolean showIntroductionScreens)|When "false" disables the introduction screens for photo capture that appear to the user.|No. Default is "true".|
|.setShowSuccessScreen(Boolean showSuccessScreen)|When "false" disables the success screen after photo capture.|No. Default is "true".|
|.setShowInvalidTokenScreen(Boolean showSuccessScreen)|When "false" disables the authentication failure screen.|No. Default is "true".|
|.setBackgroundColor(String backgroundColor)|Allows configuration of the background color of the SDK activities.|No. Default is "#ffffff".|
|.setFontColor(String fontColor)|Allows configuration of the font and icon color of the SDK activities.|No. Default is "#000000".|
| .setFontFamily(FontFamily fontFamily)| Allows configuration of the font of the SDK activities.| No. If not specified, the default is FontFamily.open_sans. Available fonts: FontFamily.open_sans, FontFamily.futura, FontFamily.verdana, FontFamily.roboto, FontFamily.poppins and FontFamily.helvetica.|No.|
|.setOnboardingTextConfiguration(OnboardingTextConfiguration onboardingTextConfiguration) | Allows customization of the instructions on the introduction screen. | No. |
|.audioConfiguration(AudioConfiguration audioConfiguration)| Configures the SDK spoken voice guidance, which narrates the capture instructions in real time. Accepted configurations are _AudioConfiguration.enable_, which shows the audio on/off button with narration starting muted; _AudioConfiguration.disable_, which disables narration and hides the button; and _AudioConfiguration.accessibility_, which shows the button with narration starting enabled when the device has accessibility features active. With TalkBack active, the full instructions are delivered by the screen reader itself. |No. Default is _AudioConfiguration.disable_.|
|.setSessionId(String sessionId)| Used to define the key that identifies the session started in the SDK. It is used to track the entire flow taken by the user in the FaceRecon execution through logs. This field accepts up to 255 characters. |No.|
|.setLogLevel(FaceRecognition.LogLevel logLevel)| Used to customize the verbosity level of the SDK logs. Available levels: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error and LogLevel.trace. Default is LogLevel.debug. |No.|
|.setDocumentNumber(String documentNumber)| Used to define the user's document number. This field accepts 14 characters. | For identification used internally for anti-fraud and security. |

**Versions prior to v6.0.0**
| Parameter | Function | Required |
|------------|--------------|--------------|
|clientSessionKey |Client key that identifies that the collected data comes from your application. Obtained through a request to the Face Recognition API|Yes.|
|.setSandboxEnvironment()|If this parameter is used in the constructor, the library will be configured to send data to the sandbox environment. If absent, requests are sent to the production environment.|No.|
|.showIntroductionScreens(Boolean showIntroductionScreens)|When "false" disables the introduction screens for photo capture that appear to the user.|No. Default is "true".|
|.setShowSuccessScreen(Boolean showSuccessScreen)|When "false" disables the success screen after photo capture.|No. Default is "true".|
|.setShowInvalidTokenScreen(Boolean showSuccessScreen)|When "false" disables the authentication failure screen.|No. Default is "true".|
|.setBackgroundColor(String backgroundColor)|Allows configuration of the background color of the SDK activities.|No. Default is "#ffffff".|
|.setFontColor(String fontColor)|Allows configuration of the font and icon color of the SDK activities.|No. Default is "#000000".|
| .setFontFamily(FontFamily fontFamily)| Allows configuration of the font of the SDK activities.| No. If not specified, the default is FontFamily.open_sans. Available fonts: FontFamily.open_sans, FontFamily.futura, FontFamily.verdana, FontFamily.roboto, FontFamily.poppins and FontFamily.helvetica.|No.|
|.activeFaceLiveness(Boolean activeFaceLiveness)|Indicates whether the SDK should perform a user selfie capture procedure or active proof of life. |No. Default is *false*.|
|.audioConfiguration(AudioConfiguration audioConfiguration)| Configures the SDK spoken voice guidance, which narrates the capture instructions in real time. Accepted configurations are _AudioConfiguration.enable_, which shows the audio on/off button with narration starting muted; _AudioConfiguration.disable_, which disables narration and hides the button; and _AudioConfiguration.accessibility_, which shows the button with narration starting enabled when the device has accessibility features active. With TalkBack active, the full instructions are delivered by the screen reader itself. |No. Default is _AudioConfiguration.disable_.|
|.setVisualConfiguration(VisualConfiguration visualConfiguration)|Used to customize the images shown to the user throughout the SDK execution.|No.|
|.setTextConfiguration(TextConfiguration textConfiguration)|Used to customize the introductory onboarding screen texts shown to the user throughout the SDK execution.|No.|
|.setSessionId(String sessionId)| Used to define the key that identifies the session started in the SDK. It is used to track the entire flow taken by the user in the FaceRecon execution through logs. This field accepts up to 255 characters. |No.|
|.setLogLevel(FaceRecognition.LogLevel logLevel)| Used to customize the verbosity level of the SDK logs. Available levels: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error and LogLevel.trace. Default is LogLevel.debug. |No.|
|.setDocumentNumber(String documentNumber)| Used to define the user's document number. This field accepts 14 characters. |Only for calls that use 1:1 validation at some point. |
|.setValidation(Boolean validation)| Used to define whether the SDK should or should not perform 1:1 validation with the user's selfie. In the user's first session this flag must be, **mandatorily**, false. This function requires the setDocumentNumber method to be filled.  |No. Default is *false*.|

## The VisualConfiguration Object
:::warning
__DEPRECATED__ AS OF **v6.0.0**!
:::

| Parameter                                                             | Function                                                                                                                                                                                                                                        | Required             |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| .setOnboardingDrawable(int onboarding_drawable, int onboarding_width) | Used to configure the image shown to the user on the SDK onboarding screen. The _onboarding_drawable_ parameter should reference the id of the image to be shown and _onboarding_width_ is the desired display size of this image. | No.                    |
| .setButtonBorderSize(int border_size)                                 | Used to configure the border width of the SDK buttons.                                                                                                                                                                               | No. Default is _1_.    |
| .setButtonShadow(boolean button_shadow)                               | When set to _false_ removes the shadow effect, default on android, used by the SDK buttons.                                                                                                                                       | No. Default is _true_. |

## The TextConfiguration Object
:::warning
__DEPRECATED__ AS OF **v6.0.0**!
:::

| Parameter                                      | Function                                                                                    | Required |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------- |
| .setCustomText(CustomLabel label, String text) | Used to configure the texts shown to the user on the SDK onboarding screen | No.        |

---

# Authentication

URL: /en/documentation/caas/face_recognition/api/authentication

:::danger Important Warning!
Starting from version 5.0.0 of iOS and Android SDKs and version 3.0.0 of the Web SDK, the authentication system was updated to use clientSessionKey instead of mobileToken.
:::

We use an API Key to allow access to our API. It has probably already been sent to you by email. If you have not yet received your key, send an email to suporte.caas@qitech.com.br .

## Client Session Key

Before configuring the SDK, you must generate a temporary clientSessionKey through a server-to-server request to our API.

### Generate Client Session Key

```bash
curl -X POST "https://api.zaig.com.br/face_recognition/client_session" \
     -H "Authorization: EXAMPLE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{ "user_id": "unique_user_identifier" }'
```

**Endpoints**

| Environment | URL |
|----------|-----|
| Sandbox | https://api.sandbox.zaig.com.br/face_recognition/client_session |
| Production | https://api.zaig.com.br/face_recognition/client_session |

**Request Details**

| Field | Type | Required | Description|
|----------|----------|----------|----------|
| user_id | string | No | Unique identifier of your application's user (e.g.: CPF, RG, etc) |

The `user_id` field in the request body is highly recommended for security and anti-fraud measures.

**Request Body**
```json
{
  "user_id": "unique_user_identifier"
}
```

**Response Body**

The successful response will contain the `client_session_key`.
```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::info Attention
You must replace `EXAMPLE_API_KEY` with the API Key received from support.
:::

---

# Face Registration (1:1)

URL: /en/documentation/caas/face_recognition/api/face_registration

To perform **face registration** (for subsequent 1:1 validation), you must use the **specific endpoints** of the Face Recognition API described on this page.

## Available endpoints

Face registration resources are exposed at the following routes:

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/face_recognition/registration` | Creates a new face registration |
| GET | `/face_recognition/registration/{registration_key}` | Retrieves registration by key |
| GET | `/face_recognition/registration/document_number/{document_number}` | Retrieves registration by document number |

**Base URL (production):** `https://api.caas.qitech.app`  
**Base URL (sandbox):** `https://api.sandbox.caas.qitech.app`

---

## Creating a registration (POST)

To register a client's face, send a **POST** request to:

`https://api.caas.qitech.app/face_recognition/registration`

The request body must contain the **document number** and the face image in one of the two formats below.

### Option 1: image via `image_key` (from the SDK)

Use the **image_key** returned by the SDK after face capture.

Request Body – image_key

```json
{
    "document_number": "DOCUMENT_NUMBER",
    "image_key": "<IMAGE_KEY_FROM_SDK>"
}
```

### Option 2: image as Base64

Send the image directly as Base64 (no headers or additional metadata).

Request Body – image (Base64)

```json
{
    "document_number": "DOCUMENT_NUMBER",
    "image": "<IMAGE_BASE64>"
}
```

### Request fields

name | type | description
:----: | :----: | ---------
document_number | string | Client's document number (e.g. CPF)
image_key | string | Image key returned by the SDK (UUID). Use **either** `image_key` **or** `image`
image | string | Face image in Base64. Use **either** `image` **or** `image_key`

:::info
You must send **only one** of the image fields: `image_key` **or** `image`. Do not send both in the same request.
:::

On success, the API returns only the face registration key:

Response Body

```json
{
    "registration_key": "face_registration_key"
}
```

---

## Retrieving registration by key (GET)

To get the registration key by its unique key:

`https://api.caas.qitech.app/face_recognition/registration/{registration_key}`

Replace `{registration_key}` with the identifier returned when creating the registration.

**Response Body:**

```json
{
    "registration_key": "face_registration_key"
}
```

---

## Retrieving registration by document (GET)

To get the registration key by document number:

`https://api.caas.qitech.app/face_recognition/registration/document_number/{document_number}`

Replace `{document_number}` with the client's document number (e.g. CPF).

**Response Body:**

```json
{
    "registration_key": "face_registration_key"
}
```

---

---

# HTTP Status

URL: /en/documentation/caas/face_recognition/api/http_status

All QI Tech APIs use the following standardization in HTTP return statuses, according to RFC 7231 :

HTTP Status | Meaning | Description
---------- | ------- | ---------------------------------
400 | Bad Request | The request sent has some formatting error. In most cases, we return in the message body an explanation of where the error is.
401 | Unauthorized | There was a problem with authentication, check if the API Key is correct and in the correct header, according to the Authentication section.
403 | Forbidden | The accessed endpoint is for internal use and is not available for this API Key.
404 | Not Found | The requested data was not found using the key used. This status is also returned when an invalid endpoint is requested.
405 | Method Not Allowed | The HTTP method used does not apply to the endpoint used.
406 | Not Acceptable | The data sent in the request body is invalid. In general, this means that the data sent is not valid JSON.
409 | Conflict | The request id corresponds to an id already processed previously. This status is returned in case of duplicate requests sent to the server.
500 | Internal Server Error | We had a problem processing this request, when we encounter this error our specialists are automatically notified and start analysis and resolution immediately.
503 | Service Unavailable | You encountered a planned or unplanned unavailability of our server infrastructure.

---

# Image

URL: /en/documentation/caas/face_recognition/api/image

Sending a face photo is mandatory for using our facial recognition API. To ensure greater reliability of the analyses performed, it is necessary for the client to follow some rules when taking the photo:

* The photo must contain only one face;
* The entire face must be visible in the photo;
* The face must occupy at least 15% of the photo area;
* The face must be facing the camera and parallel to it;
* The face must have open eyes;
* The face must have a closed mouth;
* The face must have a neutral expression and no smiles;
* The face must not be covered by any type of accessory (hats, glasses or masks).

In addition, only .jpeg and .png images with a maximum size of 3MB will be accepted.

## File submission

Request Body

```json
{
    "image": "base64_image_code"
}
```

Response Body

```json
{ 
    "image_key": "f4b5337a-7b50-406e-8c8e-7d0e77b5aa02",
    "file_size": 47407,
    "width_px": 0,
    "height_px": 0,
    "created_at": "2020-07-29T18:40:57Z"
}
```

In cases where it is necessary to send an image without immediately executing facial registration or validation routines, a JSON object containing the image Base64 must be sent. 
For this, a **POST** request must be sent to the endpoint:

`https://api.caas.qitech.app/face_recognition/image`

Once sent, the image will be submitted to quality tests and, if approved, a JSON containing the image access key will be returned. This key should be used to reference the photo during registration or facial validation.

:::info **Attention**

Only the Base64 code corresponding to the image should be sent.
:::

## Image quality validation

Response Body: Invalid image case

```json
{
    "title": "image_quality",
    "description": "This image was not approved in quality assessment. The face is too close to image edges.",
    "image_status": "not_center"
}
```

When making a POST to the image endpoint, if the image is not sufficient for validation, an HTTP Status Code 400 will be returned.

The value of the *description* field is the message that explains why the image is invalid.

In addition, we return an enumerator *image_status* so that the reason why the image is invalid can be mapped. Below we have the listing of possible *image_status*:

image_status |  description
:----: | :---------:
no_faces | No face identified.
multiple_faces | More than one face identified.
close_face | Face too close to camera.
distant_face | Face too far from camera.
not_centered | Face is not centered enough.
inclined_face | Face is inclined.
wearing_acessories | Person is using accessories that cover part of the face.
facial_expression | The person has an open mouth, is smiling or has closed eyes.
brightness_problem | The image does not have adequate lighting.
sharpness_problem | The image is not sharp enough.

**Attention -** There are other reasons why we will return 400 (All related to invalid data). Only returns with title "image_quality" are the result of image quality validation and therefore should be passed on to the user.

## File recovery
> Image recovery

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02/file" \
         -H "Authorization: EXAMPLE_API_KEY"
```

At any time it is possible to recover the sent images. For this, simply send a properly authenticated **GET** request to the endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}/file`

Where image_key is the value returned during image submission.

## Processed file recovery
> Processed image recovery

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02/cropped_file" \
         -H "Authorization: EXAMPLE_API_KEY"
```
After associating an image with a registration or validation, that image will be processed and a new image containing only the face used in facial recognition routines will be generated.

This image is available to be recovered through a properly authenticated **GET** request to the endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}/cropped_file`

Where image_key is the value returned during base image submission.

## File metadata recovery
> Metadata recovery

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02" \
         -H "Authorization: EXAMPLE_API_KEY"
```

After sending an image to the API, it is possible to recover the image metadata using the endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}`

Where image_key is the value returned during image submission.

---

# Introduction

URL: /en/documentation/caas/face_recognition/api/introduction

Welcome to QI Tech's Facial Recognition API! You can use our API to access endpoints, register customer photos and perform facial recognition before executing transactions.

## Problems?

We are not a company that hides behind an API! Contact our support and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We Love Feedback

Even if you have already solved your problem or it is very simple (Even a typo or inadequate organization that you already understood), send us an email, so we make the documentation increasingly practical and the next person won't need to suffer the pains you suffered!

## Environments

We have two environments for our clients. The base URLs of the APIs are:

* Production - `https://api.caas.qitech.app/face_recognition/`
* Sandbox - `https://api.sandbox.caas.qitech.app/face_recognition/`

:::danger Important Warning!
Real data from individuals and/or legal entities should not be used in QI Tech's Sandbox environments.  
:::

## HTTPS Only

For security reasons, all communication with QI Tech APIs must be performed using HTTPS communication. To prevent HTTP calls from being made due to inattention or other reasons, this server only provides port 443 with TLS 1.2 communication. Calls made using other protocols will be automatically denied.

---

# Standards

URL: /en/documentation/caas/face_recognition/api/standards

To facilitate integration and ensure information integrity, some standards have been defined that are followed throughout the API.

## Date and Time with Time Zone
> Some examples:

```
2019-10-15T22:35:12-03:00
2018-05-01T13:32:11+00:00
2019-05-01T00:00:00+00:00
```

It is represented according to ISO 8601. In this case, the time zone is placed right after the time and must represent the time zone of the location where that data will be valid. For example, if a rental is scheduled to start at 09:30 at Brasília airport, the sent time should be represented by 09:30-03:00, if the rental is scheduled to start at 09:30 in Manaus, it should be represented by 09:30-04:00.

The mask used for validation is as follows:

`YYYY-MM-ddThh:mm:ss±hh:mm`

## Date and Time without Time Zone
> Some examples:

```
2019-10-15T22:35:12Z
2018-05-01T13:32:11Z
2019-05-01T00:00:00Z
```

It is represented according to ISO 8601. Data that is independent of time zone should be sent without it, always in UTC, with the letter Z indicating that this data is in UTC. The following format, therefore, will be validated:

`YYYY-MM-ddThh:mm:ssZ`

## Date
> Some examples

``` 
2019-10-15
2019-01-01
2017-03-20
```

In the case of fields that receive only date, a birth date, for example, only the date, without any time, should be sent in the following format:

`YYYY-MM-dd`
 

## Documents
Since document numbers are quite varied and many of them have characters that do not fit as numeric, all document numbers are defined as string. Another good reason to define them as string is to prevent leading zeros from disappearing. Documents provided for on this page have a well-defined mask and will be subject to validation. The rest of the documents, such as RG, given their lack of standardization, will not be validated.

## CPF

> Examples of valid CPFs against the defined mask:

```
123.456.789-12
321.987.543-23
111.283.333-00
```

> Examples of invalid CPFs against the defined mask:

```
8.577.477-8
08.104.627/0001-23
123.456.789-1
23.456.789-01
```

CPF is always defined as a string and will be validated against the mask:

`###.###.###-##`

---

# Collecting the Responses

URL: /en/documentation/caas/face_recognition/flutter/collecting_response

The `startFaceRecon` method returns a `Future `. No manual JSON decoding is needed — the plugin already delivers typed Dart objects.

## FaceReconReturnValues

```dart
class FaceReconReturnValues {
  final String imageKey;
  final String deviceScanSessionId;
}
```

| Attribute | Type | Description |
|----------|------|-----------|
|imageKey|String|Identification key of the provided image, which can be used in any other service of the QI Tech system. **Important:** store this value to send in the validation APIs (e.g. the Onboarding API).|
|deviceScanSessionId|String|Identification key of the device scan session performed internally by the Face Recognition SDK, which can be used in any other service of the QI Tech system.|

## FaceReconException

On failure, the method throws a typed `FaceReconException`:

```dart
class FaceReconException implements Exception {
  final int? statusCode;
  final String reason;
  final String description;
}
```

| Attribute | Type | Description |
|----------|------|-----------|
|statusCode|int?|HTTP status code of the error.|
|reason|String|Identifier of the error reason.|
|description|String|Detailed description of the error.|

### Most common errors

| reason | statusCode | description |
|--------|-----------|-------------|
|`INVALID_TOKEN`|401|`Authentication token expired or invalid` — the `clientSessionKey` is invalid or has expired.|
|`USER_CANCELED`|0|`User canceled FaceRecon.` — the user interrupted the flow before completing it.|

## Handling example

```dart
try {
  final result = await plugin.startFaceRecon(
    CaaSEnvironment.sandbox,
    clientSessionKey,
  );

  print('Image key: ${result.imageKey}');
  print('Device Scan Session Id: ${result.deviceScanSessionId}');
} on FaceReconException catch (e) {
  print('Error executing FaceRecon:');
  print('Status: ${e.statusCode}');
  print('Reason: ${e.reason}');
  print('Description: ${e.description}');
} catch (e) {
  print('An unknown error occurred: $e');
}
```

---

# Compatibility

URL: /en/documentation/caas/face_recognition/flutter/compatibility

The `flutter_kyc_qitech` plugin requires the following minimum versions:

| Setting | Minimum version |
|------------|--------------|
|Flutter|3.3.0|
|Dart SDK|3.2.3|
|iOS|15.5|
|Android API Level|35 (Android 15 Vanilla Ice Cream)|
|Gradle|8.6.0|
|Android Gradle Plugin (AGP)|8.7|
|Kotlin|2.0.21 (recommended)|
|Native Datadog SDK (iOS, brought in by the plugin)|3.x|
|MLKit FaceDetection (iOS, if already used in your app)|8.x|

## Current plugin version

| Plugin | Version |
|--------|--------|
|`flutter_kyc_qitech`|`^5.3.0`|

:::warning Warning
Our iOS SDKs do not support being built for simulators on **arm64** architecture machines (M1/M2/M3/M4 MacBooks) unless **Rosetta** is active, translating the x86_64 architecture to arm64. We recommend using physical devices for testing.
:::

---

# Implementation

URL: /en/documentation/caas/face_recognition/flutter/example

The `startFaceRecon` method opens the native liveness flow, sends the captured image to QI Tech's Face Recognition API and returns the key of the processed image.

## Prerequisite: obtaining the Client Session Key

The `startFaceRecon` method requires a `clientSessionKey`. This key is temporary and must be generated on your backend through a server-to-server request to our API, before calling the SDK method.

### Endpoint

| Environment | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Production** | `https://api.zaig.com.br/face_recognition/client_session` |

### Request

**Method:** `POST`

**Headers:**

```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (optional, but recommended):**

```json
{
  "user_id": "unique_user_identifier"
}
```

> **Important:** The `user_id` field is **highly recommended** for security and anti-fraud measures. Use the customer's CPF if you have access to this information.

### Response

The successful response contains the `client_session_key` that must be passed to the `startFaceRecon` method.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::danger Important Note!
The Face Recognition API key must never be embedded in the application. The request above must come exclusively from your backend.
:::

## Method signature

```dart
Future<FaceReconReturnValues> startFaceRecon(
  CaaSEnvironment environment,
  String clientSessionKey, {
  FaceReconOptions? options,
})
```

The first two parameters are positional and required. Customizations are optional and passed through the named `options` parameter, described in [The FaceReconOptions object](/documentation/caas/face_recognition/flutter/face_recon_options).

## Complete example

```dart
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter_kyc_qitech/flutter_kyc_qitech.dart';

final _qitechFlutterKycPlugin = FlutterKycQitech();

// Step 1: obtain the clientSessionKey through your backend
Future<String?> fetchClientSessionKey() async {
  final response = await http.post(
    Uri.parse('<FACE_RECON_API_URL>'),
    headers: {
      HttpHeaders.authorizationHeader: '<API_KEY>',
      HttpHeaders.contentTypeHeader: 'application/json',
    },
    body: jsonEncode({'user_id': '<USER_IDENTIFICATION>'}),
  );

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    return data['client_session_key'] as String?;
  }
  return null;
}

// Step 2: start the SDK with the obtained key
Future<void> startFaceRecon() async {
  final clientSessionKey = await fetchClientSessionKey();

  if (clientSessionKey == null) {
    print('Failed to fetch clientSessionKey');
    return;
  }

  try {
    final result = await _qitechFlutterKycPlugin.startFaceRecon(
      CaaSEnvironment.sandbox,
      clientSessionKey,
      options: FaceReconOptions(
        sessionId: '<SESSION_ID>',
        documentNumber: '111.111.111-11',
        fontColor: '#FFFFFF',
        backgroundColor: '#000000',
        fontFamily: CaaSFontFamily.futura,
        showIntroductionScreens: true,
        showSuccessScreen: true,
        showInvalidTokenScreen: true,
        audioConfiguration: FaceReconAudioConfiguration.enable,
        onboardingTextConfiguration: OnboardingTextConfiguration(
          onboardingTitle: 'Important tips',
          onboardingFirstLabel: 'Make sure your face is visible',
          onboardingSecondLabel: 'Fit your face in the oval',
          onboardingThirdLabel: 'Remove accessories that cover your face',
        ),
        logLevel: CaaSLogLevel.debug,
      ),
    );

    print('Image key: ${result.imageKey}');
    print('Device Scan Session Id: ${result.deviceScanSessionId}');
  } on FaceReconException catch (e) {
    print('Error executing FaceRecon:');
    print('Status: ${e.statusCode}');
    print('Reason: ${e.reason}');
    print('Description: ${e.description}');
  }
}
```

:::info **Warning**
Enable support for the _Portrait_ and _Landscape Right_ orientations in your application for the native iOS SDK to work correctly.
:::

## Sample app

The plugin repository contains a ready-to-run sample app, under `flutter_kyc_qitech/example`, demonstrating the use of all three SDKs. To run it, create a `.env` file in the `example` folder with the credentials below, then run `flutter pub get` followed by `flutter run` with a physical device connected:

```
FACERECON_API_URL_SANDBOX=''
FACERECON_API_KEY_SANDBOX=''
OCR_MOBILE_TOKEN_SANDBOX=''
DEVICE_SCAN_API_URL_SANDBOX=''
DEVICE_SCAN_API_KEY_SANDBOX=''
```

If you have not received your credentials yet, contact suporte.caas@qitech.com.br .

---

# The FaceReconOptions object

URL: /en/documentation/caas/face_recognition/flutter/face_recon_options

## startFaceRecon parameters

| Parameter | Type | Purpose | Required |
|------------|--------------|--------------|--------------|
|environment|CaaSEnvironment|Enum used to set the execution environment to `sandbox` or `production`.|Yes.|
|clientSessionKey|String|Temporary authentication key obtained through a server-to-server request to the Face Recognition API. See [Implementation](/documentation/caas/face_recognition/flutter/example).|Yes.|
|options|FaceReconOptions?|Optional object with the SDK's visual, textual and behavioral customizations.|No.|

## FaceReconOptions

All fields are optional. When a field is not provided, the native SDK applies its default value.

| Parameter | Type | Purpose | Default |
|------------|--------------|--------------|--------------|
|sessionId|String?|Key identifying the session started in the SDK. It is used to trace the entire flow taken by the user through logs. Accepts up to 255 characters.|Generated internally.|
|documentNumber|String?|The user's document number (CPF), used exclusively for anti-fraud identification.|Not sent.|
|fontColor|String?|Font and icon color of the SDK screens, in hexadecimal format (e.g. `"#FFFFFF"`).|`"#000000"`|
|backgroundColor|String?|Background color of the SDK screens, in hexadecimal format (e.g. `"#000000"`).|`"#FFFFFF"`|
|fontFamily|CaaSFontFamily?|Font used on the SDK screens.|`CaaSFontFamily.openSans`|
|showIntroductionScreens|bool?|When `false`, disables the introduction screens shown before the liveness proof.|`true`|
|showSuccessScreen|bool?|When `false`, disables the success screen shown after the capture.|`true`|
|showInvalidTokenScreen|bool?|When `false`, disables the screen shown when the `clientSessionKey` is invalid or has expired.|`true`|
|audioConfiguration|FaceReconAudioConfiguration?|Configures the spoken voice guidance, which narrates the capture instructions in real time.|`FaceReconAudioConfiguration.disable`|
|onboardingTextConfiguration|OnboardingTextConfiguration?|Customizes the onboarding screen texts.|SDK default texts.|
|logLevel|CaaSLogLevel?|Verbosity level of the SDK logs.|`CaaSLogLevel.debug`|

:::info **Warning**
From plugin version **5.0.0** onwards, the `documentNumber` field no longer triggers face registration — it is used solely for anti-fraud identification.
:::

## OnboardingTextConfiguration

| Parameter | Type | Purpose |
|------------|--------------|--------------|
|onboardingTitle|String?|Onboarding screen title.|
|onboardingFirstLabel|String?|First instruction shown to the user.|
|onboardingSecondLabel|String?|Second instruction shown to the user.|
|onboardingThirdLabel|String?|Third instruction shown to the user.|

```dart
OnboardingTextConfiguration(
  onboardingTitle: 'Important tips',
  onboardingFirstLabel: 'Make sure your face is visible',
  onboardingSecondLabel: 'Fit your face in the oval',
  onboardingThirdLabel: 'Remove accessories that cover your face',
)
```

## Enums

### CaaSEnvironment

```dart
enum CaaSEnvironment {
  production,
  sandbox,
}
```

### CaaSFontFamily

```dart
enum CaaSFontFamily {
  jakarta,       // iOS only
  futura,        // iOS and Android
  verdana,       // iOS and Android
  trebuchetMs,   // iOS only
  tamilsangamMn, // iOS only
  openSans,      // iOS and Android
  helvetica,     // Android only
  poppins,       // Android only
  roboto,        // Android only
  systemFont,    // iOS only
}
```

:::info **Warning**
Font availability varies by platform. If an unsupported font is passed, the platform's default font is used. For cross-platform consistency, use `futura`, `verdana` or `openSans`.
:::

### FaceReconAudioConfiguration

```dart
enum FaceReconAudioConfiguration {
  enable,        // shows the audio toggle, with narration starting off
  disable,       // disables narration and hides the toggle
  accessibility, // shows the toggle with narration starting on when accessibility features are active
}
```

### CaaSLogLevel

```dart
enum CaaSLogLevel {
  trace,
  debug,
  log,
  info,
  warn,
  error,
}
```

---

# Installation

URL: /en/documentation/caas/face_recognition/flutter/installation

## Installing the plugin

Run the command below at the root of your Flutter project:

```bash
flutter pub add flutter_kyc_qitech
```

The command installs the latest version and adds the dependency to your `pubspec.yaml`:

```yaml
dependencies:
  flutter_kyc_qitech: ^5.3.0
```

Then fetch the dependencies:

```bash
flutter pub get
```

## Import

```dart
import 'package:flutter_kyc_qitech/flutter_kyc_qitech.dart';
```

And instantiate the plugin:

```dart
final _qitechFlutterKycPlugin = FlutterKycQitech();
```

## Android setup

### 1. QI Tech Maven repository

Add the reference to QI Tech's Android repository in your project's `build.gradle`:

```gradle
allprojects {
    repositories {
        maven { url 'https://sdks.qitech.com.br/' }
        ...
    }
}
```

### 2. AdMob

Initialize the AdMob service by adding the following code to your `AndroidManifest.xml`:

```xml
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="<ADMOB_APP_ID>"/>
```

If you do not have an `ADMOB_APP_ID`, contact suporte.caas@qitech.com.br .

## iOS setup

### 1. Camera permission

Add an `NSCameraUsageDescription` entry to your app's `Info.plist`, with the reason why your app requires camera access:

```xml
<key>NSCameraUsageDescription</key>
<string>We need the camera to capture your selfie</string>
```

### 2. QI Tech iOS repository source

Add the following sources at the top of your `Podfile`:

```ruby
source 'https://cdn.cocoapods.org/'
source 'https://github.com/QITechSDKs/iOS.git'
```

### 3. Static frameworks

By default, CocoaPods builds static libraries rather than frameworks. Add the following to your `Podfile`:

```ruby
use_frameworks! :linkage => :static
```

### 4. Module stability

QI Tech's native dependencies require `BUILD_LIBRARY_FOR_DISTRIBUTION` to be enabled for the Datadog targets. Add the `post_install` block below (or merge it into your existing `post_install`):

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'NO'
      # The line below is only required to build on simulators (with Rosetta active)
      config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
    end
    if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
        config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
      end
    end
  end
end
```

### 5. Installing the pods

In your Flutter app's `ios` directory, run:

```bash
cd ios
pod install
```

or, alternatively, through Flutter:

```bash
flutter build ios
```

:::warning Warning
If your app already uses **Datadog**, use the latest version within major `3.x` (`datadog_flutter_plugin` 3.x). If it uses **MLKit's FaceDetection**, use the latest version within major `8.x`.
:::

---

# Introduction

URL: /en/documentation/caas/face_recognition/flutter/introduction

Welcome to the QI Tech Face Recognition SDK integration manual for Flutter! The `flutter_kyc_qitech` plugin exposes QI Tech's native Android (Kotlin) and iOS (Swift) SDKs through a Dart interface. You should use it to run your customer's liveness proof directly from your Flutter application and reference the captured image, through a key, in the other products of the QI Tech system.

:::info **A single plugin for all three SDKs**

`flutter_kyc_qitech` delivers the three Risk Solutions SDKs in the same package: `startFaceRecon` (face recognition), `startOcr` (OCR) and `startDeviceScan` (device scan). Once installed, all three methods are available — no additional plugins are required.
:::

## Having issues?

We are not a company that hides behind an API! Contact our [support](mailto:suporte.caas@qitech.com.br) and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We love feedback

Even if you have already solved your problem or if it is very simple (even a typo or poor organization that you already understood), send us an email—this way we make the documentation more and more practical and the next person won't have to suffer the pains you suffered!

## Environments

We have two environments for our customers. The selection is made through the `CaaSEnvironment` enum, passed as the first parameter of the `startFaceRecon` method. At the moment, the following environments are available:

* Production - `CaaSEnvironment.production`
* Sandbox - `CaaSEnvironment.sandbox`

Each environment requires a different API key to generate the `clientSessionKey`.

:::danger Important Note!
Do not use real personal or corporate data in QI Tech's Sandbox environments.
:::

## Device Scan integration

The Face Recognition service automatically makes an internal call to Device Scan. Because of that, the success response includes the `deviceScanSessionId` field, which identifies the device scan session performed internally and can be used in an integrated way in other services of the QI Tech ecosystem.

## Next steps

1. [Compatibility](/documentation/caas/face_recognition/flutter/compatibility) — minimum Flutter, Dart, iOS and Android versions.
2. [Installation](/documentation/caas/face_recognition/flutter/installation) — plugin installation and native Android and iOS setup.
3. [Implementation](/documentation/caas/face_recognition/flutter/example) — obtaining the `clientSessionKey` and a complete `startFaceRecon` example.
4. [The FaceReconOptions object](/documentation/caas/face_recognition/flutter/face_recon_options) — every customization parameter.
5. [Collecting the Responses](/documentation/caas/face_recognition/flutter/collecting_response) — response structure and error handling.

---

# Collecting SDK Returns

URL: /en/documentation/caas/face_recognition/ios/collecting_response

To obtain SDK responses, you must implement the **QITechIosFaceRecognitionControllerDelegate** delegate in your controller, as shown in the example on the side.

```swift
class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {
    
    // Do something if QI Tech FaceRecognition's SDK succesfully collected document picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults response: QITechIosFaceRecognitionControllerResponse) {
    
    }
    
    // Do something if QI Tech FaceRecognition's SDK found any error when collecting document picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {
        
    }
    
    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

## QITechIosFaceRecognitionControllerResponse

The **QITechIosFaceRecognitionControllerResponse** class is used so you can receive the response from QI Tech's SDK.

In the table below you will find the details of all properties of this class:

### Properties

:::info Warning: 
Device Scan Integration Starting from version 6.1.0, the Face Recognition service will automatically perform an internal call to Device Scan. With this, the success response will include the `DeviceScanSessionId` field. This key identifies the device scan session performed internally and can be used in an integrated manner in other QI Tech ecosystem services. 
:::

| Name | Type | Description |
|------|------|-----------|
| `FaceRecognitionKey` | `String` | Unique identifier of the face photo stored in QI Tech. **Important:** Store this value to send in validation APIs (e.g.: Onboarding API). |
| `DeviceScanSessionId` | `String` | Unique identifier of the device scan session performed internally. |

## QITechIosFaceRecognitionControllerError

The **QITechIosFaceRecognitionControllerError** class is triggered when an error occurs that leads to SDK termination.

:::danger Important Warning! 
Starting from version **5.0.0**, the error structure has been reformulated to provide more detailed and diagnostic information.
:::
#### Main changes:

1. **New error types**: `InvalidToken` (replaces `InvalidMobileToken`)
2. **New available properties**:
   - `status_code`: HTTP error code
   - `reason`: Error reason identifier
   - `description`: Detailed error description

### Error Structure (SDK 5.0.0+)

#### Example: InvalidToken

```swift
{
    status_code: 401,
    reason: "INVALID_TOKEN",
    description: "Authentication token expired or invalid"
}
```

## Error Types

### SDK 5.0.0 and later

| Error | Status Code | Description |
|------|-------------|-----------|
| `InvalidToken` | 401 | Authentication token expired or invalid (replaces `InvalidMobileToken`) |

### Versions prior to 5.0.0

| Error Class | Description |
|----------------|-----------|
| `InvalidMobileToken` | MobileToken sent in configurations is invalid *(replaced by `InvalidToken` in v5.0.0+)* |
| `MissingPermission` | One of the necessary permissions was not granted |
| `NetworkFailure` | Loss of internet connection during validation |
| `ServerFailure` | Error response from QI Tech server |
| `MissingStorage` | Insufficient storage space |
| `LowImageQuality` | Image quality insufficient for validation |

---

# QITechIosFaceRecognitionConfiguration

URL: /en/documentation/caas/face_recognition/ios/configuration

## SDK 7.0.0 and later
```swift
let onboardingTextConfiguration = OnboardingTextConfiguration(
        onboardingTitle: "Relevant tips",
        onboardingFirstLabel: "Keep your face visible",
        onboardingSecondlabel: "Fit your face in the oval",
        onboardingThirdLabel: "Remove accessories that cover your face"
)

let faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(
        environment: QITechIosFaceRecognitionEnvironment.sandbox,
        clientSessionKey: clientSessionKey,
        sessionId: "7d8c6f9a-f222-450d-9501-a07c68eb2388",
        documentNumber: "123.456.789-00",
        fontColor: "#337DFF",
        backgroundColor: "#C9CCD3",
        fontFamily: .open_sans,
        showIntroductionScreens: true,
        showSuccessScreen: true,
        showInvalidTokenScreen: false,
        audioConfiguration: AudioConfiguration.enable,
        onboardingTextConfiguration: onboardingTextConfiguration,
        logLevel: .debug
)
```

**Versions prior to v7.0.0**
```swift
let visualConfiguration = VisualConfiguration()
        visualConfiguration.setOnboarding(onboardingFilePath: Bundle.main.path(forResource: "onboarding", ofType: "png")!, onboardingWidth: 200)

let textConfiguration = TextConfiguration()
        textConfiguration.setCustomText(on: .onboardingTitle, text: "To take a good photo:")
        textConfiguration.setCustomText(on: .onboardingFirstLabel, text: "- Go to a well-lit place")
        textConfiguration.setCustomText(on: .onboardingSecondLabel, text: "- Remove accessories and show your face clearly")
        textConfiguration.setCustomText(on: .onboardingThirdLabel, text: "- Insert your face into the frame, waiting for it to turn green to capture")

let faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(environment: QITechIosFaceRecognitionEnvironment.Sandbox,
                                            clientSessionKey: clientSessionKey,
                                            sessionId: "7d8c6f9a-f222-450d-9501-a07c68eb2388",
                                            backgroundColor: "#C9CCD3",
                                            fontColor: "#337DFF",
                                            fontFamily: .open_sans,
                                            showIntroductionScreens: true,
                                            showSuccessScreen: false,
                                            showInvalidTokenScreen: true,
                                            activeFaceLiveness: true,
                                            audioConfiguration: AudioConfiguration.Enable,
                                            logLevel: .debug
                                            )

faceRecognitionConfig.setVisualConfiguration(visualConfiguration: visualConfiguration)
faceRecognitionConfig.setTextConfiguration(textConfiguration: textConfiguration)
```

The **QITechIosFaceRecognitionConfiguration** class is used so you can configure environment, credentials, visual and textual aspects, that is, all the necessary configurations for SDK personalization and operation.

In the table below you will find the details of all arguments that should be used in its instantiation:

| name                    |               type                | description                                                                                                                                                                                                                                                                                                                                   |
| ----------------------- | :-------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| environment             | QITechIosFaceRecognitionEnvironment | _(required)_ Enumerator that describes the environment.                                                                                                                                                                                                                                                                                         |
| clientSessionKey        |              string               | _(required)_ Token sent by the face recognition API for SDK authentication.                                                                                                                                                                                                                                                                        |
| sessionId               |              string               | _(optional)_ Unique ID used to track the entire flow taken by the user in FaceRecon execution through logs. This field accepts up to 255 characters.                                                                                                                                                                                |
| documentNumber          |              string               | _(optional)_ Used for user identification for anti-fraud and internal security |
| fontColor               |              string               | _(optional)_ Hexadecimal of the font color. If not specified, the default is #1C49A5.                                                                                                                                                                                                                                                       |
| backgroundColor         |              string               | _(optional)_ Hexadecimal of the screen background color. If not specified, the default is #FCFCFC.                                                                                                                                                                                                                                             |
| fontFamily              |            FontFamily             | _(optional)_ Font family. If not specified, the default is .open_sans. Available fonts: .open_sans, .futura, .verdana, .trebuchetms, .tamilsangammn and .system_font.                                                                                                                                                               |
| showIntroductionScreens |             boolean              | _(optional)_ Flag that indicates whether the introduction screens, with instructions on how the photo should be captured, should be shown. If not specified, the default is _true_.                                                                                                                                                                   |
| showSuccessScreen       |             boolean              | _(optional)_ Flag that indicates whether the success screen, with the success message on capture, should be shown. If not specified, the default is _true_.                                                                                                                                                                                      |
| showInvalidTokenScreen  |             boolean              | _(optional)_ Flag that indicates whether the authentication failure screen, with the token expiration message, should be shown. If not specified, the default is _true_. |
| audioConfiguration      |        AudioConfiguration         | _(optional)_ Configures the SDK spoken voice guidance, which narrates the capture instructions in real time. Accepted configurations are: _Enable_, which shows the audio on/off button with narration starting muted; _Disable_, which disables narration and hides the button; and _Accessibility_, which shows the button with narration starting enabled when the device has accessibility features active. With VoiceOver active, the full instructions are delivered by the screen reader itself. |
| onboardingTextConfiguration | OnboardingTextConfiguration | _(optional)_ Allows configuring the instruction screen texts |
| logLevel                |             LogLevel              | _(optional)_ Used to customize the verbosity level of the SDK logs. Available levels: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error and LogLevel.trace. If not specified, the default is LogLevel.debug. |

In the table below you will find all methods accepted by the instance for configuration:
:::warning
__DEPRECATED__ AS OF **v7.0.0**!
:::

| method                 |                                                                                                                     arguments                                                                                                                     | description                                                                                     |
| ---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------- |
| setVisualConfiguration |                                                                 visualConfiguration : VisualConfiguration                                                             | _(optional)_ Class that allows modification of images displayed during SDK execution; |
| setTextConfiguration   |                                                                                                       textConfiguration : TextConfiguration                                                                                                        | _(optional)_ Class that allows modification of texts displayed during SDK execution;  |
| setDocumentNumber      |                                                    Used to define the user's document number. This field accepts 14 characters of CPF formatted as follows 000.000.000-00                                                    | Yes in all calls if using 1:1 validation at some point.                                                                                         |
| setValidation          | Used to define whether the SDK should or should not perform 1:1 validation with the user's selfie. In the user's first session this flag must be **mandatorily false**. This function requires the setDocumentNumber method to be filled. | No. Default is _false_.                                                                      |

---

# Introduction

URL: /en/documentation/caas/face_recognition/ios/introduction

Welcome to QI Tech's iOS Face Recognition SDK. This SDK performs face capture and sends it to the QI Tech Face Recognition API . You can use it to capture a customer's face image through your application and reference it by a key in other QI Tech system products.

## Problems?

We are not a company that hides behind an API! Contact our [support](mailto:suporte.caas@qitech.com.br) and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We Love Feedback

Even if you have already solved your problem or it is very simple (Even a typo or inadequate organization that you already understood), send us an email, so we make the documentation increasingly practical and the next person won't have to suffer the pains you suffered!

:::danger Important Warning!
Real data from individuals and/or legal entities should not be used in QI Tech's Sandbox environments.  
:::

---

# Importing the SDK

URL: /en/documentation/caas/face_recognition/ios/native_swift

## Remotely

> Starting the installation

```shell
  pod init
```

Our SDK can be imported using CocoaPods.

| SDK              | Current version                         |
| ---------------- | ------------------------------------ |
| QITechIosFaceRecon | `pod 'QITechIosFaceRecon', '~> 8.2.0'` |

:::info iOS Minimum Deployment Target
15.5
:::

:::danger Using simulators on MacBooks with arm64 chip
Currently, our FaceRecon SDK for iOS unfortunately does not support being compiled for simulators running
on a MacBook with **arm64 architecture chip** (M1/M2/M3/M4), **unless Rosetta is used**, which translates
the x86_64 architecture to arm64.
:::

To start the installation, run the command on the side in your project's root folder.

> Adding the source to podfile

```ruby
   source 'https://github.com/QITechSDKs/iOS.git'
   source 'https://cdn.cocoapods.org/'
```

The next step is to add the QI Tech source to the `podfile` file.

> Adding the pod to podfile

```ruby
  pod 'QITechIosFaceRecon', '~> <version>'
```

Finally, just add the `pod` name according to the format on the side.

:::danger Attention: 
Architecture Change (v6.0.0+) Starting from version 6.0.0, the SDK is distributed exclusively in static form. In your Podfile, you must use the :linkage => :static configuration. 
:::

> Podfile example (Version 6.0.0 or higher)

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  source 'https://cdn.cocoapods.org/'
  target 'ExampleApp' do
    use_frameworks! :linkage => :static
    pod 'QITechIosFaceRecon', '~> 8.2.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

> Podfile example (Previous Versions) 

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  source 'https://cdn.cocoapods.org/'
  target 'ExampleApp' do
    use_frameworks!
    pod 'QITechIosFaceRecon', '~> 5.0.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

:::warning Attention
When integrating dependencies on iOS, the need may arise to use static linking for some libraries and dynamic for others. This configuration is relevant to ensure compatibility, avoid build errors and optimize project performance. 
:::

### Hybrid Dependency Linking (if necessary)
The need for hybrid linking arises because some libraries have specific requirements, with some needing static linking to avoid internal conflicts and symbol duplication, and other dependencies may need dynamic linking, as they are designed for modularity and sharing between projects.

Differences Between Static and Dynamic Linking
* Static (static_framework): The library code is directly incorporated into the final binary, reducing runtime load time and eliminating external dependencies during execution.
* Dynamic (dynamic_framework): The library is loaded at runtime as a separate file. This reduces the final binary size and facilitates independent updates/modifications.

> Configuring hybrid linking in Podfile

```ruby
...

use_frameworks! :linkage => :dynamic # CONFIGURING THE DEFAULT LINKING MODE TO DYNAMIC

...

static_frameworks = ['framework_1', 'framework_2', ...] # INCLUDE ALL DEPENDENCIES THAT NEED TO BE LINKED STATICALLY
pre_install do |installer|
  installer.pod_targets.each do |pod|
    if static_frameworks.include?(pod.name)
      def pod.static_framework?;
        true
      end
      def pod.build_type;
        Pod::BuildType.static_framework
      end
    end
  end
end
```

> Installing dependencies

```shell
  pod install
```

Finally, run the `pod install` command to download and install the dependencies.

## Necessary Permissions

For the SDK to access device resources to collect the user's selfie, it is necessary to request permissions from the user.

In the **info.plist** file, add the permissions below:

| Permission                          | Reason                                             |
| ---------------------------------- | -------------------------------------------------- |
| Privacy - Camera Usage Description | Access to the camera to capture the user's selfie. |

## Starting the SDK

:::danger Important Warning!
Starting from version 5.0.0, the authentication system has been updated to use **clientSessionKey** instead of **mobileToken**. In addition, new configuration options have been added for feedback screens.
:::

### Obtaining the Client Session Key

Before configuring the SDK, you must generate a temporary **clientSessionKey** through a server-to-server request to our face recognition API.

### Endpoint

| Environment | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Production** | `https://api.zaig.com.br/face_recognition/client_session` |

### Request

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Optional, but recommended):**
```json
{
  "user_id": "unique_user_identifier"
}
```

> **Important:** The `user_id` field is **highly recommended** for security and anti-fraud measures. Use a unique identifier for your application's user.

### Response

The successful response will contain the `client_session_key` that should be passed to the SDK configuration.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

### SDK initialization example

```swift

import QITechIosFaceRecognition

class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {

    var qitechFaceRecognitionConfiguration : QITechIosFaceRecognitionConfiguration?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupFaceRecognition()
    }

    func setupFaceRecognition() -> Void {
      let clientSessionKey = try await fetchClientSessionKey()
                    
      let onboardingTextConfiguration = OnboardingTextConfiguration(
          onboardingTitle: "Relevant tips",                          // Title
          onboardingFirstLabel: "Keep your face visible",            // First instruction
          onboardingSecondlabel: "Fit your face in the oval",        // Second instruction
          onboardingThirdLabel: "Remove accessories that cover your face" // Third instruction
      )

      self.faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(
          environment: QITechIosFaceRecognitionEnvironment.sandbox,
          clientSessionKey: clientSessionKey,
          sessionId: "test_session_id",
          documentNumber: "123.456.789-00",
          fontColor: "#AB9FF2",
          backgroundColor: "#FFFDF8",
          fontFamily: .futura,
          showIntroductionScreens: true,
          showSuccessScreen: true,
          showInvalidTokenScreen: false,
          audioConfiguration: AudioConfiguration.enable,
          onboardingTextConfiguration: onboardingTextConfiguration,
          logLevel: .debug 
      )
    }

    // Event where you intend to call QI Tech FaceRecognition View Controller - on this example, when the user press 'next' button

    @IBAction func pressNext(_ sender: Any) {
        let qitechFaceRecognitionController = QITechIosFaceRecognitionController(faceRecognitionConfiguration: self.faceRecognitionConfig)
        qitechFaceRecognitionViewController.delegate = self
        let qitechFaceRecognitionViewController =  qitechFaceRecognitionController.getViewController()
        present(qitechFaceRecognitionViewController, animated: true, completion: nil)
    }

    // Do something if QI Tech FaceRecognition's SDK successfully collected picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults results: QITechIosFaceRecognitionControllerResponse) {

    }

    // Do something if QI Tech FaceRecognition's SDK found any error when collecting  picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {

    }

    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

**Versions prior to v7.0.0**
```swift

import QITechIosFaceRecognition

class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {

    var qitechFaceRecognitionConfiguration : QITechIosFaceRecognitionConfiguration?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupFaceRecognition()
    }

    func setupFaceRecognition() -> Void {
        // The environment can be 'Sandbox' or 'Production'
        let environment = QITechIosFaceRecognitionEnvironment.Sandbox

        // ClientSessionKey is the key you got via Face Recognition request. Each environment requires a different API_KEY.
        let clientSessionKey = fetchClientSessionKey()

        self.faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(environment: environment,
                                            clientSessionKey: clientSessionKey,
                                            sessionId: "UNIQUE_SESSION_ID",
                                            backgroundColor: "#000000",
                                            fontColor: "#FFFFFF",
                                            fontFamily: .open_sans,
                                            showIntroductionScreens: true,
                                            showSuccessScreen: false,
                                            showInvalidTokenScreen: true,
                                            activeFaceLiveness: true,
                                            audioConfiguration: AudioConfiguration.Enable,
                                            logLevel: .debug
                                            )
    }

    // Event where you intend to call QI Tech FaceRecognition View Controller - on this example, when the user press 'next' button

    @IBAction func pressNext(_ sender: Any) {
        let qitechFaceRecognitionController = QITechIosFaceRecognitionController(faceRecognitionConfiguration: self.faceRecognitionConfig)
        qitechFaceRecognitionViewController.delegate = self
        let qitechFaceRecognitionViewController =  qitechFaceRecognitionController.getViewController()
        present(qitechFaceRecognitionViewController, animated: true, completion: nil)
    }

    // Do something if QI Tech FaceRecognition's SDK successfully collected picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults results: QITechIosFaceRecognitionControllerResponse) {

    }

    // Do something if QI Tech FaceRecognition's SDK found any error when collecting  picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {

    }

    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

To incorporate the SDK into your application, you must configure your custom capture application through the **QITechIosFaceRecognitionConfiguration** class and then instantiate the **ViewController QITechIosFaceRecognitionController** passing the custom configurations as an argument.

To start the face analysis process, simply call the _present_ function to call the QI Tech ViewController that will perform the selfie capture.

It is important to implement the _Delegate_ responsible for receiving returns in case of success, error or if the user interrupts the journey at any stage of validation.

Above we have a complete implementation example.

---

# Collecting the Responses

URL: /en/documentation/caas/face_recognition/react_native/collecting_response

The `startFaceRecon` function returns a _Promise_ that resolves with an already-typed object — unlike `startOcr`, there is no need to call `JSON.parse()`.

## Promise resolution

```typescript
type FACE_RECON_RETURN_VALUES = {
  image_key: string;
  device_scan_session_id: string;
};
```

| Attribute | Type | Description |
|----------|------|-----------|
|image_key|string|Identification key of the provided image, which can be used in any other service of the QI Tech system. **Important:** store this value to send in the validation APIs (e.g. the Onboarding API).|
|device_scan_session_id|string|Identification key of the device scan session performed internally by the Face Recognition SDK, which can be used in any other service of the QI Tech system.|

```json
{
  "image_key": "5d0f0e1c-8f9e-4b6c-9c3d-2f8a1b4e7c10",
  "device_scan_session_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
```

## Promise rejection

On failure, the _Promise_ is rejected with an object of type `FACE_RECON_ERROR`:

```typescript
type FACE_RECON_ERROR = {
  status_code: number;
  reason: string;
  description: string;
};
```

| Attribute | Type | Description |
|----------|------|-----------|
|status_code|number|HTTP status code of the error.|
|reason|string|Identifier of the error reason.|
|description|string|Detailed description of the error.|

### Most common errors

| reason | status_code | description |
|--------|-------------|-------------|
|`INVALID_TOKEN`|401|`Authentication token expired or invalid` — the `client_session_key` is invalid or has expired.|
|`USER_CANCELED`|0|`User canceled FaceRecon.` — the user interrupted the flow before completing it.|

## Handling example

```tsx
startFaceRecon(CAAS_ENVIRONMENT.SANDBOX, clientSessionKey)
  .then((response) => {
    console.log('Image Key: ', response.image_key);
    console.log('Device Scan Session Id: ', response.device_scan_session_id);
  })
  .catch((error) => {
    // Optional: type assertion (cast) to FACE_RECON_ERROR.
    // Recommended to ensure type safety in TypeScript.
    const reconError = error as FACE_RECON_ERROR;

    console.error('Status:', reconError.status_code);
    console.error('Reason:', reconError.reason);
    console.error('Description:', reconError.description);
  });
```

---

# Compatibility

URL: /en/documentation/caas/face_recognition/react_native/compatibility

The `@qitech/react-native-caas` module requires the following minimum versions:

| Setting | Minimum version |
|------------|--------------|
|React Native|0.74|
|React|18.2.0|
|iOS|15.5|
|Android API Level|35 (Android 15)|
|Native Datadog SDK (iOS, brought in by the module)|3.x|
|MLKit FaceDetection (iOS, if already used in your app)|8.x|

## Current package version

| Package | Version |
|--------|--------|
|`@qitech/react-native-caas`|`11.3.0`|
|`@qitech/react-native-device-scan`|`1.2.0`|

:::warning Warning
Our iOS SDKs only support simulators on **arm64** architecture machines (M1/M2/M3/M4) with **Rosetta** active, translating the x86_64 architecture. We recommend using physical devices for testing.
:::

## Expo

The package includes an Expo _config plugin_ that automatically applies the native iOS and Android setup. See [Installation](/documentation/caas/face_recognition/react_native/installation).

:::info **Warning**
The module does not work in the _Expo managed workflow_ without `prebuild` — you must generate the native projects with `npx expo prebuild`.
:::

---

# Implementation

URL: /en/documentation/caas/face_recognition/react_native/example

The `startFaceRecon` function opens the native liveness flow, sends the captured image to QI Tech's Face Recognition API and returns the key of the processed image.

## Prerequisite: obtaining the Client Session Key

The `startFaceRecon` function requires a `client_session_key`. This key is temporary and must be generated on your backend through a server-to-server request to our API, before calling the SDK function.

### Endpoint

| Environment | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Production** | `https://api.zaig.com.br/face_recognition/client_session` |

### Request

**Method:** `POST`

**Headers:**

```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (optional, but recommended):**

```json
{
  "user_id": "unique_user_identifier"
}
```

> **Important:** The `user_id` field is **highly recommended** for security and anti-fraud measures. Use the customer's CPF if you have access to this information.

### Response

The successful response contains the `client_session_key` that must be passed to the `startFaceRecon` function.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::danger Important Note!
The Face Recognition API key must never be embedded in the application. The request above must come exclusively from your backend.
:::

## Function signature

```javascript
const result = await startFaceRecon(
  environment,         // CAAS_ENVIRONMENT
  client_session_key,  // string
  options              // FaceReconOptions (optional)
);
```

Customizations are optional and passed through the `options` object, described in [The FaceReconOptions object](/documentation/caas/face_recognition/react_native/face_recon_options).

## Complete example

```tsx
import * as React from 'react';
import { useCallback } from 'react';
import { View, Button } from 'react-native';
import {
  CAAS_ENVIRONMENT,
  CAAS_FONT_FAMILY,
  CAAS_LOG_LEVEL,
  FACE_RECON_AUDIO_CONFIGURATION,
  FACE_RECON_ERROR,
  startFaceRecon,
} from '@qitech/react-native-caas';

const FACE_RECON_API_URL = 'https://api.sandbox.zaig.com.br/face_recognition/client_session';
const FACE_RECON_API_KEY = '<FACE_RECON_API_KEY>';

const config = {
  environment: CAAS_ENVIRONMENT.SANDBOX,
  sessionId: '<SESSION_ID>',
  documentNumber: '111.111.111-11',
  fontColor: '#5dcfe3',
  backgroundColor: '#f5f3f0',
  fontFamily: CAAS_FONT_FAMILY.VERDANA,
  showIntroductionScreens: true,
  showSuccessScreen: true,
  showInvalidTokenScreen: true,
  logLevel: CAAS_LOG_LEVEL.DEBUG,
};

export default function App() {
  // Step 1: obtain the client_session_key through your backend
  const fetchClientSessionKey = useCallback(async () => {
    const response = await fetch(FACE_RECON_API_URL, {
      method: 'POST',
      headers: {
        'Authorization': FACE_RECON_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ user_id: '<USER_IDENTIFICATION>' }),
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    const data = await response.json();

    if (!data.client_session_key) {
      throw new Error("No 'client_session_key' found.");
    }

    return data.client_session_key;
  }, []);

  // Step 2: start the SDK with the obtained key
  const startFr = async () => {
    const clientSessionKey = await fetchClientSessionKey();

    startFaceRecon(config.environment, clientSessionKey, {
      session_id: config.sessionId,
      document_number: config.documentNumber,
      font_color: config.fontColor,
      background_color: config.backgroundColor,
      font_family: config.fontFamily,
      show_introduction_screens: config.showIntroductionScreens,
      show_success_screen: config.showSuccessScreen,
      show_invalid_token_screen: config.showInvalidTokenScreen,
      audio_configuration: FACE_RECON_AUDIO_CONFIGURATION.ENABLE,
      onboarding_text_configuration: {
        onboarding_title: 'Important tips',
        onboarding_first_label: 'Make sure your face is visible',
        onboarding_second_label: 'Fit your face in the oval',
        onboarding_third_label: 'Remove accessories that cover your face',
      },
      log_level: config.logLevel,
    })
      .then((response) => {
        // image_key identifies the image at QI Tech — store it and send it to the Onboarding API
        console.log('Face Recon successfully ended. Image Key: ', response.image_key);
        // device_scan_session_id identifies the internal Device Scan call
        console.log('Device Scan Session Id: ', response.device_scan_session_id);
      })
      .catch((error) => {
        const reconError = error as FACE_RECON_ERROR;

        console.error('Error executing FaceRecon:');
        console.error('Status:', reconError.status_code);
        console.error('Reason:', reconError.reason);
        console.error('Description:', reconError.description);
      });
  };

  return (
    <View>
      <Button title="Start FaceRecon" onPress={startFr} />
    </View>
  );
}
```

## Sample apps

The module repository contains two ready-to-run apps, in the `examples` folder:

* **QITechReactNativeExample** — pure React Native
* **QITechExpoExample** — Expo

In both, `App.tsx` demonstrates the full usage (Face Recognition + OCR + Device Scan) with `@qitech/react-native-caas`. Replace the sample tokens and API keys with your credentials. If you have not received them yet, contact suporte.caas@qitech.com.br .

---

# The FaceReconOptions object

URL: /en/documentation/caas/face_recognition/react_native/face_recon_options

## startFaceRecon parameters

| Parameter | Type | Purpose | Required |
|------------|--------------|--------------|--------------|
|environment|CAAS_ENVIRONMENT|Enum used to set the execution environment to `SANDBOX` or `PRODUCTION`.|Yes.|
|client_session_key|string|Temporary authentication key obtained through a server-to-server request to the Face Recognition API. See [Implementation](/documentation/caas/face_recognition/react_native/example).|Yes.|
|options|FaceReconOptions|Optional object with the SDK's visual, textual and behavioral customizations.|No.|

## FaceReconOptions

All fields are optional. When a field is not provided, the native SDK applies its default value.

```typescript
type FaceReconOptions = {
  session_id?: string;
  document_number?: string;
  font_color?: string;
  background_color?: string;
  font_family?: CAAS_FONT_FAMILY;
  show_introduction_screens?: boolean;
  show_success_screen?: boolean;
  show_invalid_token_screen?: boolean;
  audio_configuration?: FACE_RECON_AUDIO_CONFIGURATION;
  onboarding_text_configuration?: OnboardingTextConfiguration;
  log_level?: CAAS_LOG_LEVEL;
};
```

| Parameter | Type | Purpose | Default |
|------------|--------------|--------------|--------------|
|session_id|string|Key identifying the session started in the SDK. It is used to trace the entire flow taken by the user through logs. Accepts up to 255 characters.|Generated internally.|
|document_number|string|The user's document number (CPF), used exclusively for anti-fraud identification.|Not sent.|
|font_color|string|Font and icon color of the SDK screens, in hexadecimal format (e.g. `"#FFFFFF"`).|`"#000000"`|
|background_color|string|Background color of the SDK screens, in hexadecimal format (e.g. `"#000000"`).|`"#FFFFFF"`|
|font_family|CAAS_FONT_FAMILY|Font used on the SDK screens.|`CAAS_FONT_FAMILY.OPEN_SANS`|
|show_introduction_screens|boolean|When `false`, disables the introduction screens shown before the liveness proof.|`true`|
|show_success_screen|boolean|When `false`, disables the success screen shown after the capture.|`true`|
|show_invalid_token_screen|boolean|When `false`, disables the screen shown when the `client_session_key` is invalid or has expired.|`true`|
|audio_configuration|FACE_RECON_AUDIO_CONFIGURATION|Configures the spoken voice guidance, which narrates the capture instructions in real time.|`FACE_RECON_AUDIO_CONFIGURATION.DISABLE`|
|onboarding_text_configuration|OnboardingTextConfiguration|Customizes the onboarding screen texts.|SDK default texts.|
|log_level|CAAS_LOG_LEVEL|Verbosity level of the SDK logs.|`CAAS_LOG_LEVEL.DEBUG`|

:::info **Warning**
The `document_number` field does not trigger face registration — it is used solely for anti-fraud identification.
:::

## OnboardingTextConfiguration

```typescript
type OnboardingTextConfiguration = {
  onboarding_title?: string;
  onboarding_first_label?: string;
  onboarding_second_label?: string;
  onboarding_third_label?: string;
};
```

| Parameter | Type | Purpose |
|------------|--------------|--------------|
|onboarding_title|string|Onboarding screen title.|
|onboarding_first_label|string|First instruction shown to the user.|
|onboarding_second_label|string|Second instruction shown to the user.|
|onboarding_third_label|string|Third instruction shown to the user.|

## Enums

### CAAS_ENVIRONMENT

```typescript
enum CAAS_ENVIRONMENT {
  PRODUCTION = 'production',
  SANDBOX = 'sandbox',
}
```

### CAAS_FONT_FAMILY

```typescript
enum CAAS_FONT_FAMILY {
  JAKARTA = 'jakarta',                // iOS only
  FUTURA = 'futura',                  // iOS and Android
  VERDANA = 'verdana',                // iOS and Android
  TREBUCHET_MS = 'trebuchetms',       // iOS only
  TAMILSANGAM_MN = 'tamilsangammn',   // iOS only
  OPEN_SANS = 'open_sans',            // iOS and Android
  HELVETICA = 'helvetica',            // Android only
  POPPINS = 'poppins',                // Android only
  ROBOTO = 'roboto',                  // Android only
  SYSTEM_FONT = 'system_font',        // iOS only
}
```

:::info **Warning**
Font availability varies by platform. If an unsupported font is passed, the platform's default font is used. For cross-platform consistency, use `FUTURA`, `VERDANA` or `OPEN_SANS`.
:::

### FACE_RECON_AUDIO_CONFIGURATION

```typescript
enum FACE_RECON_AUDIO_CONFIGURATION {
  ENABLE = 'enable',               // shows the audio toggle, with narration starting off
  DISABLE = 'disable',             // disables narration and hides the toggle
  ACCESSIBILITY = 'accessibility', // shows the toggle with narration starting on when accessibility features are active
}
```

### CAAS_LOG_LEVEL

```typescript
enum CAAS_LOG_LEVEL {
  TRACE = 'trace',
  DEBUG = 'debug',
  LOG = 'log',
  INFO = 'info',
  WARN = 'warn',
  ERROR = 'error',
}
```

---

# Installation

URL: /en/documentation/caas/face_recognition/react_native/installation

## Installing the package

### 1. Configuring the npm registry

Create an `.npmrc` file at the root of your project:

```sh
@qitech:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=NPM_TOKEN_SENT_BY_QI_TECH
```

Replace `NPM_TOKEN_SENT_BY_QI_TECH` with the token provided by support. If you have not received your token yet, contact suporte.caas@qitech.com.br .

### 2. Installing the dependency

```sh
yarn add @qitech/react-native-caas
```

### 3. Import

```javascript
import {
  CAAS_ENVIRONMENT,
  CAAS_FONT_FAMILY,
  CAAS_LOG_LEVEL,
  FACE_RECON_AUDIO_CONFIGURATION,
  FACE_RECON_ERROR,
  startFaceRecon,
} from '@qitech/react-native-caas';
```

## Android setup

### 1. QI Tech Maven repository

Add QI Tech's Maven repository to your project-level `build.gradle`:

```groovy
allprojects {
  repositories {
    maven { url 'https://sdks.qitech.com.br/' }
    ...
  }
}
```

### 2. AdMob

Initialize the AdMob service by adding the following code to your `AndroidManifest.xml`:

```xml
<meta-data
  android:name="com.google.android.gms.ads.APPLICATION_ID"
  android:value="<ADMOB_APP_ID>"/>
```

If you do not have an `ADMOB_APP_ID`, contact suporte.caas@qitech.com.br .

## iOS setup

### 1. Camera permission

Add an `NSCameraUsageDescription` entry to your app's `Info.plist`, with the reason why your app requires camera access:

```xml
<key>NSCameraUsageDescription</key>
<string>We need the camera to capture your selfie</string>
```

### 2. QI Tech iOS repository source

Add the following sources at the top of your `Podfile`:

```ruby
source 'https://cdn.cocoapods.org/'
source 'https://github.com/QITechSDKs/iOS.git'
```

### 3. Static frameworks

Required **only** if you use Xcode **older than version 26**:

```ruby
use_frameworks! :linkage => :static
```

:::warning Warning
[Flipper](https://fbflipper.com/docs/getting-started/react-native/) does not work with `use_frameworks!`. Remove the `use_flipper()` call from your `Podfile` if it is present.
:::

### 4. Module stability

The Datadog dependencies require `BUILD_LIBRARY_FOR_DISTRIBUTION` to be enabled. Add the `post_install` block below (or merge it into your existing `post_install`):

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
        config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
      end
    end
  end
end
```

### 5. Installing the pods

```sh
cd ios && pod install
```

:::warning Warning
If your app already uses **Datadog**, use the latest version within major `3.x`. If it uses **MLKit's FaceDetection**, use the latest version within major `8.x`.
:::

## Expo setup

The package includes an Expo _config plugin_ that automatically applies all the native iOS and Android setup described above. In your `app.json`:

```json
{
  "expo": {
    "plugins": ["@qitech/react-native-caas"]
  }
}
```

Then run `prebuild` to apply the native changes:

```sh
npx expo prebuild
```

---

# Introduction

URL: /en/documentation/caas/face_recognition/react_native/introduction

Welcome to the QI Tech Face Recognition SDK integration manual for React Native! The `@qitech/react-native-caas` module exposes QI Tech's native Android (Java/Kotlin) and iOS (Swift) SDKs through a TypeScript interface. You should use it to run your customer's liveness proof directly from your React Native application and reference the captured image, through a key, in the other products of the QI Tech system.

## Available packages

| Package | Contents | When to use |
|--------|----------|-------------|
|`@qitech/react-native-caas`|Face Recognition, OCR and Device Scan|When you need face recognition, OCR or the full onboarding flow.|
|`@qitech/react-native-device-scan`|Device Scan only|When you need **only** device scan — a lighter installation with fewer native dependencies.|

:::danger Important Note!
Both packages include Device Scan. **Do not install both** — choose only one.
:::

For Face Recognition, use `@qitech/react-native-caas`.

## Having issues?

We are not a company that hides behind an API! Contact our [support](mailto:suporte.caas@qitech.com.br) and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We love feedback

Even if you have already solved your problem or if it is very simple (even a typo or poor organization that you already understood), send us an email—this way we make the documentation more and more practical and the next person won't have to suffer the pains you suffered!

## Environments

We have two environments for our customers. The selection is made through the `CAAS_ENVIRONMENT` enum, passed as the first parameter of the `startFaceRecon` function. At the moment, the following environments are available:

* Production - `CAAS_ENVIRONMENT.PRODUCTION`
* Sandbox - `CAAS_ENVIRONMENT.SANDBOX`

Each environment requires a different API key to generate the `client_session_key`.

:::danger Important Note!
Do not use real personal or corporate data in QI Tech's Sandbox environments.
:::

## Device Scan integration

The Face Recognition service automatically makes an internal call to Device Scan. Because of that, the success response includes the `device_scan_session_id` field, which identifies the device scan session performed internally and can be used in an integrated way in other services of the QI Tech ecosystem.

## Next steps

1. [Compatibility](/documentation/caas/face_recognition/react_native/compatibility) — minimum React Native, iOS and Android versions.
2. [Installation](/documentation/caas/face_recognition/react_native/installation) — package installation and native Android, iOS and Expo setup.
3. [Implementation](/documentation/caas/face_recognition/react_native/example) — obtaining the `client_session_key` and a complete `startFaceRecon` example.
4. [The FaceReconOptions object](/documentation/caas/face_recognition/react_native/face_recon_options) — every customization parameter.
5. [Collecting the Responses](/documentation/caas/face_recognition/react_native/collecting_response) — response structure and error handling.

---

# Collecting SDK Returns

URL: /en/documentation/caas/face_recognition/web/collecting_response

## The .initialize() method

The `.initialize()` method is responsible for initializing the facial recognition and liveness proof component. Upon execution, the SDK loads the face detection model and validates device/browser conditions.

**Promise resolution:**

```javascript
{
  status: "SUCCESS",
  data: null
}
```

**Rejection Scenarios:**

- **Unsupported Browser:**

```javascript
{
  status: "FAILURE",
  reason: "UNSUPPORTED_BROWSER",
  description: "User browser is not supported."
}
```

- **Not Mobile Device:**

```javascript
{
  status: "FAILURE",
  reason: "NOT_MOBILE_DEVICE",
  description: "User device is not mobile."
}
```

- **Initialization Error:**

```javascript
{
  status: "FAILURE",
  reason: "INITIALIZATION_ERROR",
  description: "..."
}
```

## The .open() method

This method receives the `clientSessionKey` (obtained via server-to-server call) and starts the interaction with the user to collect the liveness proof. It returns a _Promise_ resolved with the captured image key once the flow is complete.

**Promise resolution:**

```javascript
{
  status: "SUCCESS",
  data: string // image_key that identifies the image on the server
}
```

Example:

```javascript
{
  status: "SUCCESS",
  data: "d8a3b1c4-9e2f-47a5-8c3d-1b2e5..."
}
```

**Promise rejection:**

```javascript
{
  status: string;
  reason: string;
  description: string;
}
```

**Rejection Scenarios:**

- **User Canceled:**

```javascript
{
  status: "FAILURE",
  reason: "USER_CANCELED",
  description: "User pressed the back button."
}
```

- **Invalid Token:** (occurs when the `clientSessionKey` is invalid or expired)

```javascript
{
  status: "FAILURE",
  reason: "INVALID_TOKEN",
  description: "Authentication token expired or invalid"
}
```

- **Session Superseded:** (occurs when `.open()` is called again on an already open instance)

```javascript
{
  status: "FAILURE",
  reason: "SESSION_SUPERSEDED",
  description: "A new session has been started before the previous one was completed."
}
```

---

# Implementation

URL: /en/documentation/caas/face_recognition/web/example

:::info New in version 4.0.0
Starting from version **4.0.0**, the `WebFaceRecon` constructor no longer receives `hostComponent` — the SDK manages its own DOM node. The `client_session_key` remains required and must be passed to the `.open()` method.
:::

The implementation is done by instantiating `QITechWebFaceRecon.WebFaceRecon()`, chaining configuration options and calling `.build()`. Initialization happens in `.initialize()`, and liveness capture is started with `.open(clientSessionKey)`.

## Obtaining the Client Session Key

Before calling `.open()`, you must generate a temporary **clientSessionKey** via a server-to-server request to our face recognition API.

### Endpoint

| Environment | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Production** | `https://api.zaig.com.br/face_recognition/client_session` |

### Request

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Optional, but recommended):**
```json
{
  "user_id": "unique_user_identifier"
}
```

> **Important:** The `user_id` field is **highly recommended** for security and anti-fraud measures. Use a unique identifier for your application's user.

### Response

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

## Complete example

```html
<script src="https://facerecon.caas.qitech.app/face-recognition-4-2-1.js"></script>

<script>
  async function startFaceRecognition() {
    // 1. Obtain the clientSessionKey via server-to-server call
    const clientSessionKey = await fetchClientSessionKey();

    // 2. Configure and instantiate the SDK
    const webFaceRecon = new QITechWebFaceRecon.WebFaceRecon()
      .setThemeConfiguration({
        primaryColor:  "#2848A8",
        tertiaryColor: "#57D9FF",
        fontFamily:    "Verdana"
      })
      .setSandboxEnvironment()
      .setSessionId("UNIQUE_SESSION_ID")
      .build();

    // 3. Initialize (validates browser/device and loads model)
    await webFaceRecon.initialize();

    // 4. Start liveness capture
    const response = await webFaceRecon.open(clientSessionKey);
    console.log(`Status: ${response.status}, Key: ${response.data}`);
  }
</script>
```

## Previous versions

:::danger Important Warning!
Versions prior to **4.0.0** receive the `hostComponent` as the first constructor argument. Starting from **3.0.0**, the `web_token` was removed from the constructor and the `client_session_key` flow was introduced.
:::

```html
<script>
  // Versions 3.x
  var hostComponent = document.getElementById('webfacerecon');
  var webFaceRecon = new QITechWebFaceRecon.WebFaceRecon(hostComponent)
    .setThemeConfiguration({
      "buttonColor": "#2848A8",
      "fontColor": "#FFFFFF",
      "backgroundColor": "#FFFFFF"
    })
    .setSandboxEnvironment()
    .setSessionId('UNIQUE_SESSION_ID')
    .build();

  webFaceRecon.initialize()
    .then(() => fetchClientSessionKey())
    .then(clientSessionKey => webFaceRecon.open(clientSessionKey))
    .then(response => console.log(`Status: ${response.status}, Key: ${response.data}`))
    .catch(error => {
      console.error(error);
      alert(error.reason || error);
    });
</script>
```

---

# The QITechWebFaceRecon.WebFaceRecon() constructor

URL: /en/documentation/caas/face_recognition/web/example_zaigwebfacerecon

The `.WebFaceRecon()` method is responsible for configuring the instance of your facial recognition component. Starting from version **4.0.0**, the constructor takes no parameters — rendering is managed internally by the SDK. Use the chained methods below to customize its behavior:

| Name | Description | Required |
|----------|----------|----------|
| `.setSandboxEnvironment()` | Configures the environment to Sandbox mode. | No |
| `.setShowInvalidTokenScreen(Boolean)` | Defines whether the authentication failure screen should be displayed. Default: `false`. | No |
| `.setShowBackButton(Boolean)` | Defines whether the back button should be displayed (when pressed, ends the flow). Default: `true`. | No |
| `.setSessionId(String)` | Defines the key that identifies the session started in the SDK — used to track the user's flow through logs. Accepts up to 255 characters. | No |
| `.setThemeConfiguration(object)` | Customizes the visual identity of the SDK. | No |
| `.setLogLevel(String)` | Verbosity level of logs. Options: `"info"`, `"debug"`, `"warn"`, `"error"`. Default: `"info"`. | No |
| `.setCameraNotAllowedErrorDescription(String)` | Custom message displayed when the user denies camera permission. | No |

The `.setThemeConfiguration` method must receive an object with the following fields:

| Name | Type | Description |
| -------- | -------- | -------- |
| primaryColor | String | Hexadecimal of the SDK's primary color (background, header). Default: `#285BB8`. |
| tertiaryColor | String | Hexadecimal of the action button color. Default: `#57D9FF`. |
| fontFamily | String | _Font Family_ to be applied to SDK text. If not provided, the system default font will be used. |

## Previous Versions

:::danger Important Warning!
Starting from version **4.0.0**, the `hostComponent` parameter and `web_token` in the constructor were removed. The SDK manages its own DOM node internally.
:::

In versions prior to **4.0.0**, the constructor received the following positional parameters:

| Name | Description | Required |
|----------|----------|----------|
| hostComponent | Parent HTML component that housed the SDK HTML. | Yes |
| web_token | Client key sent by QI Tech. | Yes (versions < 3.0.0) |

---

# Importing the library

URL: /en/documentation/caas/face_recognition/web/import

To import our library, add our library address to a **src** TAG in your website's HTML:

```html
<script src="https://facerecon.caas.qitech.app/face-recognition-4-2-1.js"></script>
```

---

# Introduction

URL: /en/documentation/caas/face_recognition/web/introduction

Welcome to QI Tech's Web Face Recognition integration manual! This library performs face capture and sends it to the QI Tech Face Recognition API . You can use this library to capture a client's face image through your website and reference it through a key in other QI Tech system products.

In this step-by-step guide you will find library details as well as a javascript implementation example. With this, you have the necessary tools to adapt to your application's use case.

## Problems?

We are not a company that hides behind an API! Contact our support and we will respond as quickly as possible. Feel free to call us if you want a quick response!

### We Love Feedback

Even if you have already solved your problem or it is very simple (Even a typo or inadequate organization that you already understood), send us an email, so we make the documentation increasingly practical and the next person won't need to suffer the pains you suffered!

## Environments

We have two environments for our clients. 

* Production
* Sandbox

:::danger Important Warning!
Real data from individuals and/or legal entities should not be used in QI Tech's Sandbox environments.  
:::

The selection is performed through the `.setSandboxEnvironment()` method during SDK configuration, which will change the environment to Sandbox. If the method is not called, the production environment will be used.

---

# Face Registration and 1:1 Validation

URL: /en/documentation/caas/face_recognition/web/registration_and_validation

:::danger Deprecated Feature
The `.setDocumentNumber()` and `.setValidation()` methods have been discontinued and removed from the Web Face Recognition SDK. The face registration and 1:1 validation flow via Web SDK is no longer supported in any version.

To perform face registration and validation, use the [Face Recognition API](https://docs.qitech.com.br/documentation/caas/face_recognition/api/face_registration) directly.
:::