Voice Capture (Android)

Estimated reading: 25 minutes 171 views

Welcome to Voice Capture for Android

Welcome to the Voice Capture Quick Start Guide for Android! This document will cover how to get started by getting Aware’s demo program working on your devices.

Installer Contents

  • changes.txt - Change log for each release of Voice Capture.
  • LICENSE - Aware license agreement.
  • bin - Directory containing pre-built Voice Capture AwareId Demo APKs.
  • lib - Directory containing the Android AAR files to use in integration.
  • manuals - Directory containing Voice Capture AwareId documentation.
  • src-demo - Directory containing Aware demo source code.

Installing the Demo Via Android Studio

To start looking at the Voice Capture AwareId Demo, we recommend using Android Studio to compile and run the demo on your Android device. To begin using the demo:

  1. Start Android Studio.
  2. Open an Existing Project. Navigate to the src-demo/android/VoiceCaptureAwareIdDemo directory in the installer and select it.
  3. Select your connected device in Android Studio and press Run.

Please see the manual for getting started with the API and understanding the demo code.

Importing the Voice Capture SDK to a Project

To include the Voice Capture SDK in your application requires three steps:

  1. Update the gradle dependencies and include the AARs in the application lib directory.
    • Add or update the filetree line to include searching for AARs. i.e. api fileTree(dir: ‘libs’, include: [’*.aar’])
    • The dependency section of your application’s gradle may look like the following:

Listing 1 Gradle Dependency

   dependencies {
       api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])

       androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
           exclude group: 'com.android.support', module: 'support-annotations'
       })
       api 'com.squareup.okhttp3:okhttp:3.10.0'
       api 'com.android.support:appcompat-v7:26.1.0'
       api 'com.android.support:design:26.1.0'
       api 'com.android.support.constraint:constraint-layout:1.1.3'
       testImplementation 'junit:junit:4.12'
   }
  1. Copy the Aware-VoiceCaptureAwareId.aar from the lib directory to the libs directory of your application.
  2. Import Voice Capture into your application code to start using the VoiceCaptureAware classes.

Listing 2 Import Example

   import com.aware.voicecaptureaware.api.VoiceCaptureAwareApi;

Running the Voice Capture AwareId Demo

Our SDK package come with two demos, VoiceCaptureAwareIdDemo and VoiceCaptureAwareIdDemoQR.

In the VoiceCaptureAwareIdDemo demo, the initial launch will show the setting page. User will need to enter data string prior to perform enrollment. The following data fields need to be obtained from AwareID admin server, please refer to Server document for references:

  • Set Host URL
  • Set Customer Name
  • Set Apikey
  • Set Client Secret

The other data fields such as Set User Name, Email, Phone Number can be any sample data.

Once all the required fields are filled, tap the back button to route to the Home screen where the application will prompt the user for permission to access the device’s microphone. The user will need to grant this permission before being able to proceed with the enrollment. Once granted the user can initiate an enrollment by clicking the “Enroll” button. Follow the direction on screen to perform a face capture. Once a successful capture is completed the app will return to the home screen.

To initiate a verification/authentication workflow click on the “Verify” button on Home screen.

In the VoiceCaptureAwareIdDemoQR demo, on initial launch, it will prompt the user for permission to access the device’s camera (this is necessary to scan the QR code). Once granted the application will return to the home screen. The user can then proceed with an enrollment by clicking the “Scan QR Code” button. This will open the a camera view with which the user should scan the QR code generated from the Web app (Please see AwareID server document for reference).

Follow the on screen instructions on the capture page to perform voice capture. Once a successful capture is completed, the app will route to the home screen. To perform a verification, either scan a QR code or trigger push notificaiton from the web application.

Description

The Voice Capture AwareId SDK is the client side demo to be used with the AwareId Server product for authentication. It is used to capture voice samples and package them according to the Voice Liveness Server specifications. The Voice Liveness Server will make a determination for whether or not the subject is live. The library does not directly communicate with any servers; it provides a package for the application to deliver to the AwareId Server. It is up to the application developer to implement any server communication and security.

Voice samples are captured based on the selected capture profile. Capture profiles specify the criteria the subject must meet in order to successfully capture samples and create a server package. Profiles are provided with this installer to be used as a base for capturing voice samples that are optimized for liveness processing on the back-end. Profiles can be customized to meet any additional requirements for capture.

Design Features

  • Light-weight on-device size
  • Easy to integrate API
  • No direct UI activity to allow for a fully customizable user experience
  • Handles operation of device hardware
  • Optimized data collection for Knomi back-end analysis
  • No direct server interaction. Applications have full control over when and how they interact with the back-end services.

