> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-en/sdks/sdk-mobile/android-sdk/componentes-modulos/captura-de-documentos.md).

# Document Capture - SelphID

## Introduction <a href="#id-1-introduccion" id="id-1-introduccion"></a>

Document capture is performed through the **SelphID Component**.

This component is responsible for capturing identity documents and analyzing the information obtained. During the process, among others, the following steps are carried out:

* Internal management of cameras and permissions.
* Guided assistance during the capture of the **front and back** of the document.
* Extraction of the information contained in the document.
* Obtaining images of the document and associated elements:
  * User's face.
  * User's signature.
* High level of configuration:
  * Countries.
  * Languages.
  * Document types.

In the section [Simplified Launch](/docs.facephi-en/sdks/sdk-mobile/android-sdk/inicializacion/lanzamiento-simplificado.md) the basic steps for SDK Integration are described.\
This page details the specific information needed to launch and configure this component.

***

## Dependency <a href="#id-2-dependencia" id="id-2-dependencia"></a>

The component's specific dependency is:

```kotlin
implementation "com.facephi.androidsdk:selphid_component:$version"
```

***

## Available controllers <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controller**    | **Description**                      |
| ----------------- | ------------------------------------ |
| SelphIDController | Main document recognition controller |

***

## Simplified Launch <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Once the SDK is started and a new operation is created, the component can be launched using its controller.

Face Capture launch:

```kotlin
val response = SDKController.launch(
    SelphIDController(SelphIDConfiguration(..))
)
when (response) {
    is SdkResult.Error -> Napier.d("SelphID: ERROR - ${response.error.name}")
    is SdkResult.Success -> response.data
}
```

***

## Basic configuration <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

To launch the component it is necessary to create an object **SelphIDConfigurationData**, which defines the widget behavior.

In the basic configuration:

* It is mandatory to define the **country** and the **document type**.
* In the field `specificData` the corresponding country code must be indicated (for example, `ES` for Spain).

```kotlin
SelphIDConfiguration(
  resourcesPath = "resources_file.zip",
  wizardMode = true,
  specificData = "ES|<ALL>",
  documentType = SelphIDDocumentType.ID_CARD,
)
```

**Available document types**

```
SelphIDDocumentType.ID_CARD
SelphIDDocumentType.PASSPORT
SelphIDDocumentType.DRIVERS_LICENSE
SelphIDDocumentType.FOREIGN_CARD
SelphIDDocumentType.CREDIT_CARD
SelphIDDocumentType.CUSTOM
SelphIDDocumentType.VISA
```

***

## Result reception <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

The launch result is returned as an object **SdkResult**, which can indicate a successful result or an error.

```kotlin
when (response) {
    is SdkResult.Error -> Napier.d("ERROR - ${response.error}")
    is SdkResult.Success -> response.data
}
```

### Error handling <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Errors are returned as a **SelphIdError**.

**List of errors**

* SPD\_ACTIVITY\_RESULT\_ERROR: The activity result is incorrect.
* SPD\_ACTIVITY\_RESULT\_MSG\_ERROR: The activity result received in the msg is incorrect.
* SPD\_APPLICATION\_CONTEXT\_ERROR: The required application context is null.
* SPD\_BAD\_EXTRACTOR\_CONFIGURATION\_ERROR: Widget: Incorrect extractor configuration
* SPD\_CAMERA\_PERMISSION\_DENIED: The user has denied the permissions.
* SPD\_CANCEL\_BY\_USER: The user has canceled the process.
* SPD\_CANCEL\_LAUNCH: A general cancellation of the SDK has been performed.
* SPD\_COMPONENT\_LICENSE\_ERROR: The component License is incorrect.
* SPD\_CONTROL\_NOT\_INITIALIZATED\_ERROR: Widget: Initialization error
* SPD\_EMPTY\_LICENSE: The license String is empty.
* SPD\_EXTRACTION\_LICENSE\_ERROR: Widget: License error
* SPD\_FETCH\_DATA\_ERROR: Error in collecting the result.
* SPD\_FLOW\_ERROR: Error in the flow process.
* SPD\_HARDWARE\_ERROR: Widget: Hardware error
* SPD\_INITIALIZATION\_ERROR: Initialization error.
* SPD\_MANAGER\_NOT\_INITIALIZED: The managers are null.
* SPD\_MOVE\_FAIL: The user has not moved as specified in the process.
* SPD\_NO\_DATA\_ERROR: The input data are null.
* SPD\_OPERATION\_NOT\_CREATED: There is no operation in progress.
* SPD\_RESOURCES\_NOT\_FOUND: The resources zip was not found
* SPD\_SETTINGS\_PERMISSION\_ERROR: Widget: Permissions error
* SPD\_TIMEOUT: Timeout in the process.
* SPD\_UNEXPECTED\_CAPTURE\_ERROR: Widget: Capture error
* SPD\_UNKNOWN\_ERROR: Unknown error
* SPD\_WIDGET\_RESULT\_DATA\_ERROR: Error in the widget output data

