Document Capture (iOS)

Integration

Estimated reading: 23 minutes 248 views

Introduction

Description

The AwareID Document Capture SDK is the client side library that is used with the Face Liveness and Document Authentication Server products. It is used to capture face and document images then package them according to the Face Liveness and Document Authentication Server specifications. These packages are controlled by the application allowing the developer to control the timing and delivery methods for each transaction. It is up to the application developer to implement any server communication and security.

On the back-end, the Face Liveness service will determine whether the subject is live or not. The Document Authentication server will take the captured document to determine the validity of the document then perform a match with the live face and the facial image from the document to authenicate the user.

Design Features

  • Easy to integrate API
  • Customizable user experience
  • Handles operation of device hardware
  • Optimized data collection for back-end analysis
  • Applications have full control over when and how they interact with the back-end services.

Platforms

  • iOS 13.0 and higher

Integration Requirements

The Face Capture SDK requires Camera permissions.

The Regula Document Reader SDK requires Internet, Camera, and NFC Tag Reading permissions. Please see Regula’s documentation for additional details : https://docs.regulaforensics.com/develop/doc-reader-sdk/mobile/ios/

https://docs.regulaforensics.com/develop/doc-reader-sdk/mobile/ios/

Add Capabilities and Permissions

iOS

Under the Capabilities tab for the project’s target add the “Near Field Communication Tag Reading” capability.

Open the application’s Info.plist file and add the following Key-Type-Value tuples.

KeyTypeValue
NSCameraUsageDescriptionStringA description of what the camera is being used for.
NFCReaderUsageDescriptionStringA description of what the NFC Tag Reader is being used for.
com.apple.developer.nfc.readersession.iso7816.select-identifiersListA list of application identifiers to be read according to the ISO7816 specification.

Fill the iso7816.selected-identifiers list with the following String values :

  • A0000002471001
  • E80704007F00070302
  • A000000167455349474E
  • A0000002480100
  • A0000002480200
  • A0000002480300
  • A00000045645444C2D3031

Additional information on the necessary permissions and capabilities for RFID reading can be found here : https://docs.regulaforensics.com/develop/doc-reader-sdk/mobile/ios/rfid/

Capture Face

Overview

Face Capture SDK is used to capture the subject’s face. This chapter details the steps required to set up a facial capture, obtain data from the capture session, and get the package contents for the Face Liveness back-end.

Face Capture Integration

Create a Face Capture Object

The Face Capture library object manages all other Face Capture API classes, and methods. This object is used to set up a capture session and allow control of the face capturing process. A JSON package can be retrieved using this object following the completion of the face capture.

iOS

Create a Face Capture Object

   self.faceCapture = try FaceCapture()

Create a Workflow Object

The workflow object allows the developer to customize a capture session. The core workflow parameters are selected by specifying the workflow name. A workflow object combined with a camera are provided to the Face Capture library to control the capture session. The wokflow object may be configured with several options shown in the Face Capture documentation.

iOS

Create a Workflow Object

   try workflow = faceCapture.workflowCreate(workflowName: "Charlie")

Select a Camera

Get the list of cameras on the front or back of the phone and select one to use. Cameras can be set up as either portrait or landscape.

iOS

Select a camera

   self.cameraList = try faceCapture.getCameraList(position: FaceCapture.CameraPosition.fromString(term: mCameraPosition))
   if self.cameraList.count == 0 {
       self.reportCaptureError(message: Bundle.main.localizedString(forKey: "NO CAMERA ERR", value: "Could not find any cameras for the given camera position", table: "Localizable"))
       return
   }
   self.selectedCamera = self.cameraList[0]

Begin a Capture Session

In order to receive facial images and feedback, the capture session must be started. The capture session is initiated by calling startCaptureSession with the selected workflow and camera. Not all camera and workflow combinations are valid. Details are available in the Face Capture documentation.

iOS

Begin a Capture Session

Get the Capture Region

While a capture session is on-going, a capture region based on the capture session’s settings becomes available. This region is where the face needs to be positioned in order to successfully capture. This should be used to create a display for the user to align themselves with.

iOS

Get capture region

   let region = try faceCapture.captureSessionGetCaptureRegion()

Enable Autocapture