Platforms

  • Android 8.0 and higher

System Requirements

Hardware requirements

  • Microphone
  • 64 bit processor

Prerequisites

  • Android 8.0 or higher
  • Android NDK 20 or higher
  • API 24 or higher supported on device
  • Users must grant access to MICROPHONE permissions
  • Users must grant access to INTERNET access permissions

Android Integration

Overview

The Voice Capture AwareId SDK comes with a JAVA interface for Android integration. This chapter will outline the requirements for Android integration, how to operate the included developer demo, and which parts of the demo source code correspond to the integration tasks outlined in the Application Design chapter.

Integration Requirements

The Voice Capture AwareId SDK requires Internet and microphone permissions.

Android Voice Capture

This section provides details regarding the Voice Capture Aware ID API and how it is used to implement an application.

Add needed permissions

Permissions for microphone access and internet access should be requested in the manifest at /android/app/src/main

Setup permissions

   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   //...

   <uses-permission android:name="android.permission.RECORD_AUDIO" />
   <uses-permission android:name="android.permission.INTERNET" />

   </manifest>

Android Voice Capture SDK

Create a Voice Capture Library

The first step in utilizing the Voice Capture library is to create a library object. This is done by creating a VoiceCaptureJNI object.

Create Voice Capture Object

   private VoiceCaptureJNI mVoiceCapture;

   try {
       mVoiceCapture = new VoiceCaptureJNI();
   } catch (VoiceCaptureException ex) {
       ex.printStackTrace();
   }

Register a Capture Session Status Callback

VoiceCaptureJNI library is designed around the concept of a capture session. This is a session in which voice samples are collected. During the collection process the application needs to listen for status updates from VoiceCaptureAPI via a CaptureSessionStatusCallback. The application needs to register a class as the listener for this callback. Setting the status callback is done using the API call setCaptureSessionStatusCallback and implementing ICaptureSessionStatusCallbackTarget.

Setup Callback

   //The application must implement the following.
   public class VoiceCaptureApi implements ICaptureSessionStatusCallbackTarget {

       //To application, this listener is from the main application.
       public void SetCaptureSessionStatusListener(CaptureSessionStatusListener listener) {
           mListener = listener;

           try {
               //This sets the callback to the VoiceCapture library.
               mVoiceCapture.setCaptureSessionStatusCallback(this);
           } catch (VoiceCaptureException e) {
               e.printStackTrace();
           }
       }
   }

Create a Workflow Object

A workflow object controls the parameters for a capture session.

Create WorkFlow Object

   private VoiceCaptureJNI.IWorkflow mWorkFlow;

   try {
       mWorkFlow = mVoiceCapture.workflowCreate(VoiceCaptureJNI.ALFA2);
   } catch (VoiceCaptureException e) {
       e.printStackTrace();
   }

Adjust Workflow Settings

Change any settings for the workflow object before starting a capture session.

Adjust Workflow Settings

   try {
       mWorkFlow.setPropertyString(WorkflowProperty.USERNAME, "user_name");
       mWorkFlow.setPropertyDouble(WorkflowProperty.CAPTURE_TIMEOUT, 8.0);
       mWorkFlow.setPropertyDouble(WorkflowProperty.MINIMUM_RECORDING_LENGTH, 1.0);
       mWorkFlow.setPropertyBool(WorkflowProperty.CAPTURE_ON_DEVICE, false);

       String[] mMicrophoneList = mVoiceCapture.getMicrophoneList();
       setWorkflowProperty(PropertyTag.MICROPHONE, mMicrophoneList[0]);

       mWorkFlow.setPropertyString(WorkflowProperty.MICROPHONE, propertyValue);
   } catch (VoiceCaptureException e) {
       e.printStackTrace();
       throw new VoiceCaptureApiException(VoiceCaptureApiException.ErrorCode.InvalidProperty);
   }

Begin a Capture Session

Once the workflow object has been created and any necessary properties set, it is used to start the capture session. During the capture session the application will received status messages via the ICaptureSessionStatusCallbackTarget as described above.

Start Capture Session

   mVoiceCapture.startCaptureSession(mWorkFlow);

Capture Session Completion - Retrieve JSON

After receiving the completed message the application can get the resulting JSON by calling getServerPackage. The resulting JSON can be sent to the server to obtain a liveness result.

Get Server Package

   String json = "";
   try {
       json = mVoiceCapture.getServerPackage(mWorkFlow);
   } catch (VoiceCaptureException e) {
       e.printStackTrace();
   }

Capture Session Completion - Retrieve Voice Samples

If the capture on device setting was set to true, the getCapturedVoiceRecording function can be called to get retrieve the byte data representing the collected voice samples.

