> 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/document-ai/ocr-and-document-verification/ocr-and-document-verification-v2/full-details-endpoint/integration-overview.md).

# Integration Overview

The VIDA Verify API provides a comprehensive solution for verifying identification documents through advanced operations like OCR and ID Verification.

## API Description

<mark style="color:green;">`POST`</mark> `https://{vida-host}/api/v2/verify/`

#### Headers

<table><thead><tr><th width="200.7908935546875">Name</th><th width="225.41314697265625">Type</th><th>Description</th></tr></thead><tbody><tr><td>Authentication<mark style="color:red;">*</mark></td><td>string</td><td>OAuth access token. Get the token by calling the 'Get access token' API.</td></tr><tr><td>Content-Type</td><td>application/JSON</td><td>Format type of request body</td></tr></tbody></table>

{% hint style="info" %}
For details on the **recommended input  image,** please refer to the [Document Capture Guidelines](/identity-stack/verify/document-ai/document-capture-guidelines.md)
{% endhint %}

***

## **Pre-Processing Steps**

We have a set of validation steps which will be executed before the specific operations, if the steps are executed successfully then only the requested operation will be performed else the execution will be stopped and error will be returned in the response body. Below is the preprocessing steps:

### **Pre processor for OCR and ID verification for Malaysian cards**

**Card classification check**

* Name: Card Classification Check
* Purpose: The purpose of this step is to get the card type for the idFrontSideImage and idBackSideImage <mark style="color:red;">\*</mark>(*if enabled)* provided in request.&#x20;
* Conditions: This step will execute only for either of operations OCR or IdVerification, or both

**Image quality check**

* Name: Document Image Quality Check
* Purpose: The purpose of this step is to assess if the idFrontSideImage and idBackSideImage <mark style="color:red;">\*</mark>(*if enabled*) provided in request is as per quality standard. It will evaluate the image for different parameters like:
  * Glare: Checks if there is a Glare in the image captured
  * Blurriness: Checks if the image has blurriness.
  * Low Light: To check whether the image captured has under exposure
* Conditions: This step will execute only for either of operations OCR or IdVerification.
* Response:&#x20;
  * Success: If image quality is passed all checks parameter
  * Failure: If any of the image quality check fails

### **Success**

Image quality passes all parameter checks.

**Image Quality Result:** After the image quality check, an imageQualityResult object is provided in the response, containing assessments for glare, low light, and blurriness. Each assessment includes a score and a threshold value. Here is a snippet of the response:

<details>

<summary>Sample API Response </summary>

```json
{
  ......[TRUNCATED]....
  "imageQualityResult": {
    "front": {
      "glare": {
            "score": 0,
            "threshold": 0.95
        },
        "blurriness": {
            "score": 0.000019,
            "threshold": 0.95
        },
        ......[TRUNCATED]....
    }
  }
}
```

</details>

### **Error**&#x20;

