API Integration of BioGovID

Overview

This guide will show you how to use the AXN Verify API to verify an individual by BioGovID.

πŸ“˜

Prerequisites

  • Deploy the "BioGovID" Workflow by following the directions here.
  • Obtain the access keys for your new workflow by following the directions here
  • Download and use the BioGovID Postman Project to try it out

πŸ“˜

An example BioGovID application is also made available for you to download here

What you'll do:

  • Create a dropdown on your user interface to allow the end user to select either Driver's License, Passport or ID Card (Step 2).
  • Collect the Full Name and Personal Mobile Phone Number of the end user.
    • The phone number will be used to send a link to the user (Step 3).
    • The Full Name will be matched to the document (Step 5).

1. Get Access Token

(POST) https://api.preprod.iddataweb.com/v1/token

API Reference: https://docs.iddataweb.com/reference/auth

This access token is used to authenticate your requests. Place this token in the header of each subsequent request. See the postman project above for examples.

Locate your workflow's access keys


Then, to request an access token:


var axios = require('axios')

var user = 'Your Workflow API Key';
var password = 'Your Workflow Shared Secret';

var base64encodedData = Buffer.from(user + ':' + password).toString('base64');

var request = async () => {
  var response = await axios({
    url: 'https://api.preprod.iddataweb.com/v1/token',
    method: 'post',
    params: {
      grant_type: 'client_credentials'
    },
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache',
      Authorization: 'Basic ' + base64encodedData
    }
  })
  console.log(response.data);
}
request();

Response


{
    "errorCode": "",
    "errorDescription": "",
    "access_token": "TjZK7NSjw24AxGK9UhOE9uJDaZT23gKYuUC-9GMTAgLU", // your access token
    "expires_in": "1800",
    "token_type": "Bearer"
}

1.1. Country Selection

(POST) https://api.preprod.iddataweb.com/v1/slverify

API Reference: https://docs.iddataweb.com/reference/slverify

Once you've received an access token, you'll need to check if the user is located in a country supported by our services.

Using the same API Key as before, prompt the user to select a country, and if the country is supported, your response will contain the API Key required to take the next step in MobileMatch verification.


Request


var data = {
	"apikey": "Your API Key",
    "credential": "e.g. : [email protected]",
    "appID":"Your App Name, (e.g. 'Employee Onboarding App')",
    "userAttributes": [
        {
            "attributeType": "Country",
            "values": {
                "country": "US" // accepted values: (country codes) e.g. "US", "MX", "AU" ....
            }
        }
    ]
}

var axios = require('axios')
var token = 'YOUR_BEARER_TOKEN' // -- obtained from step 1 --

var request = async () => {
  var response = await axios({
    url: 'https://api.preprod.iddataweb.com/v1/slverify',
    method: 'post',
    data: data,
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache',
      Authorization: 'Bearer ' + token,
    }
  })
	console.log(response.data)
}
request();

Response


{
    "errorCode": "",
    "errorDescription": "",
    "transaction_id": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
    "userAttributes": [
        {
            "attributeType": "Country",
            "dateCreated": "11/08/2022 17:26:36",
            "values": {
                "country": "US"
            }
        }
    ],
    "acquiredAttributes": null,
    "userAssertionList": [
        {
            "provider": "Threatmetrix",
            "serviceOffering": "Threatmetrix Session Query Low Location Accuracy",
            "dateAsserted": "11/08/2022 17:26:37",
            "assertions": {
                "blacklist.device": "unverified",
                "blacklist.ofacIP": "unverified",
                "test.gte3Credential1d": "unverified",
                "detect.browserAnomaly": "unverified",
                "test.gte5Credential1d": "unverified",
                "test.lte3ProxyToday": "unverified",
                "test.trustedDevice6mo": "unverified",
                "test.trustedDevice": "unverified",
                "detect.possibleVPNOrTunnel": "unverified",
                "test.lte3CredentialsDevice7d": "unverified",
                "test.gte5Device1d": "unverified",
                "link.timeZone_TrueGeo": "unverified",
                "test.gte5CredentialDevice1d": "unverified",
                "test.credentialLTE500mi1hr": "unverified",
                "detect.vpn": "unverified",
                "test.exactIDAgeGTE7d": "unverified",
                "test.trueIPLTE500miInputIP": "unverified",
                "detect.proxyAnonymous": "unverified",
                "test.apSessionIDNotReplay": "unverified",
                "detect.jailbreak": "unverified",
                "link.proxyOrg_TrueOrg": "unverified",
                "test.expectedLanguage": "unverified",
                "blacklist.ip": "unverified",
                "detect.malware": "unverified",
                "detect.torExitNode90d": "unverified",
                "test.gte10Credential1d": "unverified",
                "detect.mobileTethering": "unverified",
                "test.trustedDevice28days": "unverified",
                "test.gte20Credential1d": "unverified",
                "detect.aggregator": "unverified",
                "test.smartIDAgeGTE7d": "unverified",
                "detect.proxyOpenTransparent": "unverified",
                "detect.unusualActivity": "unverified",
                "detect.proxyHidden": "unverified",
                "link.proxyISP_TrueISP": "unverified",
                "detect.tor": "unverified",
                "detect.torNode": "unverified",
                "detect.knownVPNISP": "unverified",
                "link.proxyGeo_TrueGeo": "unverified",
                "test.gte2Credential1d": "unverified"
            }
        }
    ],
    "mbun": "xxxxxx-xxxx-xxxx-xxxx-xxxxxx",
    "forwardApiKey": "324e1d4975f40c5", // Your Next API Key
    "policyObligation": true,
    "policyDecision": "obligation"
}

