> For the complete documentation index, see [llms.txt](https://docs.vida.id/identity-stack/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vida.id/identity-stack/verify/smart-kyc-fraud-api/api-integration/biometric-verification.md).

# Biometric Verification

#### Biometric Verification only

This configuration performs biometric-only verification, focusing specifically on evaluating the user’s selfie through liveness detection, image quality assessment, manipulation checks, and face validation. Although the request includes a full set of identity data such as name, government ID, and date of birth, only the biometric components are processed and validated. This setup is suitable for scenarios where demographic validation is handled externally through a registration authority agreement.

{% hint style="info" %}
If only the Biometric Verification is conducted, then a **Level 1 Certificate will be issued** upon acceptance.
{% endhint %}

## **Parameters**

<table><thead><tr><th width="150.884033203125">Field</th><th width="91.0013427734375">Type</th><th width="271.1890869140625">Description</th><th>Sample Value</th></tr></thead><tbody><tr><td>partnerTrxId</td><td>string</td><td>Generate a unique transaction ID in UUID format and include it in the request to link your transaction with the VIDA transaction.</td><td><p>Generated random uuid by the partner. </p><p></p><p>Example:</p><p><code>1000073-c00f-4008-8005-d2ec4d9be956</code></p></td></tr><tr><td>groupId</td><td>string</td><td><p>For each NIK, partners should send a unique group ID that can be used to track related transactions across multiple fraud assessment categories. </p><p></p><p>This is mandatory for customers using <a href="/pages/HCUIJlyn2RCJnps2H9bO">Multistage verification</a></p></td><td><p>Generated random UUID by the partner. </p><p></p><p>Example:</p><p><code>8000073-d00e-9008-9005-d2ce4b9ce956</code></p></td></tr><tr><td>transactionType<mark style="color:red;">*</mark></td><td>string</td><td>Type of the transaction</td><td>In the biometric verification below transaction type is applicable<br><br><code>BIOMETRIC_FRAUD_ASSESSMENT</code></td></tr><tr><td>govId<mark style="color:red;">*</mark></td><td>string</td><td>The user's government ID number</td><td><p> NIK - Nomor Induk Kependudukan), consisting of a 16-digit number: <code>3451222123456716</code> </p><p></p><p>Here are following validation that must to follow for NIK input:  </p><ul><li>NIK must 16 digit number</li><li>NIK shouldn't be started with "0"</li></ul></td></tr><tr><td>govIdType</td><td>string</td><td>The type of IDCard Document. </td><td>Supported values: <code>"KTP"</code></td></tr><tr><td>fullName<mark style="color:red;">*</mark></td><td>string</td><td>Users Full Name which should same with registered ID</td><td><p>User full name as per KTP.</p><p></p><p>Example: <code>Johnny Rudiantara Sembiring</code></p></td></tr><tr><td>dob<mark style="color:red;">*</mark></td><td>string</td><td>User's Date of Birth</td><td><p>Date of Birth in <code>yyyy-mm-dd</code> format<br></p><p>Example: <code>1989-01-01</code></p></td></tr><tr><td>mobile<mark style="color:red;">*</mark></td><td>string</td><td>The user's verified mobile number with the country code, provided in E.164 format without spaces or special characters. </td><td><p>If the mobile number isn’t available, a verified email address can be passed, however, one of the two is mandatory. </p><p></p><p>Example: <code>+6281293671234</code></p></td></tr><tr><td>email</td><td>string</td><td>The user's valid email address</td><td>Example: <code>user@example.com</code></td></tr><tr><td>consent<mark style="color:red;">*</mark></td><td>object</td><td>A user’s consented timestamp value where they agreed to consent sharing data with VIDA</td><td><p>"consent": {</p><p>      "consentedAt": "1614089870",</p><p>     "consentGiven": true</p><p>    }</p></td></tr><tr><td>selfiePhoto<mark style="color:red;">*</mark></td><td>base64-encoded string</td><td>A base64-encoded string of the user's selfie for facial recognition and face-match checks, adhering to specified image standards. </td><td>Example: <code>"/9j/4AAQSkZJRgABAQAAJAAkAAD/4QhcR..."</code><br></td></tr><tr><td>idCardPhoto</td><td>base64-encoded string</td><td>A plain base64-encoded string of the user ID card Photo (i.e. KTP)</td><td>Example: <code>"/9j/4AAQSkZJRgABAQAAJAAkAAD/4QhcR..."</code></td></tr></tbody></table>

<mark style="color:red;">\*</mark>required

{% hint style="info" %}
**Note:** When using **biometric verification**, only the biometric data will be validated, regardless of any additional parameters provided (e.g., fullName, dob, email). These additional fields may be included in the request but will not be assessed in this type.
{% endhint %}

## **Sample Request**

<details>

<summary>Sample JSON Request (Main Parameters Only)</summary>

```json
{
    "partnerTrxId": "{{random-UUID}}", //must be unique for every transaction.
    "groupId": "{{UUID4}}", //Required for Multistage verification
    "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
    "mobile": "Phone Number from ID Card",
    "email": "useremail@emailprovider.com",
    "govId": "Gov Id from ID Card",
    "govIdType": "KTP",
    "fullName":"Userbcde", //recorded but not verified
    "dob": "YYYY-MM-DD", //recorded but not verified
    "selfiePhoto": "{{selfieID1}}",
    "consent": {
        "consentedAt": "1614089870",
        "consentGiven": true
    }
}
```

</details>

## Sample Response

HTTP Status Code: `200`

<details>

<summary>JSON Response (Main Parameters only)</summary>

```json
{
    "data": {
        "authenticationLevel": "IAL2",
        "certificate": {
            "level": 2,
            "detail": "Certificate with long term validity is issued and its utilization is bound to the certificate requesting client"
        },
        //authenticationLevel & certificate field should NOT be used programmatically
        //authenticationLevel & certificate result depends on verification data availability & its RA level
        //Instead, customer should define successful transaction based on Status Check API, score & fraudAssessment status,

        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "unique transaction id generated to identify this transaction",
        "groupId": "{{as provided in request}}", //Returned only for Multistage Verification
        "registrationId": "unique VIDA user ID" //Returned only for Multistage Verification on success, used for digital signature
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "selfiePhoto",
                "result": 0.9
            },
            {
                "name": "liveness",
                "result": 0.164398
            },
            {
                "name": "imgManipulationScore",
                "result": 0.117981
            }
        ]
    }
}
```

</details>

#### Sample Response Value Explanation

<table><thead><tr><th width="198.72027587890625">Values</th><th>Description</th></tr></thead><tbody><tr><td><strong>selfiePhoto</strong></td><td>The degree of match between the selfie provided and the stored biometric data. (Score threshold: 0 to 1)</td></tr><tr><td><strong>liveness</strong></td><td>Score indicating the likelihood that the selfie represents a live person. (Score threshold: 0 to 1)</td></tr><tr><td><strong>imgManipulationScore</strong></td><td>Probability of image manipulation in the selfie. (Score threshold: 0 to 1)</td></tr><tr><td><strong>fraudAssessment</strong></td><td>Indicates whether the fraud assessment process is completed or in progress.</td></tr><tr><td><strong>authenticationLevel</strong></td><td><a href="/pages/imLVFT18M11v0vr29Nau">Assurance level </a>of the authentication process.<br><br>authenticationLevel field should not be used programatically to determine a successful transaction. Instead, customer should define successful transaction based on Status Check API, score &#x26; fraudAssessment status</td></tr><tr><td><strong>certificate</strong></td><td>Details regarding the certificate's trustworthiness for digital signatures.<br><br>certificate field should not be used programatically to determine a successful transaction. Instead, customer should define successful transaction based on Status Check API, score &#x26; fraudAssessment status</td></tr><tr><td><strong>groupId</strong></td><td>Returned only for Multistage Verification. The groupId passed on the request body</td></tr><tr><td><strong>registrationId</strong></td><td>Returned only for Multistage Verification on success, used for digital signature</td></tr></tbody></table>

## 1. Accept Response

HTTP Status Code: `200`

Status : `SUCCESS`

### Main Required Parameters

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "authenticationLevel": "IAL2",
        "certificate": {
            "level": 2,
            "detail": "Certificate with long term validity is issued and its utilization is bound to the certificate requesting client"
        },
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "unique transaction id generated to identify this transaction",
        "groupId": "{{as received in request}}",
        "registrationId": "unique VIDA user ID" //Returned only for Multistage Verification on success, used for digital signature        
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "selfiePhoto",
                "result": 0.9
            },
            {
                "name": "liveness",
                "result": 0.164398
            },
            {
                "name": "imgManipulationScore",
                "result": 0.117981
            }
        ]
    }
}
```

</details>

### With All Extended Demographic Parameters

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "authenticationLevel": "IAL2",
        "certificate": {
            "level": 2,
            "detail": "Certificate with long term validity is issued and its utilization is bound to the certificate requesting client"
        },
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "unique transaction id generated to identify this transaction",
        "groupId": "{{as received in request}}",
        "registrationId": "unique VIDA user ID" //Returned only for Multistage Verification on success, used for digital signature
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "selfiePhoto",
                "result": 0.9
            },
            {
                "name": "liveness",
                "result": 0.164398
            },
            {
                "name": "imgManipulationScore",
                "result": 0.117981
            }
        ]
    }
}
```