Get Server Package

   byte[] recording = null;
   try {
       recording = mVoiceCapture.getCapturedVoiceRecording(mWorkFlow);
   } catch (VoiceCaptureException e) {
       e.printStackTrace();
   }

Android Complete Sample in Java using a fragment

Complete Sample

   public class SecondFragment extends Fragment implements ICaptureSessionStatusCallbackTarget {

       private FragmentSecondBinding binding;
       private VoiceCaptureJNI mVoiceCapture;
       private VoiceCaptureJNI.IWorkflow mWorkFlow;
       private TextView statusTextView;
       private ProgressBar progressBar;


       @Override
       public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           try {
               mVoiceCapture = new VoiceCaptureJNI();

               mVoiceCapture.setCaptureSessionStatusCallback(this);
           } catch (Exception e) {

           }
       }

       @Override
       public View onCreateView(
               LayoutInflater inflater, ViewGroup container,
               Bundle savedInstanceState

       ) {

           binding = FragmentSecondBinding.inflate(inflater, container, false);
           return binding.getRoot();
       }

       public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
           statusTextView =
                   (TextView)getView().findViewById(R.id.recording_status_text);
           progressBar = (ProgressBar)getView().findViewById(R.id.progressBar);
           String[] mMicrophoneList;

           super.onViewCreated(view, savedInstanceState);

           try {
               //Create a Workflow object.
               mWorkFlow = mVoiceCapture.workflowCreate(VoiceCaptureJNI.ALFA2);

               mWorkFlow.setPropertyString(WorkflowProperty.USERNAME, "TestUser");
               mWorkFlow.setPropertyDouble(WorkflowProperty.CAPTURE_TIMEOUT, 0.0);
               mWorkFlow.setPropertyDouble(WorkflowProperty.MINIMUM_RECORDING_LENGTH, 1);
               mWorkFlow.setPropertyBool(WorkflowProperty.CAPTURE_ON_DEVICE, false);

               mMicrophoneList = mVoiceCapture.getMicrophoneList();
               mWorkFlow.setPropertyString(WorkflowProperty.MICROPHONE, mMicrophoneList[0]);

               mVoiceCapture.startCaptureSession(mWorkFlow);
           } catch (VoiceCaptureException e) {
               e.printStackTrace();
           }
       }

       protected void reportCaptureStatus( final String status) {
           getActivity().runOnUiThread(new Runnable() {
               @Override
               public void run() {
                   statusTextView.setText(status);
                   progressBar.setVisibility(View.INVISIBLE);
               }
           });
       }

       @Override
       public void onDestroyView() {
           super.onDestroyView();

           binding = null;
       }

       @Override
       public void onPause() {
           super.onPause();
           if (mVoiceCapture != null)
               mVoiceCapture.destroy();
           mVoiceCapture = null;
       }

       @Override
       public void captureSessionStatusCallback(CaptureSessionStatus captureSessionStatus) {
           Log.d("api", "captureSessionStatusCallback=" + captureSessionStatus.toString());

           if(captureSessionStatus.toString().equals("COMPLETED")){
               String json = "";
               reportCaptureStatus("Capture Complete");
               try {
                   json = mVoiceCapture.getServerPackage(mWorkFlow);

                   Log.d("api", "json=" + json);
               } catch (VoiceCaptureException e) {
                   e.printStackTrace();
               }
           }
       }
   }

Enrollment Process Initiated from Client

Base URL

www.awareid.aware-apis.com

To perform a successful enroll using the Voice SDK and AwareID there are two possible workflows. The first workflow is the most flexible and involves initiating the enrollment from the client application. The second workflow option involves the use of a secondary application to initiate the enrollment and generate a QR code encoded with the session token necessary to proceed with the enrollment process.

To enroll by initiating from the client we have to follow 4 steps. These steps include:

  1. Retrieve an access token. This token allows communication between the client application and the AwareID servers.
  2. Initiate an enrollment.
  3. Add device
  4. Enroll voice

Enrollment Initiated from Client Step 1 - Get Access Token

Our first step is to retrieve an “access_token”. This token will be used in our next api call to retrieve an enrollment token to proceed with enrollment.

Get Access Token

   POST /auth/realms/{{customer_name}}-consumers/protocol/openid-connect/token
   Content-Type: 'application/x-www-form-urlencoded',

   "client_id": client_id
   "client_secret": client_secret
   "scope": openid
   "grant_type" : client_credentials

Urlencoded

   This is the only call whose content type of this call is “application/x-www-form-urlencoded”

Response - openid-connect