### Reception of the successful result - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

When the result is correct (`SdkResult.Success`), an object is obtained **SelphIDResult**.

The images are returned in format **SdkImage**.\
It is possible to access the bitmap through `image.bitmap`.

To convert an image to Base64:

```kotlin
Base64.encodeToString(this.toByteArray(), Base64.NO_WRAP)
```

**Returned fields**

**frontDocument / tokenFrontDocument:**

The front image of the document, processed, cleaned, and cropped by the edges, and its corresponding token.

**backDocument / tokenBackDocument**

The back image of the document, processed, cleaned, and cropped by the edges, and its associated token.

**faceImage / tokenFaceImage**

The face image found in the document, if any, and its associated token.

Valid for the MATCHING FACIAL process.

**documentCaptured**

This property indicates the document model that was captured when a search is performed in SMSearch mode. This allows the application to know which model, among all the allowed ones, was detected.

**matchingSidesScore**

This property returns a calculation of the similarity of the data read between the front and back of the document. The calculation is performed by checking the similarity between the common fields read on both sides. The result of the calculation will be a value between 0.0 and 1.0 if there are common fields in the document. The higher the value, the more similar the compared data are. If the calculation returns -1.0, the document does not contain common fields or information from both sides is not yet available.

**Property captureProgress**

This property returns the state the capture process was in when the widget finished. These are the possible values:

```
Front_Detection_None = 0
Front_Detection_Uncertain = 1
Front_Detection_Completed = 2
Front_Document_Analyzed = 3
Back_Detection_None = 4
Back_Detection_Uncertain = 5
Back_Detection_Completed = 6
Back_Document_Analyzed = 7
```

* **0**: In the Front reading, the widget finished without having detected anything. Usually when no document is placed.
* **1**: In the Front reading, the widget finished having partially detected a document. In this case some of the expected elements could be detected, but not all the necessary ones.
* **2**: In the Front reading, the widget finished having completed detection of all the document elements. If the widget ends in this state, it is because OCR analysis could not be completed successfully.
* **3**: In the Front reading, the widget finished having analyzed and extracted all the OCR from the document. This is the state in which a correct Front reading of a document would end.

The states from **4** to **7** are exactly the same, only they refer to the process result when the back is analyzed.

**ocrResults**

This dictionary contains all the data detected in the document. The keys of each field are encoded in such a way that the key itself contains information about where the value was obtained. Thus, for example, the key `Front/MRZ/DocumentNumber` indicates the value of the DocumentNumber that was read on the Front of the document and in the MRZ region. These keys depend on the captured document and therefore will be different across countries and document models. The dictionary also contains keys with more generic names that do not carry location information. These keys contain the most complete data among all those read for that field.

These keys are the following:

* **FirstName**: The value associated with this key contains the user's first name.
* **LastName**: The value associated with this key contains the user's last name.
* **DateOfBirth**: The value associated with this key contains the date of birth detected in the document.
* **Gender**: The value associated with this key contains the user's sex detected in the document.
* **Nationality**: The value associated with this key contains the user's nationality detected in the document.
* **DocumentNumber**: The value associated with this key contains the document number.
* **DateOfExpiry**: The value associated with this key contains the document expiry date.
* **Issuer**: The value associated with this key contains the document issuer.
* **DateofIssue**: The value associated with this key contains the document issue date.
* **PlaceOfBirth**: The value associated with this key contains the user's place of birth.
* **Address**: The value associated with this key contains the address detected in the document.

Additionally, keys of the results object itself are added to make searching easier:

* **DocumentCaptured**: Value of the document model that was captured according to the model .xml. Corresponds to the documentCaptured property.
* **MatchingSidesScore**: Value indicating the correspondence between the read sides of the document. Corresponds to the matchingSidesScore property.

**timeoutDiagnostic**

