# Server Documentation

## Credentials

Find your account's **secret key** and **API keys** in your [website manager](https://business.dentity.com/website-setting).

## API Endpoints

{% hint style="info" %}
**Note:**

* When you send a request, your phone will get an SMS to start the next process.
* If your account is not verified, you have to start the process to verify your account information by **Dentity**’s system first.
  {% endhint %}

## Create a new verification

<mark style="color:green;">`POST`</mark> `https://api.dentity.com/core/api/v1/verification`

This creates a new verification request from a customer’s information.

#### Headers

| Name                                        | Type   | Description      |
| ------------------------------------------- | ------ | ---------------- |
| x-api-key<mark style="color:red;">\*</mark> | String | Domain’s API Key |

#### Request Body

| Name                                          | Type   | Description                                                                                                                                                                |
| --------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key<mark style="color:red;">\*</mark>         | String | Your domain’s API Key.                                                                                                                                                     |
| metadata                                      | Object | <p>Custom variable Id or other information<br>{               "id":"sample\_15fa31da59f69041641984405622" </p><p>}<br></p>                                                 |
| callbackUrl                                   | String | Partner will get verification status when user start process to verify                                                                                                     |
| phoneNumber<mark style="color:red;">\*</mark> | Object | <p>Holder phone number. Object includes <strong>dialCode</strong> and <strong>phone</strong></p><p>{</p><p>    "dialCode": "+1", </p><p>    "phone": "2048089972"<br>}</p> |
| email                                         | String | Holder email.                                                                                                                                                              |
| dateOfBirth                                   | String | MM/DD/YYYY                                                                                                                                                                 |
| name                                          | String | <p>{<br> "firstName": "String", <br>  "lastName": "String" <br>},</p>                                                                                                      |
| address                                       | String | <p>{ </p><p>"street": "string",</p><p>"city": "string", </p><p>"state": "string", </p><p>"zip": "string", </p><p>"country": "string"</p><p> }</p>                          |
| smsMessage                                    | String | <p>Custom SMS content. The link is required. <br>E.g: {{siteName}} has requested that you verify your information: {{link}}</p>                                            |

{% tabs %}
{% tab title="200: OK Creating verification successfully" %}

```javascript
{
    "data": {
        "_id": "6333e7c08372cd0011d974aa", //Unique verification id
        "status": "pending" // pending, verified, failed
        "metadata": {
             "id": "15fa31da59f69041641984405622" // Custom variable Id
         }
    }
}
```

{% endtab %}

{% tab title="400: Bad Request Phone number and email already exist in 2 different accounts." %}

```javascript
{
   message: "The phone or email you entered does not match your account"
}  
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
**metadata:** We recommend passing in the metadata (*userId,email,trackId..*.) as a good way for you to compare the data received correctly with the data on your end.
{% endhint %}

## Get status of a verification request

<mark style="color:blue;">`GET`</mark> `https://api.dentity.com/core/api/v1/verification/:verificationId/status`

This returns the status of a verification request.

#### Path Parameters

| Name                                             | Type   | Description            |
| ------------------------------------------------ | ------ | ---------------------- |
| verificationId<mark style="color:red;">\*</mark> | String | Unique verification id |

#### Headers

| Name                                        | Type   | Description      |
| ------------------------------------------- | ------ | ---------------- |
| x-api-key<mark style="color:red;">\*</mark> | String | Domain’s API Key |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "data": {
        "_id": "6333e7c08372cd0011d974aa", //Unique verification id
        "status": "verified" //Verification status (pending, verified, failed)
        "user": {
            "firstName": "Jamie",
            "lastName": "Johnston",
            "email": "example@dentity.com"
        },
        "user": {
            "firstName": "Jamie",
            "lastName": "Johnston",
            "fullName": "Jamie Johnston",
            "email": "example@dentity.com",
            "phoneNumber": "0987654321",
            "dateOfBirth": "string",
            "addressDetail": {
                "street": "string",
                "country": "string",
                "city": "string",
                "state": "string",
                "zip": "string"
            }
        },
        "metadata": {
            "id": "15fa31da59f69041641984405622" //Custom variable Id
        }
    }
}
```

{% endtab %}

{% tab title="400: Bad Request Verification not found" %}

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**PDF file endpoint:** Get verification PDF file is not supported for all IDV provider. Please contact us before you start to use it.
{% endhint %}

## Get verification PDF file

<mark style="color:blue;">`GET`</mark> `https://api.dentity.com/core/api/v1/verification/:verificationId/pdf`

