Run a Document capture check using the API
This developer guide takes you through the steps to run a Document capture check in the PassfortAPI 4.0 to confirm whether an individual's proof of address and proof of identity documents are valid.
This check can be run on the following tasks:
Verify identity task (
INDIVIDUAL_VERIFY_IDENTITY
)Verify address task (
INDIVIDUAL_VERIFY_ADDRESS
)
If you'd like to use this check on the Verify address task, you should ensure that:
The documents provided contain proof of address.
Your data provider extracts addresses from documents.
We recommend using Document capture when you want to verify an individual’s proof of address and proof of identity with a single check, and you also want the data provider to collect the documents from the individual.
If you would prefer to add the documents to Passfort yourself, we recommend using the Document verification check.
In the portal, the name of the Document capture check is Document verification (service collects multiple).
The Document capture check process
The process for a Document capture check is as follows:
Run the check with Passfort. Passfort sends a request to the data provider to start the onboarding flow.
The data provider uses the phone number from the check input to contact the customer and request one proof of address document and/or one proof of identity document.
The data provider checks for signs of forgery and extracts any relevant data. Depending on the data provider, they may carry out more onboarding steps like having a video call with the customer.
The data provider sends all documents, extracted data, and, optionally, video call recordings to Passfort.
Choose a profile and get the profile ID
Document capture checks are always run on profiles with the INDIVIDUAL
entity type.
Choose an individual profile to run the check on, and take note of the profile's ID number, for example, a2c4393a-e219-67a4-5ab4-2186952e9038
. You'll need it to run the check later.
If you haven't created the profile yet, follow the steps to create a profile via the API. You can also create a profile via the portal. To get the profile ID, view the profile in the portal and copy the string of letters and numbers after /profiles/
in the URL.
Confirm the profile has the required fields for the check
To see all data on the profile, make a request to the following endpoint.
Request endpoint:
GET https://api.passfort.com/4.0/profiles/{profile_id}
In this example, data is returned for an individual profile named "Alex Wheeler." The profile has the Verify identity and Verify address tasks.
Sample response:
{ "applications": [ … ], "category": "APPLICANT", "checks": [ ], "collected_data": { "entity_type": "INDIVIDUAL", "address_history": [ { "address": { "type": "STRUCTURED", "country": "GBR", "locality": "London", "original_freeform_address": "Crown, 38, Street, London, W1 2ZT", "original_structured_address": { … }, "postal_code": "W1 2ZT", "route": "Street", "street_number": "38", "subpremise": "Crown" } } ], "contact_details": { }, "personal_details": { "dob": "1975-04-19", "name": { "family_name": "Wheeler", "given_names": [ "Alex" ] }, "national_identity_number": { }, "nationality": "GBR" } }, "collection_steps": [ ], "creation_date": "2019-10-03 13:48:16", "display_name": "Alex Wheeler", "document_images": [ ], "events": [ ], "has_associates": false, "has_collection_steps": false, "id": "a2c4393a-e219-67a4-5ab4-2186952e9038", "linked_to": [ ], "role": "INDIVIDUAL_CUSTOMER", "root_id": "6bba3592-d9de-1ee5-8e97-ba8d8d13c558", "status": "NORMAL", "tags": [ ], "task_progress": { … }, "task_types": [ "INDIVIDUAL_VERIFY_IDENTITY", "INDIVIDUAL_VERIFY_ADDRESS" ], "tasks": [ { "check_ids": [ ], "creation_date": "2019-10-03 13:48:16", "form_instance_ids": [ ], "id": "3d7a333c-418d-72a1-007b-06854dbb28eb", "is_complete": false, "is_expired": false, "is_skipped": false, "state": "INCOMPLETE", "type": "INDIVIDUAL_VERIFY_IDENTITY", "variant": { "alias": "verify_identity", "id": "ddc72ea7-6e45-cc3b-dc52-30a94b9ec8c2", "name": "Verify identity", "task_type": "INDIVIDUAL_VERIFY_IDENTITY" } }, { "check_ids": [ ], "creation_date": "2019-10-03 13:48:16", "form_instance_ids": [ ], "id": "72aadb55-8b02-8495-d6b0-e1627ec23612", "is_complete": false, "is_expired": false, "is_skipped": false, "state": "INCOMPLETE", "type": "INDIVIDUAL_VERIFY_ADDRESS", "variant": { "alias": "verify_address", "id": "5562c4e4-4d12-b16a-a151-7c9eed6816e9", "name": "Verify address", "task_type": "INDIVIDUAL_VERIFY_ADDRESS" } } ], "unresolved_event_types": [ ] }
Use the response to:
Confirm the profile has the type of task you want to run the check on. To run this check on the Verify address task, the profile must have a task with the
INDIVIDUAL_VERIFY_ADDRESS
type. To run this check on the Verify identity task, the profile must have a task with theINDIVIDUAL_VERIFY_IDENTITY
type.Take note of the corresponding task ID (
tasks.id
). Use the corresponding task alias (tasks.variant.alias
) to confirm that you're looking at the right task. If more than one task has the same alias, which happens when a task has more than one version, use the task with"is_expired": "false"
. Note that the task variant ID (tasks.variant.id
) won't be used to run this check, so you don't need to take note of it.Confirm the profile has data for these required keys, which are in the
collected_data
object:personal_details.name.given_names
: The individual's first and, if applicable, middle names.personal_details.name.family_name
: The individual's surname.contact_details.phone_number
: The individual's phone number. If you're using Intelli idbox as your data provider, you must include the country code, which can be added with + or 00.
If the required fields don't exist or contain invalid data, running the check returns an error.
To learn how to add or update the profile's collected_data
, see Update Passfort's profile data.
Run the check
To run the check, send a request to the following endpoint.
Request endpoint:
POST https://api.passfort.com/4.0/profiles/{profile_id}/checks
By default, the check will run asynchronously. You can also send mode
as a query parameter to run the check synchronously.
Note that if a response is not received from the data provider within 120 seconds, the mode will switch to asynchronous automatically, so you should always support asynchronous checks. Speak to your data provider to see if they guarantee a check response within 120 seconds.
Body parameters:
When you make the POST
request, include the following parameters in the body.
Key | Value | Description |
---|---|---|
*Required string |
| The check type. |
Optional, but we recommend including it whenever possible. array of strings | Sample value: | Array of strings where each string is a unique identifier for a task the check will run on. If this key is not included, the check is automatically assigned to all uncompleted |
Optional, but we recommend including it whenever possible. object | See the following sample request body for a sample value. | Object to indicate which variant of the check is run. |
*Required string This key is optional if | Sample value: | The check alias. |
*Required string This key is optional if | Sample value: | The unique identifier for the check. |
In the following example, we'll run the check with Intelli idbox as the data provider.
Sample request body:
{ "check_type": "DOCUMENT_CAPTURE", "task_ids": [ "3d7a333c-418d-72a1-007b-06854dbb28eb" ], "variant": { "alias": "default" } }
Sample response:
{ "check_type": "DOCUMENT_CAPTURE", "input_data": {…} "instructed_on": "2023-06-15 15:09:52", "performed_on": "2023-06-15 15:10:04", "started_on": "2023-06-15 15:09:52", "providers": […], "state": "RUNNING", "task_ids": [ "3d7a333c-418d-72a1-007b-06854dbb28eb" ], "variant": {…} }
This check often takes a bit of time to run, so the check state
will likely be RUNNING
in the response. See the following section to learn how to get the check result as soon as it comes back from the data provider.
Get the check result
Listen to the Check completed webhook to get a notification when the check is finished running and learn what the result is.
This webhook sends a payload whenever results are returned from any check.
Payloads from this webhook have several important keys:
secret
: Authenticate the request by ensuring this secret matches your secret.id
: The check ID. Use it to confirm the payload is for your check by matching it to the check ID you captured earlier.check_type
: The type of check that was run.variant.alias
: The alias for the check variant. You can use it for additional confirmation that the payload is for your check by matching it to the check variant alias you captured earlier.result
: The value for this key indicates the result of the check. To learn more about the results, see the configuration information for your data provider.
When the check results are returned from the data provider, Passfort cross-references the information from the individual’s collected_data
with the information returned from the data provider to ensure it matches. This means it's possible for the data provider to pass the check and for Passfort to fail the check.
In this example, a Document capture check run with Intelli idbox passed.
Sample payload:
{ "id": "33bae6b8-5689-b96b-143c-06e93ab8527e", "event": "CHECK_COMPLETED", "secret": "yourSecret", "timestamp": 1573048450, "data": { "check": { "check_type": "DOCUMENT_CAPTURE", "id": "ea565b55-47d9-1858-4588-3a22a3838707", "result": "Pass", "variant": { "alias": "intelli_idbox", "id": "ea70ade9-3de3-1785-203b-68044cd3ecbb", "name": "Intelli idbox" } }, "customer_ref": null, "profile_id": "a2c4393a-e219-67a4-5ab4-2186952e9038" } }
Use the response to:
Confirm the check has passed:
If the check has passed,
data.check.result
isPass
.If the check hasn't passed,
data.check.result
isFail
.If an error occurred,
data.check.result
isError
.
See the following section to learn what information the data provider extracted from the document, any error or failure details, and more.
Get more information about the check result
If you want to get more information about the check result, make a call to the following endpoint.
In the request body, include the check ID (check.id
) and the profile ID (data.profile_id
) from the webhook payload.
We recommend listening to the Check completed webhook to find out when the check is finished because it's more efficient than continuously polling the following endpoint.
Request endpoint:
GET https://api.passfort.com/4.0/profiles/{profile_id}/checks/{check_id}
In this example, the Document capture check passed.
Sample response:
{ "check_type": "DOCUMENT_CAPTURE", "completed_on": "2023-06-15 15:10:04", "decision": "PASS", "errors": [], "id": "ea925b55-47d9-1858-45c8-3a2264a38707", "input_data": {…}, "instructed_on": "2023-06-15 15:09:52", "output_data": { "documents": [ { "category": "PROOF_OF_IDENTITY", "document_type": "RESIDENCE_ID", "extracted_data": { "issued": "2010-01-01", "issuer": "Police", "number": "GR654321", "personal_details": { "dob": "1986-05-04", "gender": "M", "name": { "family_name": "Wheeler", "given_names": [ "Alex" ] } } }, "files": [ { "file_id": "1d36a7cc-b4c5-5bcd-898a-5891075259ea", "reference": "b9d39276-303b-11ed-a261-0242ac120002", "type": "LIVE_VIDEO" } ], "id": "1134a62c-5c6f-456e-9a2e-7e7f4f198be3", "images": [ { "file_id": "ec89da83-23bf-4585-9391-847f7e9add21", "id": "74fc6ffa-b231-4b28-a16d-3c254c08a055", "image_type": "FRONT", "upload_date": "2023-06-15 15:10:02" } ], "verification_result": { "all_passed": true, "document_type_passed": true, "field_checks": [ { "field": "FIELD_DOB", "result": "CHECK_VALID" }, { "field": "FIELD_FAMILY_NAME", "result": "CHECK_VALID" }, { "field": "FIELD_GENDER", "result": "CHECK_VALID" }, { "field": "FIELD_GIVEN_NAMES", "result": "CHECK_VALID" }, { "field": "FIELD_ISSUED", "result": "CHECK_VALID" }, { "field": "FIELD_NUMBER", "result": "CHECK_VALID" } ], "forgery_checks": [], "forgery_checks_passed": true, "image_checks": [ { "category": "Face Matching", "result": "PASS", "type": "Face Similarity" } ], "image_checks_passed": true, "provider_information": [ { "id": "father_name", "name": "Father's name", "value": "Father First Name GR" }, { "id": "father_surname", "name": "Father's surname", "value": "Father Last Name" }, { "id": "type_of_id", "name": "Type of ID", "value": "Residence ID" }, { "id": "reference_id", "name": "Reference ID", "value": "b9d39276-303b-11ed-a261-0242ac120002" } ] } }, { "category": "PROOF_OF_ADDRESS", "document_type": "UTILITY_BILL", "extracted_data": { "address_history": [ { "address": { "country": "GRC", "locality": "Athens", "original_freeform_address": "00, Bill Address, Athens, 12345", "original_structured_address": { "country": "GRC", "locality": "Athens", "postal_code": "12345", "route": "Bill Address", "street_number": "00" }, "postal_code": "12345", "route": "Bill Address", "street_number": "00", "type": "STRUCTURED" } } ], "issued": "2023-01-01", "personal_details": { "dob": "1986-05-04", "name": { "family_name": "Wheeler", "given_names": [ "Alex" ] } } }, "files": null, "id": "f7bdb744-01d9-413f-aebb-9c2a2e3a26c3", "images": [ { "file_id": "fd9ce992-0bc4-4973-af05-63f3631c85c1", "id": "363e476e-5866-4952-8e2d-d864556917f9", "image_type": "FRONT", "upload_date": "2023-06-15 15:10:03" } ], "verification_result": { "all_passed": true, "document_type_passed": true, "field_checks": [ { "field": "FIELD_ADDRESS", "result": "CHECK_VALID" }, { "field": "FIELD_DOB", "result": "CHECK_VALID" }, { "field": "FIELD_FAMILY_NAME", "result": "CHECK_VALID" }, { "field": "FIELD_GIVEN_NAMES", "result": "CHECK_VALID" }, { "field": "FIELD_ISSUED", "result": "CHECK_VALID" } ], "forgery_checks": [], "forgery_checks_passed": true, "image_checks": [ { "category": "Face Matching", "result": "PASS", "type": "Face Similarity" } ], "image_checks_passed": true } } ], "entity_type": "INDIVIDUAL", "external_refs": { "generic": "b9d39276-303b-11ed-a261-0242ac120002" } }, "performed_on": "2023-06-15 15:10:04", "providers": […], "result": "Pass", "started_on": "2023-06-15 15:09:52", "state": "COMPLETE", "task_ids": [ "3d7a333c-418d-72a1-007b-06854dbb28eb" ], "variant": {…} }
In the response, output_data
has a documents
array with one object for each document. See the verification_result
in each document object to get key information about the check result:
all_passed
: When all the data provider's checks have passed, the value of this field istrue
. When one or more checks have failed, the value of this field isfalse
.document_type_passed
: When the correctdocument_type
was used, the value of this field istrue
. If an incorrectdocument_type
was used, the value of this field isfalse
.error_reason
: This field contains a description about why the check returned an error.field_checks
: This array of objects contains one object for every profile field that was cross-referenced with the information extracted from the data provider.forgery_checks
: This array of objects contains one object for every forgery check performed by the data provider, along with a detailed result for each one.forgery_checks_passed
: When all forgery checks performed by the data provider passed, the value of this istrue
. When one or more forgery checks failed, the value of this field isfalse
.image_checks
: This array of objects contains one object for every image check performed by the data provider, along with a detailed result for each one.provider_name
: The name of the data provider.
For a description of every field that might be returned in the response, see the Passfort API reference for Get results of a specific check.