Response - openid-connect

   STATUS CODE 200
   {
       "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJCY2IxNXZJQkZsY2JYazVmQUdJZFZXV2pTUEtTaWpsazNydmFwMHp0ekN3In0.eyJleHAiOjE2NzM5OTExMjksImlhdCI6MTY3Mzk5MDgyOSwianRpIjoiN2MzYmY1MmItNjdlMC00ODNlLWFhZjAtYjlkNWJhODE3ZWJiIiwiaXNzIjoiaHR0cHM6Ly9hd2FyZWlkLWRldi5hd2FyZS1hcGlzLmNvbS9hdXRoL3JlYWxtcy9hbmRyYWUtY29uc3VtZXJzIiwic3ViIjoiOTU3ZWMyYmYtZTczOS00YjFjLWEyN2QtMTczMjQzMDIyYTE5IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYmltYWFzLWIyYyIsImFjciI6IjEiLCJzY29wZSI6Im9wZW5pZCIsImNsaWVudElkIjoiYmltYWFzLWIyYyIsImNsaWVudEhvc3QiOiIzOC4xNDAuNTkuMjI2IiwiY2xpZW50QWRkcmVzcyI6IjM4LjE0MC41OS4yMjYifQ.OzggQ--Gl4w3NWZPg1BukkEg0fmsSyGgN-ag8eW0FARWl0Ic5fkrnrEdnIgsq5Molq0R52oe4Hy-8Tp4cOn9iCD51kPCPfTt15zVBIAYOvb5M5XZ0uPTygh02KjuFqsxIhbhH8CCUjHkpu3OhoWByc8bC8c9D_cFp3BFE-XIhNPaPxXdTLZOcJOqpdSVxsgxB66-xukI7AA8PWt10huO47l6TSBSnJIjUxNbEqR48ILfnkYY2bmyfoo-laKDv9XSSZ8hXU9sDkiGfpXOl112_f3L1sc6n1-UbRTJGFMd4fgntuanwEvN68TsyS5pz0izGlW-1T3fFJ3D2pGPefsWNA",
       "expires_in": 300,
       "refresh_expires_in": 0,
       "token_type": "Bearer",
       "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJCY2IxNXZJQkZsY2JYazVmQUdJZFZXV2pTUEtTaWpsazNydmFwMHp0ekN3In0.eyJleHAiOjE2NzM5OTExMjksImlhdCI6MTY3Mzk5MDgyOSwiYXV0aF90aW1lIjowLCJqdGkiOiJkYWNiNTc1NS1jMGEyLTQxZTEtYjMwMi05ZGEzOWRiNGNiYmUiLCJpc3MiOiJodHRwczovL2F3YXJlaWQtZGV2LmF3YXJlLWFwaXMuY29tL2F1dGgvcmVhbG1zL2FuZHJhZS1jb25zdW1lcnMiLCJhdWQiOiJiaW1hYXMtYjJjIiwic3ViIjoiOTU3ZWMyYmYtZTczOS00YjFjLWEyN2QtMTczMjQzMDIyYTE5IiwidHlwIjoiSUQiLCJhenAiOiJiaW1hYXMtYjJjIiwiYXRfaGFzaCI6IlcwbXNUU05WQUo1MG9oQ2JOR3dlTmciLCJhY3IiOiIxIiwiY2xpZW50SWQiOiJiaW1hYXMtYjJjIiwiY2xpZW50SG9zdCI6IjM4LjE0MC41OS4yMjYiLCJjbGllbnRBZGRyZXNzIjoiMzguMTQwLjU5LjIyNiJ9.MOgJ3giF0ikQnUAOBgK6eHpC0Tz3pCjhTX4IjHSjh3kzxx0KCLiWd494Fl3JSHiyvnNP7Ty1SXl4Bhq19f7y_lpGp4yLkbV9I1xsfC7m2D-EIf73D1LEluf1y97ISbh8668VqnGRG8U1FtXuwQGPZb7cgMiTbprECwLFj44_vM2qmLxFpOkOuVaqPmpgjt6MAmUbcWV8GDMAdxVnlZDZuzFkwOlb6S_WypNSYKHA6TFIe_FsA2EoxMu_9MAP3OLX7LIwX3jYIsT4z-TnUmyKC5RFzx6oc9D9Fr2eSTRBxC6QKGJrFAPt40p9_U3YFFi6VpzaGK9YQvCvdw70CVBe5Q",
       "not-before-policy": 0,
       "scope": "openid"
   }

Enrollment Initiated from Client Step 2 - Initiate An Enrollment

With the method type we start onboarding with accessToken, sessionToken, apikey

Initiate An Enrollment

   POST /onboarding/enrollment/enroll
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "username":  "username",
       "firstName": "first name", //optional
       "lastName": "last name" //optional
       "email": "user email",
       "phoneNumber": "user phonenumber"
   }