</details>

## 2. Reject Responses

### 2.1 Selfie photo match does not pass threshold

HTTP Status Code: `200`

Status : `SUCCESS`

### Sample Response if the Case of 0.3

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "73b0f092-a4be-468e-bedf-8a914c9cfd16",
        "groupId": "{{as received in request}}",
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "selfiePhoto",
                "result": 0.30000000000000004
            },
            {
                "name": "liveness",
                "result": 0.070489
            },
            {
                "name": "imgManipulationScore",
                "result": 0.081049
            }

        ]
    }
}
```

</details>

### Sample Response if the Case of 0.7

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "73b0f092-a4be-468e-bedf-8a914c9cfd16",
        "groupId": "{{as received in request}}",
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "selfiePhoto",
                "result": 0.7000000000000001
            },
            {
                "name": "liveness",
                "result": 0.070489
            },
            {
                "name": "imgManipulationScore",
                "result": 0.081049
            }

        ]
    }
}
```

</details>

### 2.2 Liveness and image manipulation does not pass threshold

HTTP Status Code: `200`

Status : `SUCCESS`

### Both Fails

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "73b0f092-a4be-468e-bedf-8a914c9cfd16",
        "groupId": "{{as received in request}}",
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "liveness",
                "result": 0.999932
            },
            {
                "name": "imgManipulationScore",
                "result": 0.997597
            }
        ]
    }
}
```

</details>

### Only 1 Passed

<details>

<summary>JSON Response</summary>

```json
{
    "data": {
        "transactionType": "BIOMETRIC_FRAUD_ASSESSMENT",
        "transactionId": "73b0f092-a4be-468e-bedf-8a914c9cfd16",
        "groupId": "{{as received in request}}",
        "fraudAssessment": "COMPLETED",
        "assessmentResults": [
            {
                "name": "liveness",
                "result": 0.669388
            },
            {
                "name": "imgManipulationScore",
                "result": 0.998272
            }
        ]
    }
}
```

</details>

### 2.3 Image quality not passed (single detail)

HTTP Status Code: `200`

Status : `SUCCESS`

**JSON Response**

{% tabs %}
{% tab title="Face Occluded" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1051,
            "title": "Detect Un-standardized Image Quality",
            "detail": "Face Occluded"
        }
    ]
}
```