Disabling and enabling this setting allows customizing when a capture can occur easily. The capture session will not successfully complete while this setting is disabled even if the subject meets all capture requirements.

iOS

Enable Autocapture

   try faceCapture.captureSessionEnableAutocapture(enableAutocapture: true)

Get the current Capture Session State

While a capture session is in progress, the application retrieves the capture session state object using the getCaptureSessionState() function. The getCaptureSessionState() function waits for new data to be available and then returns. This is a blocking function, therefore, it needs to be in a separate thread to avoid deadlocking other application functionality such as the UI thread.

iOS

Capture Session State

   currentState = try faceCapture.getCaptureSessionState()

Get the Capture State’s Status

The status indicates what the capture session is currently doing or if it has ended. The main use of the capture status is to know when to determine what content to display on screen and when to move to the next screen.

iOS

Capture Session Status Changes

   self.currentStatus = try self.currentState?.getStatus()

Get the Capture State’s Image

While the capture status is capturing, images from the camera are available to display on screen. When a capture session has ended, the final capture state object will indicate that the frame is unavailable. It is important to either check the capture status to avoid querying for an unavailable frame or handle unavailable frames appropriately.

iOS

Capture Session Images

   self.currentFrame = try self.currentState?.getFrame()

Get the Capture State’s Feedback

When the capture session’s state is capturing, the SDK will provide feedback to the application. The feedback relates to the subject’s position of the face relative to the ideal location and lighting.

iOS

Capture Session Feedback

   self.currentFeedback = try self.currentState?.getFeedback()

Get the Server Package

Once a capture has successfully completed, the workflow used to start the capture session can be used to get an encrypted or non-encrypted package. A package type is necessary to tell the server how to analyze the package. There are several package types that can be used based on usability and security requirements.

An encryption type and corresponding public key is necessary to create the encrypted package. The public key is retrieved from the AwareID server.

Unencrypted

iOS

Get the Server Package

   let serverPackage =  try self.faceLiveness.getServerPackage()

Encrypted

iOS

Get the Encrypted Server Package

   let serverPackage = self.getEncryptedServerPackage()

Stop a Capture Session

A stop capture session function is available for when the application needs to end a capture session early. The capture session should be stopped when the application is put into the background to avoid conflicts with other applications that may be running.

iOS

Stop a Capture Session

   try faceCapture.stopCaptureSession()

Capture Document

Overview

Document Reader is used to scan documents such as passports for subject data and facial images.

Document Capture Integration

There are two types of document captures, OCR and NFC. Each capture type consists of setup, running and processing. A “DocumentReader” must first be initialized, and a database file downloaded. This database consists of document templates to assist in document recognition. Each capture has a list of available setup options to help with the capture process. Once the capture process is started the user will be prompted by UI and text instructions on how to position the document for capture. When a capture is finished the collected data can be sent to the AwareID server for analysis.

Document Capture Initialization

Document capture initialization consists of checking for a valid license and downloading the document database.

Prepare The Database

The database file will be downloaded from the network only one time and stored on the user device. The current database size is (~60MB), the size can be controlled by replacing the string “Full” with other options found in the documentation: https://docs.regulaforensics.com/develop/doc-reader-sdk/mobile/ios/database/

iOS

Prepare The Database

InitializeReader

After downloading the database, the developer can initialize the reader. Read the license file from appsrcmainresrawdocument.license into a buffer. The SDK will automatically check for license updates if the update license option is set to true. Initializing the reader will result in a completion callback, and then the scan can be started.

iOS

Initialize the Reader

   func initializeDocumentReader() {
       if let config = config {
           config.licenseUpdateCheck = false
           DocReader.shared.initializeReader(config: config) { [weak self] (success, error) in
               if success {
                   LoadingOverlay.hideHourglass()
                   print("DocumentReader successfully initialized")
                   DocReader.shared.functionality.showTorchButton = false
                   self?.readerInitialized = true
               } else {
                   print(error ?? "error is nil")
               }
               LoadingOverlay.hideHourglass()
           }
       } else {
           LoadingOverlay.hideHourglass()
       }
       //To set the processing scenario, use:
       DocReader.shared.processParams.scenario = RGL_SCENARIO_FULL_PROCESS
       //The list of returned scenarios is based on the Core capabilities and your license. The license has the priority. To get the list of all available scenarios, invoke:
       for scenario in DocReader.shared.availableScenarios {
           print(scenario)
       }
   }