πŸ“˜

NOTE:

The output above includes additional information from our Device Profiling service.

Device Profiling is the process of screening the Device and User Activity of a new transaction (user session).

If a transaction is found to be high risk (fraud), you'll be alerted of any fraudulent activity found, and the transaction will be prevented from proceeding further. Device Profiling requires an embedded script to run. Without it, assertions will be marked "unverified".

For more information on Device Profiling

2. Select Document Type

(POST) https://api.preprod.iddataweb.com/v1/slverify

API Reference: https://docs.iddataweb.com/v1.0/reference/slverify

Prompt the user to select a Document Type, then send their selection to /slverify. The response you receive will include the API Key required to capture the document type selected.

πŸ‘

Each step has a designated API Key.

Each key is designed to return the API key required for the next step. This key is called your forwardApiKey.

In the response body of your last request, you'll find your next forwardApiKey.


Request


var data = {
	"apikey": "Your BioGovID (Picker) API Key", // -- obtained from step 1.1 --
    "asi": "xxxxx-xxxx-xxxx-xxxx-xxxxx", // -- obtained from step 1.1 --
    "credential": "user@email",
    "appID":"your-application-name",
    "userAttributes": [
        {
            "attributeType": "LicensePassportOrIDCard",
            "values": {
                "licensePassportOrIDCard": "your-biogovid-preference" // -- 'passport', 'license', 'idcard' --
            }
        }
    ]
}

var axios = require('axios')
var token = 'YOUR_BEARER_TOKEN' // -- obtained from step 1 --

var request = async () => {
  var response = await axios({
    url: 'https://api.preprod.iddataweb.com/v1/slverify',
    method: 'post',
    data: data,
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache',
      Authorization: 'Bearer ' + token,
    }
  })
	console.log(response.data)
}
request();

Response


{
    "errorCode": "",
    "errorDescription": "",
    "transaction_id": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
    "userAttributes": [
        {
            "attributeType": "LicensePassportOrIDCard",
            "dateCreated": "11/10/2022 16:35:38",
            "values": {
                "licensePassportOrIDCard": "license"
            }
        }
    ],
    "acquiredAttributes": null,
    "userAssertionList": null,
    "mbun": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
    "forwardApiKey": "ff16c345c324898", // -- Your next API key, based on the document type selected -- 
    "policyObligation": true,
    "policyDecision": "obligation"
}

3. Send Document Capture Link

(GET) https://api.preprod.iddataweb.com/v1/doccapture/sendlink

API Reference: https://docs.iddataweb.com/reference/doccapturesendlink

The endpoint /doccapture/sendlink sends a document capture link to the end user's Phone Number via SMS. Prompt the user to enter their phone number. Once submitted, the user will then receive a link to capture images of their BioGovID, and a picture of themself.


Request


var params = {
  "dialCode": "1",
  "telephone":"1234567890",
  "credential":"[email protected]",
  "apikey": "YOUR_BIOGOVID_API_KEY", // -- obtained from step 2 -- 
  "asi": "xxxxx-xxxx-xxxx-xxxx-xxxxx"
}

var axios = require('axios')
var token = 'YOUR_BEARER_TOKEN' // -- obtained from step 1 --

var request = async () => {
  var response = await axios({
    url: 'https://api.preprod.iddataweb.com/v1/doccapture/sendlink',
    method: 'get',
    params: params,
    headers: {
      "Content-Type": "application/json",
      "Cache-Control": "no-cache",
      Authorization: 'Bearer ' + token 
    }
  })

  console.log(response.data)
}

request();

Response


{
    "responseCode": "200",
    "errorDescription": null,
    "asi": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
    "status": "success"
}

4. Get Captured Documents

(GET) https://api.preprod.iddataweb.com/v1/doccapture/results

API Reference: https://docs.iddataweb.com/reference/doccaptureresults

The endpoint /doccapture/results returns the images captured by the user.

πŸ“˜

IMPORTANT.

Your application will need to make requests against the API every few seconds until the user finishes the capture process on their mobile device. Keep calling the API until you get "status": "success". Most customers do this every 2-5 seconds.