{% endtab %}

{% tab title="Face Too Small" %}

```json
{
    "transactionId": "2ad38778-00d9-4fdf-b509-a3b6bf35eb34",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1052,
            "title": "Detect Un-standardized Image Quality",
            "detail": "Face too small"
        }
    ]
```

{% endtab %}

{% tab title="Multiple Faces Detected" %}

```json
{
    "transactionId": "b0f4a52f-d917-41d1-8e0b-23fa93c34d15",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1054,
            "title": "Detect Un-standardized Image Quality",
            "detail": "More than one face"
        }
    ]
}
```

{% endtab %}

{% tab title="No Face Detected" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1055,
            "title": "Detect Un-standardized Image Quality",
            "detail": "No face detected"
        }
    ]
}
```

{% endtab %}

{% tab title="Image Is Blurry" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1076,
            "title": "Image Quality Is Below Threshold",
            "detail": "Image Is Blur"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### 2.4 Image quality not passed (multiple details)

HTTP Status Code: `200`

Status : `SUCCESS`

**JSON Response**

{% tabs %}
{% tab title="Blur and Overexposure" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1075,
            "title": "Image Quality Is Below Threshold",
            "detail": "Over Exposure"
        },
        {
            "code": 1076,
            "title": "Image Quality Is Below Threshold",
            "detail": "Image Is Blur"
        }
    ]
}
```

{% endtab %}

{% tab title="Blur and Underexposure" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1074,
            "title": "Image Quality Is Below Threshold",
            "detail": "Under Exposure"
        },
        {
            "code": 1076,
            "title": "Image Quality Is Below Threshold",
            "detail": "Image Is Blur"
        }
    ]
}
```

{% endtab %}

{% tab title="Blur and Unnatural Color" %}

```json
{
    "transactionId": "b8cc863f-d61e-4f62-b2a0-63796903798f",
    "groupId": "{{as received in request}}",
    "errors": [
        {
            "code": 1063,
            "title": "Image Quality Is Below Threshold",
            "detail": "UnNatural Color"
        },
        {
            "code": 1076,
            "title": "Image Quality Is Below Threshold",
            "detail": "Image Is Blur"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## 3. Required parameters are missing

These errors occur when one or more mandatory fields are not provided in the request. The response includes details of the missing parameter in the detail field.

HTTP Status Code: `400`

Status : `ERROR`

**JSON Response**

{% tabs %}
{% tab title="Missing fullName" %}

```json
{
    "errors": [
        {
            "code": 1006,
            "title": "must not be blank",
            "detail": "fullName"
        }
    ]
}
```

{% endtab %}

{% tab title="Missing selfiePhoto" %}

```json
{
    "errors": [
        {
            "code": 1006,
            "title": "must not be blank",
            "detail": "selfiePhoto"
        }
    ]
}
```

{% endtab %}

{% tab title="Invalid Base64 format" %}

```json
{
    "errors": [
        {
            "code": 1006,
            "title": "Invalid image base64 String",
            "detail": "selfiePhoto"
        }
    ]
}
```

{% endtab %}
{% endtabs %}