Response - Initiate An Enrollment

Response - Initiate An Enrollment

   STATUS CODE 200
   {
       "enrollmentToken": "enrollmentToken",
       "userExistsAlready": false,
       "requiredChecks": [
           "addDevice",
           "addVoice"
       ]
   }

Enrollment Initiated from Client Step 3 - Add Device

The device ID is checked when performing an authentication to confirm the device enrolled is the same as the device attempting.

Device Id

   This can be retrieved in Android by using the following code
   Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);

Add Device

   POST /onboarding/enrollment/adddevice
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "enrollmentToken": "enrollmentToken",
       "deviceId": "deviceID"
   }

Response - Add Device

Response - Add Device

   {
       "enrollmentStatus": 1,
       "registrationCode": ""
   }

From here the response will include a registration code and enrollment status.

There are 3 enrollment statuses:

Enrollment Statuses

   0 = Enrollment Failed
   1 = Enrollment Pending
   2 = Enrollment Complete

Enrollment Initiated from Client Step 4 - Add voice sample and check if sample belongs to a live person.

The add voice API call requires the json package generated by the Voice SDK.

Add Voice Sample

   POST /onboarding/enrollment/addVoice
   Content-Type: 'application/json; charset=UTF-8',
   Authorization: 'Bearer AccessToken'

   {
       "enrollmentToken": "{{enrollment_token}}",
       "livenessData": {
           "voice": {
               "voiceSamples": [
                   {
                       "data": {{LiveVoice}},
                       "Phrase": "\"Hello, Testing BIMaaS Application.\""
                   }
               ],
               "workflow": "alfa2",
               "meta_data": {
                   "client_device_brand": "Apple",
                   "client_device_model": "iPhone 8",
                   "client_os_version": "11.0.3",
                   "client_version": "KnomiSLive_v:2.4.1_b:0.0.0_sdk_v:2.4.1_b:0.0.0",
                   "localization": "en-US",
                   "programming_language_version": "Swift 4.1",
                   "username": "test"
               }
           }
       }
   }

Response - Add Voice Sample

The response from the enrollment call returns:

  • Liveness Result
    • This is a boolean value.
    • returns true if the sample is assessed to be a live sample
    • returns false is the sample is assessed to not be live
  • Enrollment Status
    • 0 = failed
    • 1 = pending
    • 2 = success
  • Registration Code
    • this code is used in the re-enrollment process
  • Liveness Result
    • Broken down into several fields giving feedback on the liveness score

Liveness Result

   STATUS CODE 200
   {
       "livenessResult": true,
       "enrollmentStatus": 2,
       "registrationCode": "LLXL2N",
       "livenessResults": {
           "voice": {
               "liveness_result": {
                   "decision": "LIVE",
                   "feedback": [],
                   "score_frr": 1.1757098732441127
               }
           }
       }
   }

Enrollment Process Initiated Through QR Code

To enroll by inititating through a QR code scan we first have to take in the enrollment details like first name, last name, email address and phone number and make a call to generate the QR code from a secondary application. In our demo we use a web app for this process.

Generate QR Code

Web Portal

To start an enrollment using the QR code method we must first generate the QR code to be consumed by the client application (in our example we use a web app). This web application uses a UI to allow an enduser to register using a username and email address. Then uses these pieces of information in the API Call for /triggerEnroll.

Base URL

   www.awareid.aware-apis.com

Trigger Enroll

We initiate an enrollment by calling the /triggerEnroll endpoint.

  • username - required
  • email - required
  • notifyOptions - optional

Trigger Enroll

   POST baseUrl + /b2c/proxy/triggerEnroll
   Content-Type: 'application/json; charset=UTF-8',

   { "username": "[email protected]",
       "email": "[email protected]",
       "notifyOptions": {
           "notifyByEmail": false
       }
   }

Response - Trigger Enroll

   STATUS CODE 200
   {
       status : "SUCCESS"
       sessionCallbackURL : "https://awareid-dev.aware-apis.com/onboarding?data=jgTW40dmoG6Hp_d6Rg7YaZ97vfGSlV5BcBJvLvqXVmhoQ2Hg2DcC2Kvr9AkTZ38ZkyIfiSj80QFxOWs1YeckYsp3D0D9vS46wppl1Zdt-tpiAdzlvBKA2DBfcj7rf0VePWUn1vKdIPgEoWAulqRxZ_mNakFB7FijLg0QJ8kYsB6w0Nk1A4m9QtLGIdHcuGn9XJnxooQHyr2yhtUsgfOo2FrRXYmFIF7ZNwxYd56miFCs-yuD6eZZcvZ1M01Wje7ji0NYUWVpdes-DA_P0cKgsLPX5sV7SyPSlf9kmoCQz7Ag20kAKkOf-LFFKQmgnJ3362nXIEovxS8vp4BCClu7vIfEVCE2s1zS7zNwrDuRfFdViVAQMMxDMe77LnbKbfvLqUhiv--wPFyV9Iier1EDSL9y5kikOw_PGSyuRzvbQKuoNdGj-IqVZYZ_5QivOFqq_OEt8jaX1zZxAiQ8uXRt3g"
       qrcodeImage : "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"
       sessionToken : "aa73e547-0f1b-4235-a7b0-dd52fa4ab774"
       errorSummary : null
   }