This returns the PDF file of a verification. The PDF file can only be obtained within 24 hours from the time of completing the IDV.

Depending on which Verification Agent you are using, there are two options for retrieving images and files from Dentity.  Please ask Dentity support which method is applicable for your account before integrating this API.

#### Path Parameters

| Name                                             | Type   | Description            |
| ------------------------------------------------ | ------ | ---------------------- |
| verificationId<mark style="color:red;">\*</mark> | String | Unique verification id |

#### Query Parameters

| Name        | Type    | Description                                                     |
| ----------- | ------- | --------------------------------------------------------------- |
| confidences | Boolean | Include Confidence Scores in the PDF. It's **false** by default |

#### Headers

| Name                                        | Type   | Description      |
| ------------------------------------------- | ------ | ---------------- |
| x-api-key<mark style="color:red;">\*</mark> | String | Domain’s API Key |

{% tabs %}
{% tab title="200: OK Get PDF of the verification successfully" %}

```json
{
    "data":{
        "pdf":"KQovQ3JlYXRvciAo/v8AdwBrAGg..." //PDF of the verification in base64
    }
}
```

{% endtab %}

{% tab title="400: Bad Request Verification not found" %}

{% endtab %}

{% tab title="400: Bad Request Out of time to get the pdf file" %}

{% endtab %}
{% endtabs %}

## Get bulk verifications

<mark style="color:green;">`POST`</mark> `https://api.dentity.com/core/api/v1/programmatic/credential/bulk`

Limit of 50 records in a request.

#### Request Body

| Name                                              | Type  | Description                                                              |
| ------------------------------------------------- | ----- | ------------------------------------------------------------------------ |
| verificationIds<mark style="color:red;">\*</mark> | Array | <p>\[<br>"62cd2660176d230010eeb491", "62cd36133fa924001195d809"<br>]</p> |

{% tabs %}
{% tab title="200: OK Get verifications successfully " %}

```json
{
    "data": {
        "totalItem": 2,
        "data": [
            {
                "status": "verified",
                "_id": "62cd36133fa924001195d809",
                "user": {
                    "firstName": "Lisa",
                    "lastName": "Lowse"
                },
                "metadata": {
                    "_id": "62cff0776fc2c200114773fe"
                }
            },
            {
                "status": "verified",
                "_id": "62ce91cd291e000011bc2adf",
                "user": {
                    "firstName": "Antoni",
                    "lastName": "Young"
                },
                "metadata": {
                    "_id": "62cff0776fc2c200114773ff"
                }
            }
        ],
        "page": 1,
        "pageSize": 2,
        "totalPage": 1
    }
}


```

{% endtab %}
{% endtabs %}

## Verification Webhook

In this case you will likely need to know when the customer is verified so that you can approve their order. This can be done using the **callbackUrl** option, which will make a request from our system to yours when the verification status is updated, such as when the verification is verified or failed.

We will send a **PUT request** to the **callback URL** with the following data in JSON format.

**Webhook type:**

<table><thead><tr><th width="221">Type</th><th>Description</th></tr></thead><tbody><tr><td>verification_status</td><td>Verification status change</td></tr><tr><td>email_delivery_status</td><td>Email delivery status change</td></tr><tr><td>sms_delivery_status</td><td>SMS delivery status change</td></tr></tbody></table>

1. **verification\_status** will be sent when the status of verification changes

{% hint style="info" %}
**idvImages** are not returned for all IDV providers. So contact us before you start using it.
{% endhint %}