If image Quality is fails either of any checks parameter

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transaction id generated to identify this transaction",
    "partnerTrxId": "partner transaction id submitted by customer in request",
    "groupId": "partner group id submitted by customer in request",
    "errors": [
        {
            "message": "Quality check failed. Image is too dark. (123008)",
            "code": 5203,
            "operations": [
                "ocr",
                "idVerification"
            ]
        }
    ]
}
```

</details>

{% hint style="info" %}
**Note :**&#x20;

1. Image quality check is implemented only for Malaysian and KTP cards.
   {% endhint %}

### **Pre processor for OCR and ID verification for KTP cards** <a href="#docs-internal-guid-e436b2c5-7fff-6098-c10c-7976735996e9" id="docs-internal-guid-e436b2c5-7fff-6098-c10c-7976735996e9"></a>

**Image quality check**

* Name: Document Image Quality Check
* Purpose: The purpose of this step is to assess if the idFrontSideImage provided in request is as per quality standard. It will evaluate the image for three parameters.
  * Over Exposure: To check whether the image captured has Over exposure.
  * Blurriness: Checks if the image has blurriness.
  * Low Light: To check whether the image captured has under exposure.
  * Card Dimension: Checks card width, height and card co-ordinates.
* Conditions: This step will execute only for either of operations OCR or IdVerification.
* Response:&#x20;
  * Success: If image quality is passed all checks parameter

{% hint style="info" %}
Note: For sample for KTP IQA response please refer to the API Reference docs.
{% endhint %}

### Request Body

Each request is compartmentalised into three critical components: operations, payload, and consent.

**Operations**:

This portion of the request specifies the actions or tasks to be executed for a particular request or transaction. Currently, the VIDA service supports four main operations - OCR (Optical Character Recognition) and ID Verification. The operation(s) chosen dictate what tasks will be carried out during the processing of the request.

Here are the fields required for the two supported operations:

<table><thead><tr><th width="229.7774658203125">Operation</th><th>Required Fields</th></tr></thead><tbody><tr><td>OCR</td><td>partnerTrxId, groupId, country, idType, idSubtype, idFrontSideImage, idBackSideImage <em><strong>(if enabled)</strong></em></td></tr><tr><td>idVerification</td><td>partnerTrxId, groupId, country, idType, idSubtype, idFrontSideImage, idBackSideImage <em><strong>(if enabled)</strong></em></td></tr></tbody></table>

**Payload**:&#x20;

The Payload encompasses the necessary data required to execute the operations specified in the request. The required parameters within the Payload are dynamic and depend on the chosen operations. If any of these parameters are missing, invalid, or incorrectly formatted, the service will reject the request. This rejection is indicated by an error code and a 400 HTTP response. As such, it is crucial to ensure the inclusion and validity of all necessary parameters in the Payload.

{% hint style="info" %}
**Note**: There are particular checks on the request body, for example -> No duplicate value allowed for the partner transaction id, some checks on the country and idType, idSubType. The details are mentioned in the below table.
{% endhint %}

<table><thead><tr><th width="217.76953125">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>partnerTrxId</td><td>Reference ID supplied by the customer, used for identifying the transaction and <strong>it can't be duplicated.</strong></td></tr><tr><td>groupId</td><td><p>For each unique end user, partners must send a unique <strong>group ID</strong> that allows tracking of related transactions across different <strong>KYC steps</strong>.</p><p><br><strong>Example:</strong> If a customer performs both OCR-IDV and Liveness-FaceMatch checks, the same <code>groupId</code> should be sent for both transactions. This allows the system to link them to the same end user.<br><br><strong>The value can be duplicated and it must not be null or an empty string.</strong></p></td></tr><tr><td>country</td><td>Country code in ISO 3166 -1 alpha-3 format, indicating the origin of the ID document.</td></tr><tr><td>idType</td><td>The type of ID to be processed (currently, the supported type is "ID_CARD", "PASSPORT", "DRIVING_LICENSE").</td></tr><tr><td>idSubtype</td><td>Subtype for idType (current possible values include "MyKad", "MyTentera", "MyPR", "MyKas", "KTP", "N/A").</td></tr><tr><td>idFrontSideImage</td><td>Base64 encoded image of the front side of the ID</td></tr><tr><td>idBackSideImage</td><td>Base64 encoded image of the back side of the ID <mark style="color:red;">*</mark><em><strong>(if enabled)</strong></em></td></tr></tbody></table>

**Consent**:&#x20;

The Consent component contains data related to the end user's consent. This may include confirmation that the user has agreed to the terms of service, data processing agreements, or other necessary permissions.

| Parameter  | Requirement |
| ---------- | ----------- |
| country    | Required    |
| obtained   | Required    |
| obtainedAt | Required    |
| userIp     | Optional    |

These three parts form the body of a request and all must be properly structured and present for a request to be successfully processed.

#### Schema

<details>

<summary>Sample API Request</summary>

```json
{
  "operations": ["operationName1", "operationName2"],
  "payload": {
    "partnerTrxId": "reference id supplied by customer",
    "groupId" : "reference id to track complete KYC flow",
    "idType": "current supported Idtype: ID_CARD",
    "country": "country code",
    "idSubtype": "This parameter is required for IdType, Current Possible Values are MyKad",
    "idFrontSideImage": "Base64 encoded image of ID front side",
    "idBackSideImage": "Base64 encoded image of ID back side" // if enabled
  },
  "userConsent": {
    "userIp": "user IP Address",
    "country": "Country Code",
    "obtained": "Boolean",
    "obtainedAt": "EPOCH Time"
  }
}
```

</details>

### Response

The response will be organized into distinct sections, tailored to the operations included in the request:

**Transaction Details:** This section will provide specific details about the transaction associated with the request.

* `transactionId`: A unique identifier generated for this request.
* `partnerTrxId`: Transaction id is shared by the partner in the request and can not be duplicated.
* `groupId:`I\`t is a tracking id which can be used to link multiple transactions for KYC flow and can be duplicated and it can not be a null or empty string.

**Errors:** If any issues arise during the processing of the request, they will be detailed in the errors section. This block is included in the response if any errors occur; otherwise, it is omitted.

**Warnings:** Warnings are generated based on the outcomes of the operations. They provide insights into any failed validations or checks encountered during the verification process.

**Results:** Result blocks are generated for each operation included in the request, each associated with its respective operation. The mapping for these blocks is as follows:

* `ocr: ocrResult`
* `IQA : imageQualityResult`
* `Card details : card`
* `idVerification: idVerificationResult`

The response from the API follows this schema:

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "card": {
        "country": "MALAYSIA",
        "type": "MyKad",
        "isoAlpha3CountryCode": "MYS",
        "isoAlpha2CountryCode": "MY"
    },
    "imageQualityResult": {
        "front": {
            "glare": {
                "score": 0,
                "threshold": 0.95
            },
            "blurriness": {
                "score": 0.0008,
                "threshold": 0.95
            },
            "lowLight": {
                "score": 0.076793,
                "threshold": 0.95
            }
        },
        "back": {
            "blurriness": {
                "score": 0.003535,
                "threshold": 0.95
            },
            "lowLight": {
                "score": 0,
                "threshold": 0.95
            }
        }
    },
    "idVerificationResult": {
        "front": {
            "spoofingResult": {
                "message": "Success",
                "code": 5000,
                "recapScore": {
                    "score": 0.156807,
                    "threshold": 0.95
                },
                "blackWhite": {
                    "score": 0.005257,
                    "threshold": 0.95
                }
            },
            "landmarkResult": {
                "code": 5000,
                "message": "Success",
                "threshold": 0.95,
                "containerResult": [
                    {
                        "name": "card_logo",
                        "score": 0.9831
                    },
                    {
                        "name": "chip",
                        "score": 0.9748
                    },
                    {
                        "name": "hibiscus_logo",
                        "score": 0.9832
                    },
                    {
                        "name": "malaysia_flag",
                        "score": 0.9882
                    },
                    {
                        "name": "ghost",
                        "score": 0.9891
                    },
                    {
                        "name": "portrait",
                        "score": 0.9691
                    },
                    {
                        "name": "msc_logo",
                        "score": 0.9785
                    },
                    {
                        "name": "kad_pengenalan_header",
                        "score": 0.9847
                    },
                    {
                        "name": "id_number",
                        "score": 0.9941
                    },
                    {
                        "name": "name",
                        "score": 0.9915
                    }
                ]
            },
            "forgeryResult": {
                "code": 5000,
                "message": "Success",
                "summary": {
                    "score": 0.257167,
                    "threshold": 0.95
                }
            }
        },
        "back": {
            "spoofingResult": {
                "message": "Success",
                "code": 5000,
                "recapScore": {
                    "score": 0.270645,
                    "threshold": 0.95
                },
                "blackWhite": {
                    "score": 0.014498,
                    "threshold": 0.95
                }
            },
            "landmarkResult": {
                "code": 5000,
                "message": "Success",
                "threshold": 0.95,
                "containerResult": [
                    {
                        "name": "coat_of_arm",
                        "score": 0.9956
                    },
                    {
                        "name": "kopiah",
                        "score": 0.995
                    },
                    {
                        "name": "twin_tower",
                        "score": 0.9934
                    },
                    {
                        "name": "state_registrar",
                        "score": 0.9913
                    },
                    {
                        "name": "id_number",
                        "score": 0.9906
                    },
                    {
                        "name": "sn",
                        "score": 0.9911
                    }
                ]
            }
        }
    },
    "ocrResult": {
        "front": {
            "data": {
                "idNumber": {
                    "value": "xxxxxx-xx-xxxx",
                    "score": 0.993373,
                    "threshold": 0.95
                },
                "name": {
                    "value": "KHANIZA",
                    "score": 0.999926,
                    "threshold": 0.95
                },
                "address": {
                    "value": "KUALA LUMPUR",
                    "score": 0.997141,
                    "threshold": 0.95
                },
                "dob": {
                    "value": "19980218",
                    "score": 0.993373,
                    "threshold": 0.95
                },
                "citizenship": {
                    "value": "WARGANEGARA",
                    "score": 1,
                    "threshold": 0.95
                },
                "gender": {
                    "value": "F",
                    "score": 1,
                    "threshold": 0.95
                },
                "religion": {
                    "value": "ISLAM",
                    "score": 1,
                    "threshold": 0.95
                },
                "portraitImage": "base64...."
            }
        },
        "back": {
            "data": {
                "extendedIdNumber": {
                    "value": "980218-14-6288-02-01",
                    "score": 0.988594,
                    "threshold": 0.95
                }
            }
        }
    }
}
```