Our response for trigger enroll includes five pieces of information with the most relevant piece being the base64 encoded string of the QR that is used to be displayed to the user to continue the enrollment on their device.

With our QR code generated in our web application we then have to proceed with scanning the QR code and completing the enrollment. The following steps apply to enrolling a user from the client side application using a QR code. These steps include:

  1. Scan QR code and decrypt data.
  2. Initiate an enrollment.
  3. Add device
  4. Enroll voice

The QR Code will return a url with an encrypted data parameter named “data”.

This data has to be decrypted using the available public key. Once decoded 3 pieces of information are provided separated by “&”.

  1. Host url
  1. This URL is where all subsequent api calls will be made through
  1. The API Key
  1. This API Key is used in the header of api calls
  2. The key value pair in the header is as follows:

“apikey”:API_Key

  1. Session Token
  1. The session token is used to validate the session.

Enrollment Using QR Code Step 1 - Validate Session Token

The first api call necessary to enroll a user is /tokenVerify/validateSession.

Validate Session

   POST /tokenVerify/validateSession
   "Content-Type": 'application/json; charset=UTF-8',
   "apikey": apiKey

   {
       "sessionToken":sessionToken
   }

Urlencoded

   This is the only call whose content type of this call is “application/x-www-form-urlencoded”

Response - Validate Session Token

Response - Validate Session Token

   {
       "accessToken": "accessToken",
       "methodType": "enroll",
       "customerName": "customerName",
       "customerLogo": "",
       "userName": "customerUsername",
       "email": "customerEmail"
   }

Enrollment Using QR Code Step 2 - Initiate An Enrollment

With the method type we start onboarding with accessToken, sessionToken, apikey

Initiate An Enrollment

   POST /onboarding/enrollment/enroll
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "username":  "username",
       "firstName": "first name", //optional
       "lastName": "last name" //optional
       "email": "user email",
       "phoneNumber": "user phonenumber"
   }

Response - Initiate An Enrollment

Response - Initiate An Enrollment

   STATUS CODE 200
   {
       "enrollmentToken": "enrollmentToken",
       "userExistsAlready": false,
       "requiredChecks": [
           "addDevice",
           "addVoice"
       ]
   }

Enrollment Using QR Code Step 3 - Add Device

The device ID is checked when performing an authentication to confirm the device enrolled is the same as the device attempting.

Device Id

   This can be retrieved in Android by using the following code
   Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);

Add Device

   POST /onboarding/enrollment/adddevice
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "enrollmentToken": "enrollmentToken",
       "deviceId": "deviceID"
   }

Response - Add Device

Response - Add Device

   {
       "enrollmentStatus": 1,
       "registrationCode": ""
   }

From here the response will include a registration code and enrollment status.

There are 3 enrollment statuses:

Enrollment Statuses

   0 = Enrollment Failed
   1 = Enrollment Pending
   2 = Enrollment Complete

Enrollment Using QR Code Step 4 - Add voice sample and check if sample belongs to a live person.

The add voice API call requires the json package generated by the Voice SDK.

Add Voice Sample

   POST /onboarding/enrollment/addVoice
   Content-Type: 'application/json; charset=UTF-8',
   Authorization: 'Bearer AccessToken'

   {
       "enrollmentToken": "{{enrollment_token}}",
       "livenessData": {
           "voice": {
               "voiceSamples": [
                   {
                       "data": {{LiveVoice}},
                       "Phrase": "\"Hello, Testing BIMaaS Application.\""
                   }
               ],
               "workflow": "alfa2",
               "meta_data": {
                   "client_device_brand": "Apple",
                   "client_device_model": "iPhone 8",
                   "client_os_version": "11.0.3",
                   "client_version": "KnomiSLive_v:2.4.1_b:0.0.0_sdk_v:2.4.1_b:0.0.0",
                   "localization": "en-US",
                   "programming_language_version": "Swift 4.1",
                   "username": "test"
               }
           }
       }
   }