Setup Initialization Completion Callback

A completion handler callback is required to be set to the IDocumentReaderInitCompletion. It will be called after the initialization process is complete, either successfully or with errors. The initCompletion callback takes two parameters. The first one is a result boolean. The second one is a DocumentReaderException type object which contains an error message if applicable.

iOS

Setup Init Completion Callback

   DocReader.shared.initializeReader(config: config) { [weak self] (success, error) in /*
       //Set up OCR scanning.
   */}

Document Scanning Process For OCR

Setup Document Scanning

Set the selected scenario and any required options. The SDK supports many scenarios and options, one such option is the ability to check for holograms on a document, another option is the ability to scan multiple pages of a document. More information on scenarios and options can be found in the documentation.

iOS

Setup Document Scanning

   DocReader.shared.startNewSession()
   DocReader.shared.functionality.orientation = .portrait
   DocReader.shared.processParams.checkHologram = self.checkHologram ? true : false
   DocReader.shared.processParams.scenario = RGL_SCENARIO_OCR
   DocReader.shared.rfidScenario.autoSettings = true

   DocReader.shared.processParams.multipageProcessing = true
   DocReader.shared.processParams.timeout = 20

Start Document Scanning

Starting the scanner requires passing in a completion callback where results can be processed.

iOS

Start Document Scanning

   DocReader.shared.showScanner(parentVC) { [weak self] (action, result, error) in }

Process Data

Once scanning is complete save the encrypted data by calling results.getEncryptedContainers().

iOS

Process Data

   DocReader.shared.showScanner(parentVC) { [weak self] (action, result, error) in
           self?.rfidPresence = result?.chipPage != 0
           if action == .complete || action == .processTimeout {
               self?.timeout = action == .processTimeout
               if self?.readRFID == true && result?.chipPage != 0 {
                   self?.startRFIDReading(resultData: resultData, infoMap: infoMap, onBoardingType: onBoardingType, callback: callback)
               } else if result?.documentType != nil {
                   self?.handleResult(resultData: resultData, infoMap: infoMap, onBoardingType: onBoardingType, result: result, callback: callback)
               } else {
                   self?.handleResult(resultData: resultData, infoMap: infoMap, onBoardingType: onBoardingType, result: result, callback: callback)
               }
           }
       }

Document Scanning Process for NFC (Optional)

Setup Document Scanning

This process is optional depending on if the server is set to capture RFID data and the document is equipped with an RFID chip. For active authentication, which is supported by some passports, a server URL must be supplied to handle a server challenge.

iOS

Setup Document Scanning

   DocReader.shared.processParams.scenario = RGL_SCENARIO_MRZ
   let reprocParams = DocReader.ReprocParams()
   reprocParams.serviceURL = OnBoardingStorage.getBiMaasURL() ?? ""
   reprocParams.httpHeaders = ["Authorization":"Bearer"+(OnBoardingStorage.getBiMaasJWT() ?? ""),"apiKey":OnBoardingStorage.getBiMaasAPIKey() ?? ""]
   reprocParams.failIfNoService = true
   DocReader.shared.rfidScenario.reprocParams = reprocParams
   DocReader.shared.rfidScenario.autoSettings = true
   DocReader.shared.functionality.orientation = .portrait
   DocReader.shared.processParams.shouldReturnPackageForReprocess = true

Start Document Scanning

Starting the scanner requires passing in a completion callback where results can be processed.

iOS

Start Document Scanning

   // Start the scanner using a UIViewController object, an object sublclassed by UIViewController, while passing a callback function.
   DocReader.shared.startRFIDReader(fromPresenter: parentVC, completion: { [weak self] (action, results, error) in
       })

Process Data

Once scanning is complete save the encrypted data by calling results.getEncryptedContainers().

iOS