</details>

***

### Error Response Structure in Different Scenarios

The error response structure varies based on different scenarios. Here are the possible scenarios and their corresponding error response structures:

{% hint style="info" %}
Note: These examples are provided to illustrate different **error scenario responses**. There may be **additional scenarios** with a similar response structure but different **error messages**.
{% endhint %}

**If error is associated with invalid payload like missing comma, quotes making the JSON passed unreadable.**

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "errors": [
        {
            "message": "Invalid request: Error occurred while parsing the request",
            "code": 5003
        }
    ]
}
```

</details>

**If error is associated with an empty operation field in payload.**

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "errors": [
        {
            "message": "operations Operations cannot be empty",
            "code": 5003,
            "operations": null
        }
    ]
}
```

</details>

**If error is associated with partnerTrxId blank string is passed.**

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "errors": [
        {
            "message": "partnerTrxId must not be blank",
            "code": 5001,
            "fieldName": "payload.partnerTrxId",
            "operations": [
                "ocr",
                "idVerification"
            ]
        }
    ]
}
```

</details>

**If error is associated with groupId blank string is passed.**

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "errors": [
        {
            "message": "groupId must not be blank",
            "code": 5001,
            "fieldName": "payload.groupId",
            "operations": [
                "ocr",
                "idVerification"
            ]
        }
    ]
}
```