Response - Add Voice Sample

The response from the enrollment call returns:

  • Liveness Result
    • This is a boolean value.
    • returns true if the sample is assessed to be a live sample
    • returns false is the sample is assessed to not be live
  • Enrollment Status
    • 0 = failed
    • 1 = pending
    • 2 = success
  • Registration Code
    • this code is used in the re-enrollment process
  • Liveness Result
    • Broken down into several fields giving feedback on the liveness score

Liveness Result

   STATUS CODE 200
   {
       "livenessResult": true,
       "enrollmentStatus": 2,
       "registrationCode": "LLXL2N",
       "livenessResults": {
           "voice": {
               "liveness_result": {
                   "decision": "LIVE",
                   "feedback": [],
                   "score_frr": 1.1757098732441127
               }
           }
       }
   }

Authentication Workflow

Like the enrollment process we can also complete an authentication in two variations. The first is initiating the authentication from the client side and the second involves using a QR code scan to initiate the authencation process and using the client application to complete the authentication process. Below we explain how to achieve both options beginning with the Client Initiated Authentication

Client Initiated Authentication

A client initiated authentication is performed in 3 steps:

  1. Initiate authentication
  2. Verify device
  3. Verify voice

Base URL

Base URL

   www.awareid.aware-apis.com/onboarding/authentication

Authentication Initiated from Client Step 1 - Initiate Authentication

Initiate Authentication

   POST /authenticate
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "registrationCode": "registrationToken",
       "deviceId": "deviceID"
   }

Response - Initiate Authentication

Response - Initiate Authentication

   STATUS CODE 200
   {
       "authToken": "b8bf6f22-6f93-4bcb-a5b6-871b689c6750",
       "requiredChecks": [
           "verifyDevice",
           "verifyVoice"
       ]
   }

Authentication Initiated from Client Step 2 - Verify Device

Verify Device

   POST /verifyDevice
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "authToken": "authToken",
       "signature": "signature",
       "deviceId": "deviceID"
   }

Response - Verify Device

Response - Verify Device

   STATUS CODE 200
   {
       "message": "Device verified.",
       "authStatus": 1
   }

Authentication Initiated from Client Step 3 - Verify Voice

Verify Voice

   POST /verifyVoice
   {
       "authToken": "auth_token",
       "livenessData": {
           "voice": {
               "voiceSamples": [
                   {
                       "data": "base64 voice sample package from SDK",
                       "Phrase": "\"Hello, Testing BIMaaS Application.\""
                   }
               ],
               "workflow": "alfa2",
               "meta_data": {
                   "client_device_brand": "Apple",
                   "client_device_model": "iPhone 8",
                   "client_os_version": "11.0.3",
                   "client_version": "KnomiSLive_v:2.4.1_b:0.0.0_sdk_v:2.4.1_b:0.0.0",
                   "localization": "en-US",
                   "programming_language_version": "Swift 4.1",
                   "username": "test"
               }
           }
       }
   }

Response - Verify Voice

Response - Verify Voice

   {
     "livenessResult": true,
     "matchResult": true,
     "matchScore": 100,
     "authStatus": "2 (Complete)",
     "voiceLivenessResults": ""
   }

Authentication Using QR Code

To authenticate by inititating through a QR code scan we first have to take in the user identifying data such as first name, last name, email address and phone number and make a REST call to generate the QR code from a secondary application. For this discussion we assume a web application.

Generate QR Code

Web Portal

To start an authentication using the QR code method we must first generate the QR code to be consumed by the client application (in our example we use a web app). This web application uses a UI to allow an end user to register using a username and email address. Then uses these pieces of information in the API Call for /triggerAuthenticate .

Base URL

   www.awareid.aware-apis.com

Trigger Authenticate

We initiate an authentication by calling the /triggerAuthenticate endpoint.

  • username - required
  • notifyOptions - optional

Trigger Authenticate

   POST baseUrl + /b2c/proxy/triggerAuthenticate
   Content-Type: 'application/json; charset=UTF-8',

   { "username": "[email protected]",
       "notifyOptions": {
           "notifyByPush": true
       }
   }