This property returns a text string that explains why the widget timed out. This string can be used on a later timeout screen where the main application can provide more information to the user about what happened during document capture.

**countryCaptured**

Country of the document.

**documentTypeCaptured**

Document type. Corresponds to those in section 5.1.10.

**personalData**

Reduced set of data obtained from the user:

* issuer
* documentNumber
* issueDate
* expiryDate
* name
* surname
* fullName
* gender
* birthDate
* birthPlace
* nationality
* address
* nfcKey
* numSupport
* mrz

***

## Advanced information <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

### Document selector - OPTIONAL

**showDocumentSelector**

Activation of the document selector view. It will be presented as soon as the controller is launched.

**enabledCountries**

List of countries in ISO2 that will appear in the selector. If its value is null or does not contain valid values, all those available by the SDK will be shown.

**enabledDocumentTypes**

List of document types that will appear in the document type selector. If its value is null or does not contain values, all those available by the SDK will be shown.

#### Advanced component configuration

The component behavior is defined by **SelphIDConfigurationData**.

**resourcesPath**

Indicates the name of the component resources in zip format. Example: “resources-selphid-2-0.zip“.

This name will be used to look for the file at the path of *assets*.

<div align="left"><figure><img src="/files/f8b040d604e6d04bf68ce0572e068a64d0d9f817" alt=""><figcaption></figcaption></figure></div>

**wizardMode**

Indicates whether the widget is configured to capture both sides (front and back) of the document one after the other. In this mode the widget would only be launched once and, after capturing the front, it would continue with the back.

**showResultAfterCapture**

Indicates whether to show a screen with the captured image of the document after the analysis process. On this screen the user is given the option to repeat the capture process if the image obtained from the document is not correct.

**showTutorial**

Indicates whether the widget activates the tutorial screen. This view explains intuitively how the capture is performed.

**tutorialOnly**

Indicates whether the widget should be launched only to show the tutorial.

**scanMode**

Indicates the OCR scanning mode for documents. Depending on the choice, several types of documents or one specific document will be scanned and searched. This mode can be of three types:

* **SelphIDScanMode.MODE\_GENERIC**: The generic mode allows scanning any type of document regardless of country or document type. The result of this mode is not as accurate as the following ones, but it allows scanning several standard documents.
* **SelphIDScanMode.MODE\_SEARCH**: The search mode will allow using a whitelist and blacklist, and will search in the documents that meet these conditions. These conditions are indicated in the "specificData" variable. This way, the search can be narrowed by limiting the number of templates, making the search much more precise than in the generic case.
* **SelphIDScanMode.MODE\_SPECIFIC**: Search for a specific document. These conditions are indicated in the "specificData" property shown below.

**specificData**

This property allows defining which documents will be scanned during the process, in case the scanning mode (scanMode) is set to **MODE\_SEARCH** or **MODE\_SPECIFIC**.

An example configuration that allows scanning all Spanish nationality documents would be the following:

```
val selphIDConfiguration = SelphIDConfigurationData(
    scanMode = SelphIDScanMode.MODE_SEARCH,
    specificData = "ES|<ALL>",  // Código ISO de España (ES)
)
```

**fullscreen**

Indicates whether the view will have priority to be displayed in full screen, if the system allows it.

**tokenImageQuality**

Indicates the amount of quality wanted in the tokenized images. Value between 0 and 1.

**documentType**

The permitted values are the following:

* **SelphIDDocumentType.ID\_CARD**: The widget is configured to capture identity documents.
* **SelphIDDocumentType.PASSPORT**: The widget is configured to capture passports.
* **SelphIDDocumentType.DRIVERS\_LICENSE**: The widget is configured to capture driving licenses.
* **SelphIDDocumentType.FOREIGN\_CARD**: The widget is configured to capture foreign documents.
* **SelphIDDocumentType.CUSTOM**: The widget is configured to capture other types of documents that do not correspond to any of the above categories.
* **WidgetSelphIDDocumentType.VISA**: The widget is configured to capture a country's visa. (SDK min 2.1.2)

**documentSide**

The permitted values are the following:

* **SelphIDDocumentSide.FRONT**: The widget is configured to capture the front side of the document.
* **SelphIDDocumentSide.BACK**: The widget is configured to capture the back side of the document.

**timeout**

It is an enumerated type that defines the timeout for capturing one side of the document. It has 3 possible values:

* SelphIDTimeout.SHORT: 15 seconds.
* SelphIDTimeout.MEDIUM: 20 seconds.
* SelphIDTimeout.LONG: 25 seconds.
* SelphIDTimeout.VERY\_LONG: 60 seconds.