</details>

**If error is associated with operations calls**

In this scenario, the error is associated with an operation call, such as when no card is detected in an OCR operation:

<details>

<summary>Sample API Response</summary>

```json
{
  "errors": [
    {
      "message": "No Card Detected",
      "code": 5101,
      "operations": ["ocr"]
    }
  ]
}
```

</details>

**If any error occurred which is not associated with any operation**

This type of error represents an internal server error, not associated with any specific operation:

<details>

<summary>Sample API Response</summary>

```json
{
  "errors": [
    {
      "message": "Internal Server Error",
      "code": 5005
    }
  ]
}
```

</details>

**If error is associated with duplicate partner transactionId**

<details>

<summary>Sample API Response</summary>

```json
{
    "transactionId": "unique transation id generated by vida for the request",
    "partnerTrxId": "reference id supplied by customer",
    "groupId": "reference id to track complete KYC flow",
    "errors": [
        {
            "message": "Invalid request: Duplicate partnerTrxId",
            "code": 5003
        }
    ]
}
```

</details>

{% hint style="info" %}
Refer to the[ HTTP Status and Error Codes page](/identity-stack/verify/document-ai/ocr-and-document-verification/ocr-and-document-verification-v1/http-status-and-error-codes.md) for detailed list of status and error codes.
{% endhint %}