Example:

Request

var params = {
  asi: 'xxxxx-xxxx-xxxx-xxxx-xxxxx', // -- obtained from step 1.1 --
};

var axios = require("axios");
var token = 'YOUR_BEARER_TOKEN'; // -- obtained from step 1 --

var request = async () => {
  var response = await axios({
    url: "https://api.preprod.iddataweb.com/v1/doccapture/results",
    method: "get",
    params: params,
    headers: {
      "Content-Type": "application/json",
      "Cache-Control": "no-cache",
      Authorization: "Bearer " + token,
    },
  });
   return response.data
};

var timeout = Date.now() + (15 * 60 * 1000) // timeout after 15 minutes.

var session = setInterval(async () => {
  if (Date.now() > timeout){ // If the user has timed out, return.
    clearInterval(session)
    return
  }
 
  var documents = await request(); // Request the user's uploaded documents.
  var status = documents.status // Request the status of the user's session.

  if (status === 'success'){ // If the user has successfully uploaded their documents,
    clearInterval(session)
    console.log(documents)
    return 
  }
  console.log('waiting for documents ....')
}, 3000) // Request a new status update every 3 seconds.

Response (during session)


{
    "responseCode": null,
    "errorDescription": "Status is not yet complete.",
    "asi": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
    "status": "pending",
    "urls": {}
}

Response (once session has completed)


{
  responseCode: '200',
  errorDescription: '',
  asi: 'xxxxx-xxxx-xxxx-xxxx-xxxxx',
  status: 'success',
  urls: {
    frontImage: 'https://preprod1.iddataweb.com/axn/api/file/e0950d....',
    cameraSnapshot: 'https://preprod1.iddataweb.com/axn/api/file/e0950d....',
    backImage: 'https://preprod1.iddataweb.com/axn/api/file/e0950d....'
  }
}

5. Verify

(POST) https://api.preprod.iddataweb.com/v1/slverify

API Reference: https://docs.iddataweb.com/v1.0/reference#slverify

Lastly, you'll submit the user's captured images and PII (Personal Information) to /slverify for final verification.


Request


var data = {
  asi: "xxxxx-xxxx-xxxx-xxxx-xxxxx", // -- obtained from step 1.1 --
  credential: "[email protected]",
  userAttributes: [
    {
      attributeType: "DriversLicenseImages",
      values: {
        frontImage:
          "https://preprod1.iddataweb.com/axn/api/file/e0950d....",
        backImage:
          "https://preprod1.iddataweb.com/axn/api/file/e0950d....",
      },
    },
    {
      attributeType: "CameraSnapshot",
      values: {
        cameraSnapshot:
          "https://preprod1.iddataweb.com/axn/api/file/e0950d....",
      },
    },
    {
      attributeType: "FullName",
      values: {
        fname: "John",
        lname: "Smith",
        mname: "",
      },
    },
    {
      attributeType: "InternationalTelephone",
      values: {
        dialCode: "1",
        telephone: "1234567890",
      },
    },
    {
      attributeType: "Country",
      values: {
        "country": "US"
      }
    }
  ],
};

var axios = require("axios");
var token = "YOUR_BEARER_TOKEN" // -- obtained from step 1 --

var request = async () => {
  var response = await axios({
    url: "https://api.preprod.iddataweb.com/v1/slverify",
    method: "post",
    data: data,
    headers: {
      "Content-Type": "application/json",
      "Cache-Control": "no-cache",
      Authorization: "Bearer " + token,
    },
  });
  console.log(response.data);
};
request();

Response

{
  errorCode: '',
  errorDescription: '',
  transaction_id: 'xxxxx-xxxx-xxxx-xxxx-xxxxx',
  userAttributes: [
    {
      attributeType: 'FullName',
      dateCreated: '10/31/2022 19:56:59',
      values: [Object]
    },
    {
      attributeType: 'InternationalTelephone',
      dateCreated: '10/31/2022 19:56:59',
      values: [Object]
    },
    {
      attributeType: 'Country',
      dateCreated: '10/31/2022 19:56:59',
      values: [Object]
    }
  ],
  acquiredAttributes: null,
  userAssertionList: [
    {
      provider: 'Threatmetrix',
      serviceOffering: 'Threatmetrix Session Query Low Location Accuracy',
      dateAsserted: '10/31/2022 19:57:00',
      assertions: [Object]
    }
  ],
  mbun: 'xxxxx-xxxx-xxxx-xxxx-xxxxx',
  forwardApiKey: '',
  policyObligation: false,
  policyDecision: 'approve' // expect values: 'approve', 'deny'
}

Result

If the policyDecision = approve , the user has been approved. Additional information on the SLVerify output(s) can be found here.

For instructions on how to test this workflow (including real user data), please visit: Testing BioGovID Only