**videoFilename**

Sets the absolute path of the file name where a video of the capture process will be recorded. The application is responsible for requesting the necessary permissions from the phone in case that path requires additional permissions. By default, the widget will not perform any recording process unless a file path is specified through this method.

**DocumentModels**

This property allows, through an XML-formatted string, configuring the document models that the widget will try to capture. The definition of these models is, by default, in an .xml models file found in the resources .zip. With this property, an application can update the document models on the fly.

Note: This property does not alter the contents of the resources file.

**generateRawImages**

This property configures the widget to return the complete camera image used to capture the document. These images are returned in the properties `rawFrontDocument` and `rawBackDocument` of the object `results` respectively.

**tokenPreviousCaptureData**

When document capture is performed in 2 calls, this property allows passing a dictionary with the previous capture information. In this way, the widget can intelligently combine the results of both reads and thus return the combined information from both captures. It also allows the widget to calculate a degree of similarity between the data on both sides.

In the case where the capture of both sides of the document is done in a single call, this is not necessary since the widget performs this process internally.

**translationsContent**

This advanced property allows, through an XML-formatted string, configuring the translation of the literals shown during the process.

Note: This property does not alter the contents of the resources file.

**viewsContent**

This advanced property allows the widget views to be configured using a string in xml format.

Note: This property does not alter the contents of the resources file.

**showDiagnostic**

Show diagnostic screens at the end of the process

**showPreviousTip**

Displays a screen before starting the capture with information about the process to be carried out and a button to start it.

**vibrationEnabled**

Indicates whether vibration feedback is desired when the process ends.

***

## Component Customization <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

In addition to the [SDK Customization](/docs.facephi-en/sdks/sdk-mobile/android-sdk/personalizacion.md) this component allows its interface to be modified.

### Texts <a href="#id-81-textos" id="id-81-textos"></a>

Texts can be customized by overwriting the values in a string XML file included in the client application.

Examples of available keys:

#### Diagnostics

| Name                                     | Value                                                                             |
| ---------------------------------------- | --------------------------------------------------------------------------------- |
| `selphid_component_timeout_title`        | Timeout exceeded                                                                  |
| `selphid_component_timeout_desc`         | Check that the document is inside the frame and the data is visible.              |
| `selphid_component_timeout_front_desc`   | Check that the front of the document is inside the frame and the data is visible. |
| `selphid_component_timeout_back_desc`    | Check that the back of the document is inside the frame and the data is visible.  |
| `selphid_component_internal_error_title` | There was a technical problem                                                     |
| `selphid_component_internal_error_desc`  | We are sorry. The capture could not be completed                                  |

#### Previous Tip

| Name                                      | Value                                                                        |
| ----------------------------------------- | ---------------------------------------------------------------------------- |
| `selphid_component_tip_message`           | Frame your document within the frame. The photo will be taken automatically. |
| `selphid_component_tip_message_alt`       | Frame your document within the frame. The photo will be taken automatically. |
| `selphid_component_tip_anim_id_alt`       | Place your identity document horizontally, and point your phone vertically.  |
| `selphid_component_tip_anim_passport_alt` | Place your passport horizontally, and point your phone vertically.           |
| `selphid_component_tip_anim_driving_alt`  | Place your driver's license horizontally, and point your phone vertically.   |
| `selphid_component_tip_title`             | Document photo                                                               |
| `selphid_component_tip_button`            | START                                                                        |
| `selphid_component_tip_button_alt`        | Start document capture                                                       |
| `selphid_component_tip_close_button_alt`  | BACK                                                                         |
| `selphid_component_tip_info_button_alt`   | See tips                                                                     |

#### Tutorial

