Run a Document verification check using the API
This developer guide takes you through the steps to run a Document verification check in the Passfort API 4.0 to confirm whether an individual's proof of identity document is 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 as well as proof of identity, for example, a driver's license.
Your data provider extracts addresses from documents.
Caution
It's not possible to run a variant of this check with Onfido on the Verify address task because Onfido does not extract the individual’s address from the document.
With this check, you upload the document directly to the profile. If you'd like to collect the document from the customer via the data provider's SDK, use the Document fetch check instead.
Where possible, we recommend using the Document fetch check because it also enables you to use any services the data provider is offering to check the quality of users' photos of documents. Contact your data provider to find out what services they offer.
In the portal, the name of the Document verification check is ID verification (Passfort collects documents).
Choose a profile and get the profile ID
Document verification checks are always run on profiles with the INDIVIDUAL
entity type.
Choose an individual profile to run the check on, and get the profile's ID number, for example, a2c4393a-e219-67a4-5ab4-2186952e9038
. You'll need it to make the request in the next step.
If you haven't created the profile yet, follow the steps to create a profile using the API. If you have access to the full Passfort product, 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 task ID, or
tasks.id
. Use the corresponding task alias (tasks.variant.alias
) to confirm you're looking at the right task. If there is more than one task with 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 stored 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.address_history
: An array of objects containing a list of the individual's addresses. Note that this field is only required if the document will be used to verify the individual's address.personal_details.dob
: The individual's date of birth. Note that this field is only required if you're using a check variant with Onfido or GBG ID3global as the data provider. If you're using a check variant with idvcheck as the data provider, this is an optional field.personal_details.nationality
: The individual's country of nationality. Note this field is only required if you're using a check variant with idvcheck or GBG ID3global as the data provider and the Check nationality option is also configured. If the Check nationality option is not configured, this is an optional field. If you're using Onfido, this field isn't used at all.
If the required fields do not exist on the profile or do not contain valid data, the check will return an error when you try to run it in the Run the check section.
To learn how to add/update the fields in the profile's collected_data
, see Update Passfort's profile data.
The document_id
is also a required field. We'll create it in the next step. To learn which optional profile fields can be used for this check and to learn about configuration options like the Check nationality option, see the information for your data provider: Onfido, GBG ID3global, idvcheck.
Create the document object
Follow these steps to add a document to the profile, using these specifications:
If you're using the Check facial similarity configuration option with Onfido, the
image_type
is a required parameter when you make the request to add thedocument_images
. Theimage_type
value must beFACE
for at least one of the document images.When you make the request to create the
document
object, send thecategory
anddocument_type
in the request body as follows.
Key | Value |
*Required string | On the Verify address task: On the Verify identity task, the value depends on your data provider:
|
*Required string | When the category is When the category is When the category is When the category is |
Run the check
To run the check, send a request to the following endpoint.
In the request body, include the document ID, which is returned when you created the document object in the previous section, and the task ID, which is returned when you got all data from the profile.
Note
If you forget to take note of the document ID or the task ID, send a request to get all data from the profile. The document ID is returned in collected_data.documents.id
and the task ID is returned in tasks.id
. If there is more than one task with the same alias, which happens when a task has more than one version, use the task with "is_expired": "false"
.
Request endpoint:
POST https://api.passfort.com/4.0/profiles/{profile_id}/checks
By default, the Document verification 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 request, include the following parameters in the body.
Key | Value | Description |
*Required string |
| The type of check that's being run. |
*Required string | Sample value: | The unique identifier for the document in the profile's documents. |
Optional, but we recommend including it whenever possible array of strings |
If you do not send a value for this key, the check is run on the Verify identity task when the document | The unique identifier for the task(s) the check will run on. |
*Required object | For a sample value, see the following sample request body. | Object to indicate which variant of the check will 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 on the Verify identity task, sending the document we created earlier.
Sample request body:
{ "check_type": "DOCUMENT_VERIFICATION", "document_id": "9a92b3c5-e804-06bc-cccc-6b3b43ea2a7a", "task_ids": [ "3d7a333c-418d-72a1-007b-06854dbb28eb" ], "variant": { "alias": "default" } }
Sample response:
{ "check_type": "DOCUMENT_VERIFICATION", "deadline": "2019-10-14 14:37:46", "document_id": "9a92b3c5-e804-06bc-cccc-6b3b43ea2a7a", "id": "ea565b55-47d9-1858-4588-3a22a3838707", "input_data": { "address_history": [ … ], "documents": [ { "category": "PROOF_OF_IDENTITY", "document_type": "PASSPORT", "id": "9a92b3c5-e804-06bc-cccc-6b3b43ea2a7a", "images": [ { "id": "ec1565b6-82c7-0577-8b3a-94462b67c97a", "image_type": "FRONT", "upload_date": "2019-10-03 14:05:19" }, { "id": "5562c4e4-4d12-b16a-a151-7c9eed6816e9", "image_type": "FACE", "upload_date": "2019-10-03 14:08:12" } ] } ], "entity_type": "INDIVIDUAL", "personal_details": { … }, }, "instructed_on": "2019-10-03 14:26:44", "performed_on": "2019-10-03 14:26:48", "providers": [ … ], "started_on": "2019-10-03 14:26:44", "state": "RUNNING", "task_ids": [ … ], "variant": { … } }
This check often takes a bit of time to run, so the check state
will likely be RUNNING
in the response because the response is returned immediately. See the next step to learn how to get the check results as soon as they come in 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 to learn what the result is.
This webhook sends a payload whenever results are returned from any check, including checks other than the Document verification 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 previously captured.data.check.check_type
: The type of check was run. When the Document verification check was run, the value isDOCUMENT_VERIFICATION
.data.check.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 previously.data.check.result
: The results of the check. Possible results for the Document verification check arePass
,Fail
, orError
. To learn what triggers each result, see the configuration topic for your data provider: Configuring Onfido v3, Configuring GBG ID3global, and Configuring idvcheck.
When the check results are returned from the data provider, Passfort cross-references the information from 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 verification check passed.
Sample payload:
{ "id": "33bae6b8-5689-b96b-143c-06e93ab8527e", "event": "CHECK_COMPLETED", "secret": "yourSecret", "timestamp": 1570807808, "data": { "check": { "check_type": "DOCUMENT_VERIFICATION", "id": "ea70ade9-3de3-1785-203b-68044cd3ecbb", "result": "Pass", "variant": { "alias": "gbg_document_verification", "id": "ea565b55-47d9-1858-4588-3a22a3838707", "name": "Default" } }, "customer_ref": null, "profile_id": "a2c4393a-e219-67a4-5ab4-2186952e9038" } }
Use the response to:
Confirm the check passed:
If the check has passed, the
data.check.result
isPass
.If the check hasn't passed, the
data.check.result
isFail
.If an error occurred, the
data.check.result
isError
.
See the following information to learn what forgery or image checks the data provider performed, 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 verification check returned an error. We can see from the response that this was because the image was outside the data provider's size limits.
Sample response:
{ "check_type": "DOCUMENT_VERIFICATION", "completed_on": "2019-10-03 14:28:02", "decision": "ERROR", "document_id": "9a92b3c5-e804-06bc-cccc-6b3b43ea2a7a", "errors": [ ], "id": "ea70ade9-3de3-1785-203b-68044cd3ecbb", "input_data": { "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" } } ], "documents": [ { "category": "PROOF_OF_IDENTITY", "document_type": "PASSPORT", "id": "9a92b3c5-e804-06bc-cccc-6b3b43ea2a7a", "images": [ { "id": "ec1565b6-82c7-0577-8b3a-94462b67c97a", "image_type": "FRONT", "upload_date": "2019-10-03 14:05:19" }, { "id": "5562c4e4-4d12-b16a-a151-7c9eed6816e9", "image_type": "FACE", "upload_date": "2019-10-03 14:08:12" } ] } ], "entity_type": "INDIVIDUAL", "personal_details": { "dob": "1975-04-19", "name": { "family_name": "Wheeler", "given_names": [ "Alex" ] }, "nationality": "GBR" } }, "instructed_on": "2019-10-03 14:26:44", "output_data": { "documents": [ { "category": "PROOF_OF_IDENTITY", "document_type": "PASSPORT", "id": "ce712852-ef66-11e9-9774-3607af249582", "images": [ { "id": "9e3ca2d4-ef66-11e9-bbe4-a6cea75352cd", "image_type": "FRONT", "upload_date": "2019-10-15 16:12:43" }, { "id": "b57b4e9a-ef66-11e9-a62d-3607af249582", "image_type": "FACE", "upload_date": "2019-10-15 16:13:22" } ], "verification_result": { "all_passed": false, "error_reason": "(ErrorSource.PROVIDER) Error 303: Provider Error: The supplied image is outside of the recommended sizes [en-GB] while running 'ID3Global IDScan' service." } } ], "entity_type": "INDIVIDUAL" }, "performed_on": "2019-10-03 14:26:48", "providers": [ { "instructed_on": "2019-10-03 14:26:44", "provider_name": "GB Group ID Scan", "variant_name": "GBG ID" } ], "result": "Error", "started_on": "2019-10-15 16:16:36", "state": "COMPLETE", "task_ids": [ "3d7a333c-418d-72a1-007b-06854dbb28eb" ], "variant": { "id": "5562c4e4-4d12-b16a-a151-7c9eed6816e9", "name": "Verify identity - Forexo" } }
The input_data.documents
array of objects that's returned in the response contains important information about the documents:
extracted_data
: An object containing all the information the data provider extracted from the document.verification_result.field_checks
: A set of comparisons between the information extracted from the data provider and the information in the profile.verification_result.forgery_checks
: The results of any forgery checks conducted by the data provider.verification_result.image_checks
: The results of any image quality checks conducted by the data provider.
The output_data.documents.verification_result
object that's returned in the response contains some important information about the check result:
all_passed
: When all the image, forgery, and field checks have passed, the value of this key istrue
. When one or more checks have failed, the value of this key isfalse
.document_type_passed
: When the correctdocument_type
was used, the value of this key istrue
. If an incorrectdocument_type
was used, the value of this key isfalse
.error_reason
: A description about why the check returned an error.field_checks
: An array of objects that contains one object for every profile field that was cross-referenced with the information extracted from the data provider.forgery_checks
: An array of objects that 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 key istrue
. When one or more forgery checks failed, the value of this key 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.image_checks_passed
: When all image checks performed by the data provider passed, the value of this key istrue
. When one or more image checks failed, the value of this key isfalse
.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.
Now that you have the results of the check, you may want to mark the task as complete.