Onfido LogoOnfido Logo


Verify users against 2 different documents


Follow this guide to be able to verify a single user against 2 different documents with a single live photo or live video.

Onfido allows you to complete 2 checks for a single applicant, against 2 different documents, without the user needing to upload a live photo or video twice.

Instead of asking the user to repeat the upload of a live photo or live video with a new document, it is possible to request the upload of a second document at the end of the standard capture flow. An additional check can then be submitted to compare the user's live photo or video, provided during the initial flow, with the second uploaded document. Using this process reduces friction and wait time for end users, allowing you to onboard customers quickly and efficiently whilst meeting the necessary requirements.

Concurrent checks are required for this flow. Please contact Onfido's Customer Support to enable this for your account.

Overview of steps

The following diagram illustrates the flow for a check containing 2 Document reports, one for an ID document and one for a driving license, and a single Facial Similarity video report:

Note: You can customize and re-order the steps for document and biometric capture based on the desired flow for your application.

Integration guidance

This guide assumes you're using the Onfido SDKs. If you have built your own capture experience you will need to adjust your experience to allow for the upload of 2 documents and 1 live photo or video in order to use this process.

Follow the steps below to create 2 checks for a single applicant against 2 different documents using the same live photo or video.

You may find our SDK reference pages for iOS, Android and Web useful.

1. Create an applicant

The first step in creating any check is to create an applicant from your backend server, using a valid API token.

For Document and Facial Similarity reports, you must at least specify the applicant's first and last names in the body of the request.

2. Generate an SDK token

Use your API token to make a request to the 'generate SDK token' endpoint, including the applicant ID you created in the previous step and a valid referrer.

You can use the same SDK token for both instances of the SDK.

3. Initialize the Onfido SDK

You'll need to setup the SDK to support the submission of 2 documents and 1 live photo or live video from an end user.

You can also customize the welcome screen of the SDK flow to specify to the end user which steps they will be presented with, including both document uploads.

The first instance of the SDK will allow the user to upload the first document and a live photo or video. The second instance of the SDK, once it has been re-initialized, will allow the user to upload the second document.

Example first initialization of the SDK (iOS)

1func StartCheck(){
2 GetSDKToken(tokenCreated: {response in
3 sdkToken = response["token"].rawString()!
4 let config = try! OnfidoConfig.builder()
5 .withSDKToken(sdkToken)
6 .withDocumentStep(ofType: .drivingLicence(config: nil))
7 .withFaceStep(ofVariant: .video(withConfiguration: nil))
8 .build()
10 let onfidoFlow = OnfidoFlow(withConfiguration: config)
11 .with(responseHandler: { results in
12 switch results {
13 case .success:
14 self.SendLicenceAndVideo()
15 case .cancel:
16 self.resetApp()
17 case .error(_):
18 self.resetApp()
19 @unknown default:
20 self.resetApp()
21 }
22 })
24 let onfidoRun = try! onfidoFlow.run()
25 self.present(onfidoRun, animated: true, completion: nil)
26 })
27 }

Example handle completion of first step (iOS)

1func SendLicenceAndVideo() {
2 let parameters: [String:Any] = [
3 "applicant_id": applicantId,
4 "report_names": [
5 "document",
6 "facial_similarity_video"
7 ],
8 "document_ids": [
9 firstDocumentId
10 ]
11 ]
13 AF.request("https://\(remoteServer)/create_checks",
14 method: .post,
15 parameters: parameters,
16 encoding: JSONEncoding.default,
17 headers: headers
18 ).responseJSON { response in
19 let banner = StatusBarNotificationBanner(title: "Starting first check: DL + video", style: .info)
20 banner.show(queuePosition: .front)
21 firstCheck = JSON(response.value as Any)
23 self.SecondStep()
24 }
25 }

4. Create a check

After the user has uploaded the first document and a live photo or video, create a check containing a Document report and one type of Facial Similarity report.

The first check will compare the first document uploaded to the live photo or video submitted.

5. Re-initialize the Onfido SDK

Without waiting for the first check to be completed, re-initialize the Onfido SDK for the second document capture flow.

The end user will not see that the SDK has been re-initialized, but will continue through the SDK flow process to upload a second document. After this step the user has completed the verification flow.

Note: You can re-initialize the SDK using the same SDK token or by generating a new SDK token. Example second initialization of the SDK (iOS)

1func SecondStep(){
2 let config = try! OnfidoConfig.builder()
3 .withSDKToken(sdkToken)
4 .withDocumentStep(ofType: .passport(config: nil))
5 .build()
7 let onfidoFlow = OnfidoFlow(withConfiguration: config)
8 .with(responseHandler: { results in
9 switch results {
10 case .success:
11 self.SendSecondDocument()
12 case .cancel:
13 self.resetApp()
14 case .error(_):
15 self.resetApp()
16 @unknown default:
17 self.resetApp()
18 }
19 })
21 let onfidoRun = try! onfidoFlow.run()
22 self.present(onfidoRun, animated: true, completion: nil)
23 }

Example handle completion of second step (iOS)

1func SendSecondDocument() {
2 // Note that a second check can't start on the same applicant while
3 // another one is ongoing. Your backend should handle this logic by
4 // implementing a Webhook listener and a check queue.
5 let parameters: [String:Any] = [
6 "applicant_id": applicantId,
7 "report_names": [
8 "document",
9 "facial_similarity_video"
10 ],
11 "document_ids": [
12 secondDocumentId
13 ]
14 ]
15 AF.request("\(remoteServer)/check_loop",
16 method: .post,
17 parameters: parameters,
18 encoding: JSONEncoding.default).response{ response in
19 print(response.value as Any)
20 }
21 self.resetApp()
23 let alert = UIAlertController(title: "Data upload completed", message: "You can monitor check progress\nand status on your Onfido Dashboard", preferredStyle: .alert)
25 alert.addAction(UIAlertAction(title: "Close", style: .default, handler: nil))
27 self.present(alert, animated: true)
28 }

6. Submit a second check

After the second document has been uploaded, submit a second check containing a Document report and Facial Similarity report. The second check will compare the second document uploaded to the live photo or live video submitted.

Note: If you require specific driving licence information, such as obtainment date, you can use the Document with Driving Licence Information document report in the associated check. Note: Any Facial Similarity report will always compare to the latest uploaded identity document associated with the applicant ID.

7. Recieve the results of both checks

If you have set up webhooks, a webhook notification will be sent upon completion of each check.

You can retrieve an individual check or report's status and result via the API. Further details on how to retrieve checks can be found in our API reference.