Response - Trigger Authenticate

   STATUS CODE 200
   {
       status : "SUCCESS"
       sessionCallbackURL : "https://awareid-dev.aware-apis.com/onboarding?data=jgTW40dmoG6Hp_d6Rg7YaZ97vfGSlV5BcBJvLvqXVmhoQ2Hg2DcC2Kvr9AkTZ38ZkyIfiSj80QFxOWs1YeckYsp3D0D9vS46wppl1Zdt-tpiAdzlvBKA2DBfcj7rf0VePWUn1vKdIPgEoWAulqRxZ_mNakFB7FijLg0QJ8kYsB6w0Nk1A4m9QtLGIdHcuGn9XJnxooQHyr2yhtUsgfOo2FrRXYmFIF7ZNwxYd56miFCs-yuD6eZZcvZ1M01Wje7ji0NYUWVpdes-DA_P0cKgsLPX5sV7SyPSlf9kmoCQz7Ag20kAKkOf-LFFKQmgnJ3362nXIEovxS8vp4BCClu7vIfEVCE2s1zS7zNwrDuRfFdViVAQMMxDMe77LnbKbfvLqUhiv--wPFyV9Iier1EDSL9y5kikOw_PGSyuRzvbQKuoNdGj-IqVZYZ_5QivOFqq_OEt8jaX1zZxAiQ8uXRt3g"
       qrcodeImage : "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"
       sessionToken : "aa73e547-0f1b-4235-a7b0-dd52fa4ab774"
       errorSummary : null
   }

Our response for trigger authenticate includes five pieces of information with the most relevant piece being the base64 encoded string of the QR that is used to be displayed to the user to continue the authentication on their device.

With our QR code generated in our web application we then have to proceed with scanning the QR code and completing the authentication. The authentication workflow involves 4 steps:

  1. Scan QR code and decrypt data.
  2. Initiate authentication
  3. Verify device
  4. Verify voice

The QR Code will return a url with an encrypted data parameter named “data”.

This data has to be decrypted using the available public key. Once decoded 3 pieces of information are provided separated by “&”.

  1. Host url
  1. This URL is where all subsequent api calls will be made through
  1. The API Key
  1. This API Key is used in the header of api calls
  2. The key value pair in the header is as follows:

“apikey”:API_Key

  1. Session Token
  1. The session token is used to validate the session.

Authentication Using QR Code Step 1 - Validate Session Token

The first api call necessary to authenticate a user is /tokenVerify/validateSession.

Validate Session

   POST /tokenVerify/validateSession
   "Content-Type": 'application/json; charset=UTF-8',
   "apikey": apiKey

   {
       "sessionToken":sessionToken
   }

Urlencoded

   This is the only call whose content type of this call is “application/x-www-form-urlencoded”

Response - Validate Session Token

Response - Validate Session Token

   {
       "accessToken": "accessToken",
       "methodType": "authenticate",
       "customerName": "customerName",
       "customerLogo": "",
       "userName": "customerUsername",
       "email": "customerEmail"
   }

Authentication Using QR Code Step 2 - Initiate Authentication

Initiate Authentication

   POST /authenticate
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "registrationCode": "registrationToken",
       "deviceId": "deviceID"
   }

Response - Initiate Authentication

Response - Initiate Authentication

   STATUS CODE 200
   {
       "authToken": "b8bf6f22-6f93-4bcb-a5b6-871b689c6750",
       "requiredChecks": [
           "verifyDevice",
           "verifyVoice"
       ]
   }

Authentication Using QR Code Step 3 - Verify Device

Verify Device

   POST /onboarding/authentication/verifyDevice
   Authorization: 'Bearer AccessToken'
   apikey: 'apikey'

   {
       "authToken": "authToken",
       "signature": "signature",
       "deviceId": "deviceID"
   }

Response - Verify Device

Response - Verify Device

   STATUS CODE 200
   {
       "message": "Device verified.",
       "authStatus": 1
   }

Authentication Using QR Code Step 4 - Verify Voice

Verify Voice

   POST /onboarding/authentication/verifyVoice
   {
       "authToken": "auth_token",
       "livenessData": {
           "voice": {
               "voiceSamples": [
                   {
                       "data": "base64 voice sample package from SDK",
                       "Phrase": "\"Hello, Testing BIMaaS Application.\""
                   }
               ],
               "workflow": "alfa2",
               "meta_data": {
                   "client_device_brand": "Apple",
                   "client_device_model": "iPhone 8",
                   "client_os_version": "11.0.3",
                   "client_version": "KnomiSLive_v:2.4.1_b:0.0.0_sdk_v:2.4.1_b:0.0.0",
                   "localization": "en-US",
                   "programming_language_version": "Swift 4.1",
                   "username": "test"
               }
           }
       }
   }

Response - Verify Voice

Response - Verify Voice

   {
     "livenessResult": true,
     "matchResult": true,
     "matchScore": 100,
     "authStatus": "2 (Complete)",
     "voiceLivenessResults": ""
   }

Software Acknowledgments

Aware VoiceCapture libraries incorporate third-party software. See the LICENSE file installed with the VoiceCapture software for the full license agreement.

CONTENTS