API Integration of BioGovID with Status Polling
Overview
This guide will show you how to use the AXN Verify API to verify an individual via. BioGovID w/ polling.
Prerequisites
- Deploy the "Incode" Workflow by following the directions here.
- Obtain the access keys for your new workflow by following the directions here
- Download and use the Incode Postman Project to try it out
What you'll do:
- UI/UX : Create a dropdown on your user interface to allow the end user to select whether to send link via Email or Text Message (Step 2).
- Specify the redirect page your users return to.
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"
}
2. Get / Send Incode Link
(POST) https://api.preprod.iddataweb.com/v1/async-ui/send-link
& (POST) https://api.preprod.iddataweb.com/v1/async-ui/get-link
API Reference: https://docs.iddataweb.com/reference/slverify
Once you've received an access token, you'll use it to send an Incode Capture link to your end user.
Using the same API Key as before, prompt the user to select whether to send the link via Email or Text Message. Then, using their selection, make the appropriate request.
TIP:
You can optionally generate a link and not have it sent to your end user automatically. That way, you can control how this link is provided. See /get-link
To generate and deliver the link automatically, see /send-link
Request: /send-link
var data = {
"apikey": "Your API Key",
"credential": "e.g. : [email protected]",
"appID":"Your App Name, (e.g. 'Employee Onboarding App')",
"userAttributes": [
/** -- Only include one of the below options as "userAttributes": [] -- **/
// Option 1: Send Capture Link via. Text Message
// --- start option: 1 ---
{
"attributeType": "InternationalTelephone",
"values": {
"dialCode": "1",
"telephone": "1234567890"
}
},
{
"attributeType": "FullName",
"values": {
"fname": "first_name",
"mname": "",
"lname": "last_name"
}
},
// --- end option: 1 ---
// Option 2: Send Capture Link via. Email
// --- start option: 2 ---
{
"attributeType": "Email",
"values": {
"email": "[email protected]"
}
},
{
"attributeType": "FullName",
"values": {
"fname": "first_name",
"mname": "",
"lname": "last_name"
}
}
// --- end option: 2 ---
]
}
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/async-ui/send-link',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
Authorization: 'Bearer ' + token,
}
})
console.log(response.data)
}
request();
Request: /get-link
var data = {
"apikey": "Your API Key",
"credential": "e.g. : [email protected]",
"appID":"Your App Name, (e.g. 'Employee Onboarding App')",
"userAttributes": [] // Note: for /get-link, userAttributes (e.g. email, telephone) is not required and can be left blank.
}
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/async-ui/get-link',
method: 'post',
data: data,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
Authorization: 'Bearer ' + token,
}
})
console.log(response.data)
}
request();
Response
/** Depending on the endpoint used **/
// Response: to /send-link
{
"services": [
{
"name": "Incode BioGovID Verification",
// Creates and delivers link.
"status": "delivered",
"apSessionId": "34523008-c5a3-4ca0-93452-2z5mbd10"
}
],
"asi": "4e234574e8-c706-45eb-b648-effdb90ff31a7"
}
// Response: to /get-link
{
"services": [
{
"name": "Incode BioGovID Verification",
// Returns link, instead of delivering it.
"url": "https://saas-onboarding.incodesmile.com/iddataweb_a508/flow/64e3b5663d864e96402cb1b3?uuid=265e602a-e848-49bf-ba6c-ce83a32e1007%22",
"status": "initialized",
"apSessionId": "c5af5e18-bbff-479f-b721-09b3ce06e754"
}
],
"asi": "3dc24510-c44b-4000-849d-cf7644685aad"
}
3. Check: User Status
(GET) https://preprod1.iddataweb.com/preprod-axn/axn/api/async-ui/status
Periodically poll this endpoint to check the overall status of a user session (e.g. complete, pending).
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 status is complete. Most customers do this every 2-5 seconds.
Request
var axios = require("axios");
var token = 'YOUR_BEARER_TOKEN'; // -- obtained from step 1 --
var request = async () => {
var response = await axios({
url: "https://preprod1.iddataweb.com/preprod-axn/axn/api/async-ui/status",
method: "get",
params: {
"apSessionId": "", // -- obtained from step 2 --
"asi": "" // -- obtained from step 2 --
},
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 response = await request();
var status = response.status
if (status === 'complete') // If the user has successfully completed Incode,
{
clearInterval(session)
return
}
console.log('waiting for user to complete document capture process...')
}, 3000) // Request a new status update every 3 seconds.
Response (during session)
{
"status": "pending"
}
Response (once session has completed)
{
"status": "complete"
}
3. Verify
(POST) https://api.preprod.iddataweb.com/v1/slverify
API Reference: https://docs.iddataweb.com/reference/slverify
Lastly, you'll collect the asi (obtained from step 2) and submit it to the endpoint /slverify for a final policy decision.
Request
var data = {
"credential": "test-incode",
"asi": "Your_transaction_ID", // -- obtained from step 2 --
"appID": "",
"country": "US",
"idpType": "optional idp type",
"apikey": "Your API Key"
"userAttributes": [
{
"attributeType": "InternationalTelephone",
"values": {
"dialCode": "1",
"telephone": "telephone-number"
}
},
{
"attributeType": "FullName",
"values": {
"fname": "first_name",
"mname": "",
"lname": "last_name"
}
}
]
}
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",
body: data,
headers: {
"Content-Type": "application/json",
"Cache-Control": "no-cache",
Authorization: "Bearer " + token,
},
});
return response.data
};
Response
{
"errorCode": "",
"errorDescription": "",
"transaction_id": "",
"userAttributes": [
{
"attributeType": "InternationalTelephone",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"dialCode": "1",
"telephone": ""
}
},
{
"attributeType": "FullName",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"fname": "",
"lname": "",
"mname": "",
"suffix": null
}
}
],
"acquiredAttributes": [
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DocumentType",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"documentType": "DriversLicense"
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "AcquiredAddress",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"country": "",
"address": "",
"route": "",
"administrative_area_level_1": "",
"street_number": "",
"locality": "",
"postal_code": "",
"subpremise": null
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DOB",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"month": "",
"day": "",
"year": ""
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "SubmissionTimestamp",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"Timestamp": "14/09/2023 15:29:35"
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DriversLicenseExpirationDate",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"driversLicenseExpirationDate": ""
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DriversLicenseIssueDate",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"driversLicenseIssueDate": ""
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DriversLicenseState",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"driversLicenseState": ""
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "WorkflowTransactionStage",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"Stage": "1"
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "FullName",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"fname": "",
"lname": ""
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "WorkflowTransactionStageAttempt",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"Count": "1"
}
},
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"attributeType": "DriversLicenseNumber",
"dateCreated": "09/14/2023 15:30:17",
"values": {
"driversLicenseNumber": ""
}
}
],
"userAssertionList": [
{
"provider": "Incode",
"serviceOffering": "Incode BioGovID Verification",
"dateAsserted": "09/14/2023 15:30:17",
"assertions": {
"test.documentBalancedLightBackCheck": "pass",
"test.2DBarcodeContentCheck": "pass",
"test.documentSharpnessFrontCheck": "pass",
"test.documentSexCrosscheck": "pass",
"test.documentAuthenticated": "pass",
"test.selfieLensesCheck": "unverified",
"test.selfieBrightnessCheck": "unverified",
"test.possibleFraud": "pass",
"test.postitCheckFront": "unverified",
"test.postitCheckBack": "unverified",
"test.documentExpirationDateCrosscheck": "pass",
"test.2DBarcodeReadable": "pass",
"test.selfieLiveness": "pass",
"test.documentPhysicalPresence": "pass",
"test.documentIssueDateValid": "pass",
"test.documentTypeSideCrosscheck": "pass",
"test.documentNumberCrosscheck": "pass",
"test.selfieMaskCheck": "unverified",
"test.expired": "pass",
"test.documentFacialPhotoCheck": "pass",
"test.documentDOBValid": "pass",
"test.documentClassified": "pass",
"test.overallDocumentCrosscheck": "pass",
"test.documentExpirationDateValid": "pass",
"test.documentAlignmentCheck": "pass",
"test.documentSharpnessBackCheck": "pass",
"test.frontTampered": "pass",
"test.documentFullNameCrosscheck": "pass",
"test.documentBalancedLightFrontCheck": "pass",
"link.selfie_govID": "pass",
"test.documentDOBCrosscheck": "pass"
}
}
],
"mbun": "",
"forwardApiKey": "",
"policyObligation": false,
"policyDecision": "approve"
}
Result
If the policyDecision = approve
, the user has been approved. Additional information on the SLVerify output(s) can be found here.
Updated 1 day ago