Getting started

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

For a complete technical documentation with specifications for all field types, JSON objects and methods, you can consult our complete API reference: API reference

If you need technical assistance, please contact your account manager or support ([email protected]).

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 with tasks.
  • Load the transaction URL 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 with the result ID.
  • Retrieve the data using the result ID.

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 JWT Bearer token. The JWT token 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:

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

JWT payload:

{
    "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.

Create a transaction

POST https://api.cm.com/id-scan/v1/transactions

Request headers

Content-Type: application/json
Authorization: Bearer GENERATED_TOKEN_HERE

Request body

{
    "tasks": [
        "document_scan",
        "face_liveness",
        "face_match"
    ],
    "settings": {
        "documentScan": {
            "redactFields": ["personal_number"]
        }
    },
  	"locale": "nl-NL",
    "mobileOnly": true,
    "expiresIn":3600
}

Response body

{
    "id": "c3b92333-3935-4c15-a95e-8eb0051e644b",
    "state": "pending",
    "tasks": [
        "document_scan",
        "face_liveness",
        "face_match"
    ],
    "settings": {
        "documentScan": {
            "redactFields": [
                "personal_number"
            ]
        }
    },
    "url": "https://api.cm.com/id-scan/v1/nl-nl/identifications/zAWtVwkuYVDJKg...",
  	"locale": "nl-NL",
    "mobileOnly": true,
    "expires": "2022-01-01T13:00:00+00:00",
    "created": "2022-01-02T13:00:00+00:00"
}

Task types

TypeDescription
document_scanUpload or take a photo of the front and back side of an ID document.
face_livenessLiveness check using the camera.
face_matchCompares the photo on the ID document with the photo taken during the liveness check.

Valid combinations

  • document_scan
  • document_scan, face_liveness
  • document_scan, face_liveness, face_match

Settings

Configure the task behavior. For example, change the allowed document expiration or redact fields from the downloaded document image.

{
  	<other fields omitted for readability>
    "settings": {
        "documentScan": {
            "redactFields": [
                "personal_number",
              	"signature"
            ],
            "allowedExpiration": 30
        }
    }
}

Locale

Sets the language of the transaction. Currently supports English en-US, Dutch nl-NL, and French fr-FR. This setting is optional. By default, a transaction is in English en-US.

{
  	<other fields omitted for readability>
    "tasks": [
        "document_scan"
    ],
  	"locale": "nl-NL"
}

Mobile only

Controls whether a user is forced to use a mobile device to complete all task for the transaction. When set to true a user is forced to use a mobile device and when set to false a user can also use a non-mobile device like a desktop. This setting is optional. By default, this is false.

{
  	<other fields omitted for readability>
    "tasks": [
        "document_scan"
    ],
    "mobileOnly": true
}

Expires in

Set the time in seconds after which a transaction expires. The number of seconds can be between 3600 (1 hour) to a maximum of 86400 seconds (24 hours). This setting is optional. By default a transaction will expire after one hour.

{
  	<other fields omitted for readability>
    "tasks": [
        "document_scan"
    ],
    "expiresIn": 7200
}

Integrate on website

Integration with iframe

Add an iframe to your website with the transaction URL.

<iframe src="TRANSACTION_URL_HERE" width="650" height="600" allow="camera"></iframe>

πŸ“˜

Make sure the minimum width is set to 650 to ensure there is enough space for the embedded page.

Add an event listener on the page to retrieve a notification when the transaction completes.

<script>
  window.addEventListener('message', function (e) {
    const transactionId = e.data.transactionId;
    const state = e.data.state;
    const resultId = e.data.resultId;
    // now send the resultId to your backend and retrieve the result
  });
</script>

Integration with return URL

Create the transaction with return URL and scan return URL.

{
    "tasks": [
        "document_scan"
    ],
    "returnUrl": "https://example.com",
    "scanReturnUrl": "https://example.com"
}

Redirect the user to the url returned in the transaction response.

After the transaction is completed the user is redirected to the returnUrl. The query parameters trxid and resultid are appended to the URL. Use transaction ID in combination with the result ID to retrieve the transaction result.

The scanReturnUrl is used to redirect the user back to your own status page. This is only used when the QR code is scanned and the user completes the transaction on a mobile device. When no URL is set a default status page is shown.

Retrieve transaction result

When all tasks are completed by the end user you get the result ID from the notification or as query parameter in the return URL. Use this result ID in combination with the transaction ID to retrieve the transaction results. It is recommended to use the mrz source if available for a given field, as this will contain the most accurate value.

Request headers

Authorization: Bearer GENERATED_TOKEN_HERE

GET https://api.cm.com/id-scan/v1/transactions/{transactionId}/results/{resultId}

Response

{
    "id": "c3b92333-3935-4c15-a95e-8eb0051e644b",
    "state": "completed",
    "tasks": [
        {
            "type": "document_scan",
            "state": "completed",
            "score": 0.86,
            "result": [
                {
                    "field": "document_number",
                    "locale": null,
                    "values": [
                        {
                            "source": "mrz",
                            "value": "SPECI2021"
                        },
                        {
                            "source": "visual",
                            "value": "SPECI2021"
                        }
                    ]
                },
                {
                    "field": "given_names",
                    "locale": null,
                    "values": [
                        {
                            "source": "mrz",
                            "value": "WILLEKE LISELOTTE"
                        },
                        {
                            "source": "visual",
                            "value": "WILLEKE LISELOTTE"
                        }
                    ]
                },
                {
                    "field": "given_names",
                    "locale": "nl-NL",
                    "values": [
                        {
                            "source": "visual",
                            "value": "Willeke Liselotte"
                        }
                    ]
                },
                {
                    "field": "nationality",
                    "locale": null,
                    "values": [
                        {
                            "source": "mrz",
                            "value": "Netherlands"
                        }
                    ]
                },
                {
                    "field": "nationality",
                    "locale": "nl-NL",
                    "values": [
                        {
                            "source": "visual",
                            "value": "Nederlandse"
                        }
                    ]
                },
              	<other fields omitted for readability>
            ],
            "files": [
                {
                  	"category": "document",
                  	"type": "DRIVING_LICENSE",
                    "name": "Netherlands - Driving License (2022)",
                  	"score": 0.85,
                    "url": "https:\/\/api.cm.com\/id-scan\/v1\/downloads\/pz6vLGjX9OOOsiQxEY..."
                },
                {
                  	"category": "document",
                  	"type": "DRIVING_LICENSE",
                    "name": "Netherlands - Driving License (2022) Side B",
                  	"score": 0.87,
                    "url": "https:\/\/api.cm.com\/id-scan\/v1\/downloads\/55mrqZQhtp1wa3a1uC..."
                },
              	{
                  	"category": "image",
                    "type": "portrait",
                    "url": "https:\/\/api.cm.com\/id-scan\/v1\/downloads\/YNBQ0V4nofRehT8e2Y..."
                }
            ]
        },
        {
            "type": "face_liveness",
            "state": "completed"
        },
        {
            "type": "face_match",
            "state": "completed",
            "score": 0.877
        }
    ]
}

πŸ“˜

This example only shows a small section of field types in results. For a full list of all fields see the API reference.

Download document image

The URL in the files section for the document_scan task contains the URLs of the document images.

Request headers

Authorization: Bearer GENERATED_TOKEN_HERE
GET https://api.cm.com/id-scan/v1/downloads/pz6vLGjX9OOOsiQxEY...

Response

Binary image

Retrieve transaction report

Once the transaction is completed, you can retrieve an audit report.

This audit report is available to be retrieved by using the transaction ID of the completed transaction as well as the result ID from the notification or return URL query parameter.

There are two types of audit reports: simple and extended.

Request headers

Authorization: Bearer GENERATED_TOKEN_HERE

Response

Downloadable PDF file.

Simple audit report

The simple report is created when the transaction is completed. This report is always retrievable.

It contains no documents and is not sealed.

GET https://api.cm.com/id-scan/v1/transactions/{transactionId}/report/{resultId}

Extended audit report

The extended report is available to be created on request, only within the validity period of the transaction.

After the transaction expires, the extended report will not be able to be retrieved.

It contains all the scanned documents from the transaction and will be digitally sealed. Specify the type=extended query parameter to request this report.

GET https://api.cm.com/id-scan/v1/transactions/{transactionId}/report/{resultId}?type=extended

Events

To get notified when a transaction is completed or other events occurred, you can subscribe to events.
See: Events

Error handling

When an error occurs, you will receive a JSON response describing the error. The error codes per endpoint can be found in the API reference.

Example:

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