Process Data

   DocReader.shared.startRFIDReader(fromPresenter: parentVC, completion: { [weak self] (action, results, error) in
       switch action {
       case .complete, .processTimeout:
           self?.timeout = action == .processTimeout
           self?.handleResult(resultData: resultData, infoMap: infoMap, onBoardingType: onBoardingType, result: results, callback: callback)
       case .cancel:
           print("Canceled")
       case .error:
           print("Error")
       default:
           print(action)
           break
       }
   })

Notes

Processing the callback data should be done in the OnResume() of the applications activity. This will make sure that the application owns the data and that the activity used by the Regula SDK if finished.

Enrollment Process

This section provides details regarding the enrollment process when initiated from a client or QR code. An instance of the services is hosted by Aware at www.awareid.aware-apis.com.

Enrollment with AwareID requires both a face capture and a document capture. The face from the document is matched against the face capture from the application to ensure that the user is owner of the document.

Enrollment can be done in one of two ways.

Client Based

Get Access Token

Retrieve an “access_token”, this token allows communication between the client application and the AwareID servers. For this enrollment method the user is required to enter some configuration information:

Configuration Variables

   mUserName - A name used to identify the enrollment.
   mEmail - An email used to identify the enrollment.
   mPhoneNumber - A phone number used to identify the enrollment.
   mCustomerName - The customer’s name to access the AwareID server.
   mHostname - The URL of the AwareID server ex. https://awareid.aware-apis.com/mCustomerName
   mApiKey - Used to access the AwareID server.
   mClientSecret - Used to access the AwareID server.

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 - Retrieve Access Token

The “access_token” is saved and used as the “JWT” in future calls to the AwareID server.

Response - openid-connect

   STATUS CODE 200
   {
       "access_token": "eyJhbGciOiJSUzI1NiIsI...",
       "expires_in": 300,
       "refresh_expires_in": 0,
       "token_type": "Bearer",
       "id_token": "eyJhbGciOiJSUzI1NiI...",
       "not-before-policy": 0,
       "scope": "openid"
   }

QR Code Based

Generate QR Code

Web Portal

To start an enrollment using the QR code method a QR code must first be generated 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 /triggerEnroll.

Trigger Enroll

Enrollment is initiated by calling the /triggerEnroll endpoint with the received access token.

  • 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 : "iVBORw0KGgoAAAA..."
       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.

Decrypt The QR Code

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

This data must be decrypted using the available public key. Once decoded three 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.

Decode The base64 URL Encoded Data

iOS

Decode The base64 URL Encoded Data

       static func convertBytesArrayToBase64String(bytesArray: [UInt8]) -> String? {
      let originalData = NSData(bytes: bytesArray, length: bytesArray.count)
      let base64Data = originalData.base64EncodedData(options: NSData.Base64EncodingOptions.endLineWithLineFeed)
      let base64String = String(data: base64Data, encoding: String.Encoding.utf8)
      return base64String
  }

Extract Signature and Encrypted Data

iOS

Extract Signature And Encrypted Data

       let tag = "com.aware.keys.main".data(using: .utf8)!
   let getQuery: [String: Any] = [kSecClass as String: kSecClassKey,
                                   kSecAttrApplicationTag as String: tag,
                                   kSecAttrKeyType as String: kSecAttrKeyTypeEC,
                                  kSecReturnRef as String: true]
   var item: CFTypeRef?
   let status = SecItemCopyMatching(getQuery as CFDictionary, &item)
       let key = item as! SecKey
   var error: Unmanaged<CFError>?
   let data = plainText.data(using: .utf8)!
   guard let signature = SecKeyCreateSignature(key, .ecdsaSignatureMessageX962SHA256, data as CFData, &error) else {
       throw error!.takeRetainedValue() as Error
   }
   let signedData = signature as Data
   let signedString = signedData.base64EncodedString()

Verify Signature

Verify the signature using the public key.

Server Key

 String serverPublicKeyEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj1v8H6ehFSCfm23Z12W5tWr9UQM8+kWJsZqplgE7QcuhbM97G1bs874ouKjojdWmFHuLSkEuUNi9oIU3USJhSaCUmseD7CI0Tui4ODy8Y/3++BNqYGXAG2XQhNuGx4/6JVCg33zL46yl7zAj5fdl5+tJ5DrITDqf12dcwdPNTOM18ddBkKRL0oD4eIx2IGc4oCEBPghJlQCmDAuuXsuaNQc12sOo2BC9Uf+TQgIe5OjptAEaZLIEYTKle66yrWlZ+o0T028DtK971UUMmBQ0Uk+JKKfvTMkgCam4lZ8UMmBeaogYF5UPcMsoQlfkqjo3RILEyCaeW97ZAw3oq70DjwIDAQAB";