| Name                                            | Value                                                                        |
| ----------------------------------------------- | ---------------------------------------------------------------------------- |
| `selphid_component_tutorial_message_1`          | Look for a background with good contrast.                                    |
| `selphid_component_tutorial_message_2`          | Place the document inside the frame.                                         |
| `selphid_component_tutorial_message_3`          | Avoid glare that makes the document difficult to read.                       |
| `selphid_component_tutorial_1_anim_id_alt`      | Place the document on a surface with a color different from the document.    |
| `selphid_component_tutorial_2_anim_id_alt`      | Place your identity document horizontally, and point your phone vertically.  |
| `selphid_component_tutorial_3_anim_id_alt`      | Reflections appear on the document.                                          |
| `selphid_component_tutorial_1_anim_pass_alt`    | Place the passport on a surface with a color different from the document.    |
| `selphid_component_tutorial_2_anim_pass_alt`    | Place your passport horizontally, and point your phone vertically.           |
| `selphid_component_tutorial_3_anim_pass_alt`    | Reflections appear on the document.                                          |
| `selphid_component_tutorial_1_anim_driving_alt` | Place the document on a surface with a color different from the document.    |
| `selphid_component_tutorial_2_anim_driving_alt` | Place your identity document horizontally, and point your phone vertically.  |
| `selphid_component_tutorial_3_anim_driving_alt` | Reflections appear on the document.                                          |
| `selphid_component_tip_health_alt`              | Place your health card horizontally, and point your phone vertically.        |
| `selphid_component_tutorial_1_anim_health_alt`  | Place the health card on a surface with a color different from the document. |
| `selphid_component_tutorial_2_anim_health_alt`  | Place your identity document horizontally, and point your phone vertically.  |
| `selphid_component_tutorial_3_anim_health_alt`  | Reflections appear on the document.                                          |
| `selphid_component_tip_custom_alt`              | --                                                                           |
| `selphid_component_tutorial_1_anim_custom_alt`  | --                                                                           |
| `selphid_component_tutorial_2_anim_custom_alt`  | --                                                                           |
| `selphid_component_tutorial_3_anim_custom_alt`  | --                                                                           |
| `selphid_component_tutorial_close_button_alt`   | Back to previous tutorial                                                    |

#### Document and Country Selector

| Name                                          | Value                                |
| --------------------------------------------- | ------------------------------------ |
| `selphid_selector_title`                      | Complete your Onboarding             |
| `selphid_selector_country_label`              | Which country is your document from? |
| `selphid_selector_country_placeholder`        | Select a country                     |
| `selphid_selector_country_search_label`       | Choose a country                     |
| `selphid_selector_country_search_placeholder` | Search for a country                 |
| `selphid_selector_country_search_clear`       | Clear search                         |
| `selphid_selector_country_no_results`         | No results                           |
| `selphid_selector_document_label`             | Which document will you use?         |
| `selphid_selector_document_placeholder`       | Select a document                    |
| `selphid_selector_document_dialog_title`      | Choose the document                  |
| `selphid_selector_document_dialog_cancel`     | CANCEL                               |
| `selphid_selector_document_dialog_select`     | SELECT                               |
| `selphid_selector_continue`                   | Continue                             |
| `selphid_selector_type_id_card`               | Identity document                    |
| `selphid_selector_type_passport`              | Passport                             |
| `selphid_selector_type_drivers_license`       | Driver's license                     |
| `selphid_selector_type_foreign_card`          | Residence card                       |
| `selphid_selector_type_credit_card`           | Credit card                          |
| `selphid_selector_type_custom`                | Custom                               |
| `selphid_selector_type_visa`                  | Visa                                 |

### Animations <a href="#id-82-animaciones" id="id-82-animaciones"></a>

The component uses animations **Lottie** (`.json`) both in the *previous tip* as well as in the *tutorials*.

If you want to modify the SDK animations, you must include the files with **the same name** in the folder `res/raw/`

```
selphid_anim_tip_driver_h.json
selphid_anim_tip_driver_m.json
selphid_anim_tip_health.json
selphid_anim_tip_id_h.json
selphid_anim_tip_id_m.json
selphid_anim_tip_mrz.json
selphid_anim_tip_pass_h.json
selphid_anim_tip_pass_m.json

selphid_anim_tuto_driver_h_1.json
selphid_anim_tuto_driver_h_2.json
selphid_anim_tuto_driver_h_3.json
selphid_anim_tuto_driver_m_1.json
selphid_anim_tuto_driver_m_2.json
selphid_anim_tuto_driver_m_3.json

selphid_anim_tuto_id_h_1.json
selphid_anim_tuto_id_h_2.json
selphid_anim_tuto_id_h_3.json
selphid_anim_tuto_id_m_1.json
selphid_anim_tuto_id_m_2.json
selphid_anim_tuto_id_m_3.json

selphid_anim_tuto_pass_h_1.json
selphid_anim_tuto_pass_h_2.json
selphid_anim_tuto_pass_h_3.json
selphid_anim_tuto_pass_m_1.json
selphid_anim_tuto_pass_m_2.json
```
