# Getting started

ID Scan is a service to perform online ID verifications. This documentation focuses on the <<glossary:API>> integration.

For a complete technical documentation with specifications for all field types, <<glossary:JSON>> objects and methods, you can consult our complete API reference: [API reference](https://developers.cm.com/verification/reference/post_transactions)

If you need technical assistance, please contact your account manager or support (<support@cm.com>).

# Service description

## Transactions

A transaction is a collection of information related to the ID verification process. It consists of tasks and settings.

## Task

A task is an action that needs to be performed by the end user.

# Environment

The base URL for all API requests:

Production: `https://api.cm.com/id-scan/v1/`

# Usage

The steps for using the service are:

* [Create a transaction](https://developers.cm.com/verification/docs/create-transaction)  with tasks.
* [Load the transaction URL](https://developers.cm.com/verification/docs/create-transaction#integrate-on-website) in an iframe on your website.
* The end user will perform the transaction tasks.
* After all tasks are completed, a JavaScript event is sent with the result ID.
* [Listen for the event](https://developers.cm.com/verification/docs/id-scan-events)  with the result ID.
* [Retrieve the data](https://developers.cm.com/verification/docs/transaction-result)  using the result ID.
* *Optional: download [document images](https://developers.cm.com/verification/docs/transaction-result#download-document-image) or the [audit report](https://developers.cm.com/verification/docs/transaction-result#retrieve-audit-report)*

# Authentication

Before you can start using the API, you need API credentials. Credentials consist of a key ID and secret. Contact your account manager to get production credentials. Credentials should be kept secret.

In order to authenticate you need to use your credentials to generate a <<glossary:JWT>> <<glossary:Bearer token>>. The [JWT token](https://jwt.io/introduction/) has to be generated using the `HS256` algorithm and your credentials. This JWT has to contain the following attributes: `iat`, `nbf`, and `exp` in the payload, as well as the attribute `kid` in the header of the JWT. This `kid` attribute needs to contain the Key ID of your credentials.

The generated token needs to be passed via the HTTP Authorization header:

```
Authorization: Bearer GENERATED_TOKEN_HERE
```

There are many libraries available for different programming languages that can help you to generate a JWT. See the Libraries tab on <https://jwt.io>.

**Example**

Assuming we want to create a token that is valid for 60 seconds and we have received the following credentials:

Key ID: `3b438437-04a4-40bb-8389-54bb02766fba`\
Secret: `AC4Etykn7jusGR5FwLDAtILtQbiQbTMKedP31szXg4WlSbjGEXyNMZ`

We need to create a JWT with the following properties:

JWT header:

```json
{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "3b438437-04a4-40bb-8389-54bb02766fba"
}
```

JWT payload:

```json
{
    "iat": 1546300800,
    "nbf": 1546300800,
    "exp": 1546300860
}
```

* `iat`: the time when the token was generated.
* `nbf`: the time after which the token is valid, usually equal to `iat`.
* `exp`: the time when the token will expire.

> 📘
>
> Make sure these are UNIX timestamps in seconds

This results in the following token:

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjNiNDM4NDM3LTA0YTQtNDBiYi04Mzg5LTU0YmIwMjc2NmZiYSJ9.eyJpYXQiOjE1NDYzMDA4MDAsIm5iZiI6MTU0NjMwMDgwMCwiZXhwIjoxNTQ2MzAwODYwfQ.bwqCUHS1d5d8guAPHDsdd9-a8oXxH1q45O0tDP1asTo
```

Add this token to the `Authorization` header in the API request.

```
Authorization: Bearer GENERATED_TOKEN_HERE
```

> The <https://jwt.io> website provides a way to inspect or validate JWT tokens.

# Branding

The ID Scan UI can be customized to match your brand or website theme. Contact us to have this configured.

| Option           | Description                                                              |
| :--------------- | :----------------------------------------------------------------------- |
| Primary color    | The accent color, for example used for buttons.                          |
| Background color | Background color of the frame/page.                                      |
| Text color       | Heading and body text color.                                             |
| Font             | Heading and body font family (must be web safe or a generic font family) |

# Error handling

## Generic

When a 4xx or 5xx error occurs, you will receive a JSON response describing the error.

Example:

```json
{
    "status": 400,
    "message": "Error message"
}
```

## Document scan errors

The table below specifies each possible error response during a document scan task along with a description and reason it might occur.

[block:parameters]
{
  "data": {
    "h-0": "Error in response",
    "h-1": "Description",
    "0-0": "processing",
    "0-1": "**Error occurred while processing the document**  \nAn (unexpected) problem occurred on the server.",
    "1-0": "unknown_type_front",
    "1-1": "**Front side of document was not recognized**  \nImage/scan quality was not sufficient for document recognition.",
    "2-0": "unknown_type_back",
    "2-1": "**Back side of document was not recognized**  \nImage/scan quality was not sufficient for document recognition.",
    "3-0": "expiration_criteria_not_met",
    "3-1": "**Document was expired**  \nThe document has been found to have expired according to the expiration date indicated on it, as per the set criteria. By default, this refers to the current date.",
    "4-0": "unable_to_determine_date_of_expiry",
    "4-1": "**Unable to determine expiry date on the document**  \nWhile the image/scan quality was sufficient for document recognition, it was either still of poor quality or masked, resulting in this field being unreadable.",
    "5-0": "text_fields_analysis_failed",
    "5-1": "**Document fields failed to be detected**  \nWhile the image/scan quality was sufficient for document recognition, it was still of poor quality, resulting in all OCR fields being unreadable.",
    "6-0": "age_criteria_not_met",
    "6-1": "**Transaction aborted due to user's age**  \nThe user's age does not meet the criteria set for the transaction, as determined from the age field on the document.",
    "7-0": "unable_to_determine_age",
    "7-1": "**Unable to determine age on the document**  \nWhile the image/scan quality was sufficient for document recognition, it was either still of poor quality or masked, resulting in this field being unreadable.",
    "8-0": "field_validation_failed",
    "8-1": "**Document data was invalid**  \nThe field from the document was found to be invalid (incorrect social security number formats or impossible values), suggesting the possibility of a fake or tampered document.",
    "9-0": "front_side_provided_back_side_required",
    "9-1": "**Back side of the document is required**  \nThe front side of the document has been provided, but the back side of the document is also required.",
    "10-0": "back_side_provided_front_side_required",
    "10-1": "**Front side of the document is required**  \nThe back side of the document has been provided, but the front side of the document is also required.",
    "11-0": "image_quality_requirements_not_met",
    "11-1": "**Image quality requirements were not met**  \nOne or more of the image quality checks enabled for your account failed. See [image quality checks](https://developers.cm.com/verification/docs/id-scan-configuration#image-quality-checks)."
  },
  "cols": 2,
  "rows": 12,
  "align": [
    "left",
    "left"
  ]
}
[/block]

> 📘 Other side required occasions
>
> Another side/page of the document may be required in the following scenarios:
>
> * ID-1 size documents (most ID cards and driving licenses) was detected
> * `requireBothSides` setting enabled
> * <<glossary:MRZ>> not found
> * Date of expiry not found
> * Date of birth not found and `minimumAge` or `maximumAge` settings were included

# Invoicing

Not all document scan tasks are invoiced. To help clarify what exactly is invoiced during a document scan task, the table below specifies each possible error response during a document scan task and whether it will be invoiced. As of the 1st of January 2025, only one document scan attempt will be invoiced per transaction.

| Error in response                           | Invoiced |
| :------------------------------------------ | :------- |
| processing                                  | No       |
| unknown\_type\_front                        | No       |
| unknown\_type\_back                         | No       |
| expiration\_criteria\_not\_met              | Yes      |
| unable\_to\_determine\_date\_of\_expiry     | Yes      |
| text\_fields\_analysis\_failed              | Yes      |
| age\_criteria\_not\_met                     | Yes      |
| unable\_to\_determine\_age                  | Yes      |
| field\_validation\_failed                   | Yes      |
| front\_side\_provided\_back\_side\_required | Yes      |
| back\_side\_provided\_front\_side\_required | Yes      |
| image\_quality\_requirements\_not\_met      | Yes      |
| *null*                                      | Yes      |

All *executed* face liveness and face match tasks are invoiced, regardless of the final state.