iOS

Verify Signature

       public func verify(with key: PublicKey, signature: Signature, digestType: Signature.DigestType) throws -> Bool {

       let digest = self.digest(digestType: digestType)
       var digestBytes = [UInt8](repeating: 0, count: digest.count)
       (digest as NSData).getBytes(&digestBytes, length: digest.count)

       var signatureBytes = [UInt8](repeating: 0, count: signature.data.count)
       (signature.data as NSData).getBytes(&signatureBytes, length: signature.data.count)

       let status = SecKeyRawVerify(key.reference, digestType.padding, digestBytes, digestBytes.count, signatureBytes, signatureBytes.count)

       if status == errSecSuccess {
           return true
       } else if status == -9809 {
           return false
       } else {
           throw SwiftyRSAError.signatureVerifyFailed(status: status)
       }
   }

Rebuild Key Using SecretKeySpec

iOS

Rebuild Key Using SecretKeySpec

       let attributes: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeEC, kSecAttrKeySizeInBits as String:  256, kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: true,kSecAttrApplicationTag as String: tag]]
       var error: Unmanaged<CFError>?
   guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
       throw error!.takeRetainedValue() as Error
   }
   let publicKey = SecKeyCopyPublicKey(privateKey)
   let publicKeyData = SecKeyCopyExternalRepresentation(publicKey!, nil)
   let publicKeyNSData = NSData(data: publicKeyData! as Data)
   let publicKeyBase64Str = publicKeyNSData.base64EncodedString()

The following steps are the same for both client based and QR code based enrollment

Initiate An Enrollment

With this method type we start onboarding with accessToken, sessionToken and apikey.

Initiate An Enrollment

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

   {
      "sessionToken": "sessiontoken"
   }

Response - Initiate an Enrollment

Response - Initiate An Enrollment

   STATUS CODE 200
   {
       "enrollmentToken": "be00a983-e60a-44de-8685-70da3b1b98be",
       "userExistsAlready": false,
       "requiredChecks": [
           "addDevice",
           "addFace",
           "addDocument"
       ]
   }

Get Device ID

iOS

Get Device Id

       let deviceId = UIDevice.current.identifierForVendor?.uuidString

Add Device

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

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

Add Face Sample

Send a facial image to the back end to verify liveness. If the subject is live, the facial image will be kept for verification. The addFace API call requires the JSON package generated by the Face Capture SDK.

Add Face Sample

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

   {
       "enrollmentToken": "enrollmentToken",
       "faceLivenessData":
          {
            "video": {
            "workflow_data": {
               "workflow": "hotel2",
               "rotation": 0,
               "frames": [
                   "data":"face package data generated by face sdk",
                   "data":"face package data generated by face sdk",
                   "data":"face package data generated by face sdk"
               ]
           },
           "meta_data": {
               "client_device_brand": "Unknown",
               "username": "username",
               "client_version": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66"
           },
           "client_version": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66"
       }
     }
   }

Response - Add Face 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 too 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": 1,
       "registrationCode": "LLXL2N",
       "faceLivenessResults": {
           "video": {
               "liveness_result": {
                   "decision": "LIVE",
                   "feedback": [],
                   "score_frr": 1.1757098732441127
               }
           }
       }
   }

Add Document OCR

This method takes the data captured from the document capture SDK.