```javascript
{
  "type": "verification_status",
  "_id": "6333e7c08372cd0011d974aa",
  "status": "verified",
  "user": {
    "firstName": "Jamie",
    "lastName": "Johnston",
    "fullName": "Jamie Johnston",
    "email": "example@dentity.com",
    "phoneNumber": "0987654321",
    "dateOfBirth": "string",
    "addressDetail": {
      "street": "string",
      "country": "string",
      "city": "string",
      "state": "string",
      "zip": "string"
    }
  },
  "metadata": {
    "id": "sample_15fa31da59f69041641984405622"
  },
  // idvImages are not returned for all IDV providers. So contact us before you start using it. 
  "idvImages": [
    {
      "category": "drivers_license",
      "images": {
        "cropped_back": null,
        "cropped_front": null,
        "face": "https://documentary-assets-production-sandbox-cognito-us-west-2.s3.us-west-2.amazonaws.com/flwses_5YcEVAaJhGHbmP/1/r/rLsqCopvKH675Klm.jpeg?response-content-disposition=attachment%3B%20filename%3Dface.jpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATAVOPDHKTR4VVYBD%2F20230520%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230520T044527Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=187a35670d9fe3b7d175a44b41c01a6ff5649f391febc3ae381022e0ec070207",
        "original_back": "https://documentary-assets-production-sandbox-cognito-us-west-2.s3.us-west-2.amazonaws.com/flwses_5YcEVAaJhGHbmP/1/back.jpeg?response-content-disposition=attachment%3B%20filename%3Doriginal_back.jpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATAVOPDHKTR4VVYBD%2F20230520%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230520T044527Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=206ed0b1c7dbfb436e515a0eba68649c7ceb866ba62bd9757747579dbe240a71",
        "original_front": "https://documentary-assets-production-sandbox-cognito-us-west-2.s3.us-west-2.amazonaws.com/flwses_5YcEVAaJhGHbmP/1/front.jpeg?response-content-disposition=attachment%3B%20filename%3Doriginal_front.jpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATAVOPDHKTR4VVYBD%2F20230520%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230520T044527Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=aaf53c1b1694ab2de0474c4ea240f8d53569798a557d9bee4c527a3fba096262"
      }
    }
  ]
}
```

2. **email\_delivery\_status** will be sent when the email sending status change

```json
{    
    "type": "email_delivery_status"
    "_id": "64708367f13bbe00118e82a3",
    "status": "pending",
    "emailDeliveryEvents": [
        {
            "email": "thangdd@vmodev.com",
            "timestamp": 1685095273,
            "status": "delivered"
        },
        {
            "email": "thangdd@vmodev.com",
            "timestamp": 1685095271,
            "status": "processed"
        }
    ]
}
```

Email delivery events include `processed`, `dropped`, `delivered`, `deferred`, and `bounce`.

<table><thead><tr><th width="168">Status</th><th>Description</th></tr></thead><tbody><tr><td>processed</td><td>Message has been received and is ready to be delivered.</td></tr><tr><td>dropped</td><td>You may see the following drop reasons: Invalid SMTPAPI header, Spam Content (if Spam Checker app is enabled), Unsubscribed Address, Bounced Address, Spam Reporting Address, Invalid, Recipient List over Package Quota</td></tr><tr><td>delivered</td><td>Message has been successfully delivered to the receiving server.</td></tr><tr><td>deferred</td><td>Receiving server temporarily rejected the message.</td></tr><tr><td>bounce</td><td>Receiving server could not or would not accept mail to this recipient permanently. If a recipient has previously unsubscribed from your emails, the message is dropped.</td></tr><tr><td>blocked</td><td>Receiving server could not or would not accept the message temporarily. If a recipient has previously unsubscribed from your emails, the message is dropped.</td></tr></tbody></table>

3. **sms\_delivery\_status**  Dentity will send an update to that URL every time the status changes; Values include `accepted`, `sending`, `sent`, `failed`,  and `delivered`.

```json
{
    "type": "sms_delivery_status",
    "_id": "64708367f13bbe00118e82a3",
    "status": "pending",
    "smsDeliveryEvents": {
        "to": "+16162904619",
        "status": "sent"
    }
}
```

The request will also have the “**Dentity-Signature**” header which should be used to verify that the request came from us. Below is an example in NodeJS:

{% tabs %}
{% tab title="Javascript" %}
{% code lineNumbers="true" %}

```javascript
const crypto = require('crypto');
function verifySignature(data, headers) {
 const key = headers['Dentity-Signature'];
 const hash = crypto
       .createHmac('sha256', 'SECRET KEY')
       .update(JSON.stringify(data))
       .digest('base64');
 return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(key));
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note:** If you would like to receive a webhook for all requests, contact us to set up an automatic webhook for your account.
{% endhint %}
