Skip to main content

Document Verification

Overview#

LoginID document scanning helps you confirm the identity of your users, allowing you to have increased confidence in who is using your platform, leading to a significant reduction in fraud.

In recent years there has been a significant increase in the need to remotely onboard new users in a secure manner. The industry best practice for performing this verification is by having the end user scan a government issued identity document and take a selfie. The system then ensures the user is the rightful owner of the document by checking the authenticity of the document and matching the picture on the document with the selfie taken by the user, leveraging a liveness detection algorithm.

At a high level, this flow consists of: creating a user profile without any credentials, going through a document scanning & selfie flow, then binding a FIDO2 credential to that account. This allows you to securely onboard a new user and authenticate them with confidence in a low friction manner going forward.

note

If you are interested in providing this experience to your users, please contact support@loginid.io

Prerequisites#

  • Backend / API application created on the dashboard with API credential assigned
  • Download Server SDK (optional)
  • Download Client SDK (optional)

With Server SDK#

Step 1: Create user profile without#

To initiate the document scanning flow, you must first create a profile for this user in the LoginID system. This allows you to ensure you’re adding the FIDO2 credential to the same user who completed the document scan.

Server SDK: .addUserWithoutCredentials(username)

This returns a `user_id`, which is used in several of the subsequent steps in this flow.

Step 2: Generate Code#

Once you have the user_id, you must generate a code. This code is what allows the customer to regain access to their account, as it lets them register a new credential. To understand which code_type is best for your use case, please see our guide on choosing a code type.

Server SDK: .initDocScan(user_id)

This returns a URL, which you can open in a new tab or as an iFrame on your existing page.

note

Document scanning has higher success rates on mobile devices than laptops due to the camera quality on the respective devices. The flow will prompt the user if they’d like to move to their mobile device, which is done through a QR code.

Step 3: Evaluate results#

After the end user has completed the document scan and selfie check, you can call this method to get the result and user’s details.

Server SDK: .evaluateDocScan

This will return a URL and auth token, to which you must make a GET call to receive the results. This GET call will return the user’s information and the details related to their document scan and selfie. This can be called multiple times as required.

Step 4: Complete document scan#

After evaluating the results, you have the option to have us store the selfie template for use at a later time. If the `activate_credential` flag is set, a biometric template will be stored for future use. Most commonly this template is used in the case of account recovery, when the user loses their registered authenticators. For more information, please see the guide on Account Recovery through a Selfie.

If you do not want the template to be stored for future use, you simply invoke this method and set the `activate_credential` flag to FALSE.

Server SDK: .completeDocScan

Step 5: Add FIDO2 credential#

Once the user has passed the document scan, they should be prompted to set up a FIDO2 authenticator. As this is the user’s first authenticator, you can initialize the addition of the authenticator directly, without going through the code authorization flow.

Server SDK: initAddCredentialWithoutCode

This returns the FIDO attestation challenge, which must be passed through to the browser to prompt the customer for FIDO authentication. Once the user completes the FIDO registration, you now have a securely onboarded customer and have extremely high assurance in who is accessing your platform.

Calling APIs Directly#

Step 1: Create user profile without credentials#

The required scope of the service token for this request is user.retrieve

Request:

POST /api/native/manage/users

Header:

Authorization: Bearer {authorization_token}

X-Client-ID: {client_id}

Body:

{
"username": "string"
}

The response is the user’s profile information (including the user_id) for the provided username.

Step 2: Initiate document scanning flow#

The required scope of the service token for this request is credentials.force_add

Request:

POST /api/native/credentials/authid/init

Header:

Authorization: Bearer {authorization_token}

Body:

{
"client_id": "string",
"user_id": "string",
"options": {
"credential_name": "string"
}
}

Where:

  • client_id: generated on the LoginID dashboard.
  • user_id: ID of an already registered user. In this case it would be the user_id of the person trying to add a new device.
  • credential_name: The name to be assigned to the credential, if not provided, a default name will be assigned to it.

Response:

{
"credential_uuid": "string",
"iframe_url": "string"
}

Step 3: Evaluate results#

The required scope of the service token for this request is credentials.retrieve_sensitive

Request:

POST /api/native/credentials/authid/evaluate

Header:

Authorization: Bearer {authorization_token}

Body:

{
    "client_id": "string",
    "user_id": "string",
    "credential_uuid": "string"
}

Where:

  • client_id: generated on the LoginID dashboard.

  • user_id: ID of an already registered user. In this case it would be the user_id of the person trying to add a new device.

  • credential_uuid: The credential unique identifier that you can retrieve from the response of the /init endpoint.

    \

Response:

{
"result_url": "https://...",
"token_type": "Bearer",
"auth_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZ...."
}

Step 4: Complete document scan#

The required scope of the service token for this request is credentials.force_add

Request:

POST /api/native/credentials/authid/complete

Header:

Authorization: Bearer {authorization_token}

\n Body:

{
    "client_id": "string",
    "user_id": "string",
    "credential_uuid": "string",
    "activate_credential": false
}

Where:

  • client_id: generated on the LoginID dashboard.

  • user_id: ID of an already registered user. In this case it would be the user_id of the person trying to add a new device.

  • credential_uuid: The credential unique identifier that you can retrieve from the response of the /init endpoint.

  • activate_credential: Indicates whether you want to persist the credential or not.

    \

Response:

{
"credential_uuid": "b7bd9990-2c43-4dce-9286-93cccf81bc62",
"username": "john.doe",
"namespace_id": "07523c4752bc7168"
}