Add Document OCR

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

   {
       "documentsInfo": {
           "documentPayload": {
               "request": {
                   "data": {
                       "ContainerList": {
                           "List": [{
                               "License": "AAEAAHQU5U8HN..."
                               "buf_length": 1724,
                               "light": 0,
                               "list_idx": 0,
                               "page_idx": 0,
                               "result_type": 50
                           }, {
                               "EncryptedRCL": "MDAwMXjaJJdlUyv..."
                               "buf_length": 1063742,
                               "light": 0,
                               "list_idx": 0,
                               "page_idx": 0,
                               "result_type": 49
                           }]
                       },
                       "TransactionInfo": {
                           "ComputerName": "localhost",
                           "DateTime": "2023-06-29T12:03:04.472Z",
                           "SystemInfo": "Linux, localhost, 5.10.81-12-9-24339823-abS901U1UEU2AVF7, #1 SMP PREEMPT Tue Jun 21 00:33:42 UTC 2022, aarch64",
                           "TransactionID": "903639b3-dad8-4cdb-9c14-cc25ab624019",
                           "UserName": "u0_a952",
                           "Version": "6.8.9145"
                       }
                   },
                   "vendor": "REGULA"
               }
           },
           "processParam": {
               "alreadyCropped": true
           }
       },
       "enrollmentToken": "64e401db-a6f0-4484-9930-c948abeaaf09"
   }

Response - Add Document OCR

Response - Add Document OCR

  STATUS CODE 200
  {
       "enrollmentStatus": 0,
       "registrationCode": "",
       "matchResult": true,
       "matchScore": 5.8946095,
       "ocrResults": {
               "mrzPresence": false,
               "documentType": "United States - ePassport (2005) Page 3",
               "year": "2005",
               "documentTypeId": "-705504038",
               "fidType": "Passport Page",
               "overallResult": "FAILED",
               "rfidValidationResults": null,
               "authenticityResult": {
                       "authenticityImagePatternCheck": {
                               "securityElements": [],
                               "overallResult": "UNDEFINED"
                       },
                       "overallResult": "UNDEFINED"
               },
               "overallResultScore": 0,
               "icaoCode": "USA",
               "fidTypeId": "240",
               "signatureImage": "/9j/4AAQS..."

       "overallResultInfo": {
                       "fieldErrorCodes": ["MRZ_NONE", "VISUAL_NONE", "BARCODE_NONE", "DOCUMENT EXPIRED"],
                       "numberOfImages": 2,
                       "imagePairValid": false,
                       "analysisEngineErrorCodes": ["AUTHENTICITY_NULL"]
               },
               "countryName": "United States",
               "portraitImage": "/9j/4AAQSkZJRgAB..."
                       "rfidPresence": 1,
               "fieldType": [{
                       "name": "Document Class Code",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 0,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Issuing State Code",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 1,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Document #",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 2,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Date of expiry",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 3,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Date of issue",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 4,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Date of birth",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 5,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Place of Birth",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 6,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Surname",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 8,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Given names",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 9,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Nationality",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 11,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Sex",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 12,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Issuing Authority",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 24,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Surname And Given Names",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 25,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Nationality Code",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 26,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "MRZ Type",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 35,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Optional data",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 36,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Issuing State",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 38,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "MRZ Lines",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 51,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Check digit of document number",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 80,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Check digit of birth date ",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 81,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Check digit of expiry date",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 82,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Final check digit",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 84,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Age",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 185,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Check digit of 'Optional data'",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 195,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Other valid IDs",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 315,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Observations",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 318,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "DS Certificate Issuer",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 327,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Months to expire",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 364,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Age at issue",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 522,
                       "overallResult": "UNDEFINED"
               }, {
                       "name": "Years since issue",
                       "fieldResult": {
                               "isMrzStatusValid": "NOT_VALIDATED",
                               "isBarcodeStatusValid": "NOT_VALIDATED",
                               "mrz": "",
                               "mrzVisualCompareValid": "NOT_COMPARED",
                               "isVisualStatusValid": "NOT_VALIDATED",
                               "visual": "",
                               "barcode": "",
                               "mrzBarcodeCompareValid": "NOT_COMPARED",
                               "visualBarcodeCompareValid": "NOT_COMPARED"
                       },
                       "typeId": 523,
                       "overallResult": "UNDEFINED"
               }],
               "icaoVerificationResult": false
       },
       "retryDocumentCapture": false,
       "documentVerificationResult": false,
       "icaoVerificationResult": false,
       "icaoChipValidationResults": null
  }

Software Acknowledgments

AwareID Document Capture libraries incorporate third-party software. See the LICENSE file installed with the AwareID Document Capture software for the full license agreement.

CONTENTS