Document Verification
The Document Verification product lets you verify the authenticity of Identity documents submitted by your users and confirm that the document actually belongs to the user by comparing the user's selfie to the photo on the document. To run a document verification job, we require:
- 1.A selfie of the user
- 2.An image of the document
- 3.The country of issuance (this must be one of our supported document type and country, all supported documents and countries is listed in the next section)
For the full list of supported documents, please refer to the supported regions in our documentation.
We highly recommend using document verification product via the mobile SDKs or Web SDK (on a mobile device). This is because we require high image resolutions in order for our machine to check the authenticity of the document. You can still use document verification via the other integration options but you will be responsible for capturing the images to the required specification.
Document images should be sent in the right orientation depending on how the information is printed on the document.
To check the authenticity of the document, we require high resolution images. The image should be cropped to include the entire document with minimal background. The following is the minimum specification we require for the document image:
- Minimum resolution on the horizontal (longer) side of credit card sized IDs should be 1500 pixels
- Minimum resolution on the horizontal (longer) side of passports should be 2200 pixels
- Image size should not be less than 600KB
- Image size should not be more than 10MB
To get the best results on document verification, we recommend the image of the document meets the following criteria:
- 1.Image should not be tightly cropped
- 2.All boundaries of document is visible
- 3.The face on the document is visible
- 4.Document was placed on a flat non-white surface during capture
- 5.If document contains an MRZ code, no part of the code is covered by a finger or cut off the image
- 6.No part of the document is covered by a finger
- 7.There is no glare or bright light on the document
- 8.All text on the document must be readable after capture
You need to perform two steps to use this product:
- Make a request to Smile ID for a job to be performed
- Upload the job payload
NOTE: The value of the
job_type
for this product is 6
Request Type: POST
Environment | URL |
---|---|
Sandbox | |
Production |
Keys | Type | Required | Description |
source_sdk | string | Yes | The integration option you are using. For rest api send the value as "rest_api" |
source_sdk_version | string | Yes | The version of the integration option you are using |
signature | string | Yes | Your calculated access signature |
timestamp | string | Yes | The timestamp that was used to calculate the signature (in ISO date/time format) |
smile_client_id | string | Yes | This is your partner id which can be found on the side navigation panel of the Smile ID partner portal |
partner_params | object | Yes | A JSON object containing the partner parameters below as well as any additional key value pairs you wish to include for tracking which will be returned in the response |
{job_type | string | Yes | The type of job you want to perform. This should be set to 6 |
job_id | string | Yes | A value generated by you, so you can track jobs on your end. This value must be unique, can be any string and can follow your identifier convention |
user_id} | string | Yes | A value generated by you, so you can track users on your end. This value must be unique, can be any string and can follow your identifier convention |
model_parameters | string | No | This parameter is specific to mobile SDK, can be left as an empty JSON object |
callback_url | string | Yes | A publicly available endpoint on your system where Smile ID will send the results of a job to in the form of a POST request (with no authorisation headers) |
At the end of the request, you will receive a job number for tracking and a url where you will be uploading your images.
{
"source_sdk": "rest_api",
"source_sdk_version": "1.0.0",
"signature": "<calculated signature>",
"timestamp": <timestamp e.g. 2021-08-12T17:57:00.614879>,
"smile_client_id": "<partner id>",
"partner_params":
{
"job_type": 6,
"job_id":"job_09876",
"user_id":"user_12345"
},
"model_parameters": {},
"callback_url": "https://<partner side callback URL>/"
}
In the response body to the prep upload request, you will receive an AWS s3 bucket link. You will upload the images for face and identity document verification to this link. The URL is structured like:
"https://smile-uploads-test.s3.us-west-2.amazonaws.com/videos/
<partner_id>/<partner_id>-<smile_job_id>-<random hash>/attachments.zip
?AWSAccessKeyId=<>
&Content-Type=application%2Fzip
&Expires=1598449184&Signature=<>
&x-amz-security-token=<>&x-amz-server-side-encryption=AES256"
200: OK
A record has now been created waiting for the job to be processed once the required data has been uploaded
{
"upload_url": "https://smile-uploads-test.s3.us-west-2.amazonaws.com/videos/<partner_id>/<partner_id>-<smile_job_id>-<random hash>/selfie.zip?AWSAccessKeyId=<>&Content-Type=application%2Fzip&Expires=1598449184&Signature=<>&x-amz-security-token=<>&x-amz-server-side-encryption=AES256",
"ref_id": "<partner_id>-<smile_job_id>-<random hash>",
"smile_job_id": "0000000001",
"camera_config": "null", ---sdk specific---
"code": "2202"
}
400: Bad Request
Trying to use a job_id in partner_params that has already been used
{
"error": "Job already exists. Did you mean to set the retry flag to true?",
"code": "2215"
}
To perform a job, Smile ID requires a Zip file that contains the following information:
- images - images are ID document photo (bearer's face must be visible), selfie and liveness images (optional)
- Info.json file - the structure of the info.json file is detailed below
The Zip file must have the same name as the file_name specified while making a job request (prep upload). In the case of the example request above, the filename will be attachments.zip.
Request Type: PUT
Environment | URL |
---|---|
Sandbox | Upload URL you were supplied while making a Job Request |
Production | Upload URL you were supplied while making a Job Request |
The request body will be of type binary (the zip file)
The info.json file contains the selfie and ID card images required to process the document verification job. The images can either be parsed inline as a base64 encoded string or the image files themselves can be zipped with the info.json file. Only .jpg file type is supported.
The structure of the info.json file is detailed below
Parameter | Description |
---|---|
package_information | This contains information about the rest api you’re calling. We recommend you use the following as the package_information: "package_information": { "apiVersion": { "buildNumber": 0, "majorVersion": 2, "minorVersion": 0 }
} |
id_info | The country and id type you want to verify. The uploaded ID card image must match the country and id type you specify in this json object. To view the list of supported documents check the supported documents section on this page.
"id_info": { "country":"<country code e.g. KE>", "id_type":"<smile ID type keyword e.g. NATIONAL_ID>" }
⚠️ id_type is optional. If a job is submitted without id_type and the machine can't classify the document, we will reject the job. |
images | The images required for the document verification job. There are 3 image types that can be uploaded:
The images can be added as base64 encoded strings or the image files themselves can be added to the zip and the filename specified in the info.json.
{ "image_type_id": “varies based on image type and type of upload either base64 string or filename. Read more on image types in FAQs”, "image": "<base64 string of image>", "file_name": "<name of file in the zip that will be uploaded>" }
Depending on the image_type_id one of the other parameters (image or file_name) will be an empty string (“”) |
The zip file contains the info.json file only (if images are inline i.e. supplied as base64 encoded strings) or both an info.json file and image files (if the image files themselves are uploaded).
Example zip file and info.json when images are inline (i.e. base64 encoded strings)
The zip file contains only the info.json file and no image files.
The content of the info.json file below:
{
"package_information":
{
"apiVersion": {
"buildNumber": 0,
"majorVersion": 2,
"minorVersion": 0
}
},
"id_info":
{
"country":"<country code e.g. NG>",
"id_type":"<smile ID type keyword e.g. PASSPORT>"
},
"images": [
{
<Use this for the selfie>
"image_type_id": 2,
"image": "iVBORw0KGgoAAAANSUhEUgAAArgWElmTU0A- - -truncated base64 string",
"file_name": ""
},
{
<Use this for the ID card>
"image_type_id": 3,
"image": "iVBORw0KGlDQ1BJQ0MgUHJvZmlsZQAASImVVw- - -truncated base64 string",
"file_name": ""
}
]
}
Example zip file and info.json when images are uploaded as files
The zip file contains the info.json file, selfie and ID card images.
The content of the info.json file below:
{
"package_information":
{
"apiVersion": {
"buildNumber": 0,
"majorVersion": 2,
"minorVersion": 0
}
},
"id_info":
{
"country":"<country code e.g. NG>",
"id_type":"<smile ID type keyword e.g. PASSPORT>"
},
"images": [
{
<Use this for the selfie>
"image_type_id": 0,
"image": "",
"file_name": "Selfie.jpeg"
},
{
<Use this for the ID card>
"Image_type_id": 1,
"image": "",
"file_name": "ID.jpg"
}
]
}
Action | Description |
Proof of life & spoof detection | Performed on user submitted selfie |
Selfie compares | Selfie comparison to user submitted document image |
Document Verification | To verify the document we confirm the following:
|
The full list of keys and possible return values are highlighted below:
Name | Type | Description | Value |
PartnerParams.job_id | String | A unique reference defined by you to keep track of the job | |
PartnerParams.job_type | String | The type of job you performed. | 6 |
PartnerParams.user_id | String | A unique reference defined by you to keep track of the user | |
ResultCode | String | Numeric value of the job outcome. | |
ResultText | String | Textual value of the job outcome. Human readable value for the result. | |
SmileJobID | String | The Smile internal reference number for the job | |
Country | String | The country of issuance of the ID type | |
IDType | String | The ID type of the document ID | |
IDNumber* | String | The ID number extracted from the document ID either by OCR or decoding the MRZ | |
FullName* | String | The full names on the document ID extracted either by OCR or decoding the MRZ | |
DOB* | String | The date of birth extracted from the document ID either by OCR or decoding the MRZ | |
Gender* | String | The gender extracted from the document ID either by OCR or decoding the MRZ | |
ExpirationDate* | String | The expiration date of the document ID extracted from the document ID either by OCR or decoding the MRZ | |
Document | String | The cropped and upright document image returned as a base64 string | |
PhoneNumber* | String | The phone number extracted from the document ID either by OCR or decoding the MRZ | |
PhoneNumber2* | String | The second phone number extracted from the document ID either by OCR or decoding the MRZ | |
Address* | String | The address extracted from the document ID either by OCR or decoding the MRZ | |
signature | String | The outgoing signature, you can use this to verify that the response is from Smile ID | |
timestamp | String | The outgoing timestamp in ISO date/time format, use this to calculate the outgoing Signature | |
Actions | Object | The JSON object contains the results of checks Smile ID performed on the job | |
{Human_Review_Compare | String | If the Smile ID system can not automatically decide on the face compares it will be reviewed by humans and the result will be displayed here | “Passed” “Failed” “Unable to Determine” “Not Applicable” |
Human_Review_Liveness_Check | String | If the Smile ID system can not automatically decide on the liveness of the user submitted selfie, it will reviewed by humans. The result is displayed here.
NOTE: the machine liveness check result Liveness_Check is reported as failed even if the reviewer passes the review | “Passed” “Failed” “Unable To Determine” “Not Applicable” |
Liveness_Check** | String | Liveness check on user provided selfie | “Passed” “Failed” “Under Review” “Not Applicable” |
Register_Selfie | String | Register selfie of user | “Approved” “Rejected” “Not Applicable” |
Verify_Document | String | Verify the document ID submitted by the user | “Passed”
“Failed”
“Under Review”
“Not Applicable” |
Return_Personal_Info | String | Return user’s PII from OCR / MRZ | “Returned” “Not Returned” “Not Applicable” |
Selfie_To_ID_Card_Compare} | String | Compare user-submitted selfie to photo on user-submitted ID card | “Completed” “Under Review” “Not Applicable” |
*Only returned if information is on the physical ID card
** If a single selfie image is provided, the system will only perform a photo of photo check
{
DOB: "1989-01-20",
FullName: “John Joe Doe”,
Gender: “M”,
IDType: "PASSPORT",
Actions: {
Liveness_Check: "Passed",
Register_Selfie: "Approved",
Verify_Document: "Passed",
Human_Review_Compare: "Passed",
Return_Personal_Info: "Returned",
Selfie_To_ID_Card_Compare: "Completed",
Human_Review_Liveness_Check: "Passed"
},
Country: "NG",
Document: "----base64 encoded string----”,
IDNumber: "B00123456",
ResultCode: "0810",
ResultText: "Document Verified After Human Review",
SmileJobID: "0000000046",
PartnerParams: {
job_id: "Testing_0036",
user_id: "Test_0036",
job_type: 6
},
ExpirationDate: "2025-11-26",
timestamp: "2021-12-14T20:07:56.829Z",
signature: "---signature---”
}
Actions performed on the product are not completed at the same time, so we send results to your callback endpoint when they are ready. Also, if the Smile ID system can not automatically make a decision on an action it is passed to our human reviewers, the system decision is sent via callback once the reviewers make a final decision.
The Document Verification can fail for multiple reasons:
- 1.A spoof was detected on the submitted selfie - if we believe the selfie has been tampered with or is a picture of a picture, the document verification will fail.
- 2.The submitted selfie does not match the face on the document - if the selfie and face on the document do not match, the document verification job will fail.
- 3.The document is expired.
- 4.The OCR extracted information and the decoded MRZ information do not match e.g. name encoded in the MRZ does not match the name that can be seen on the document.
- 5.The document image or selfie is blurry.
- 6.Some known visible security features on the document are missing e.g. the coat of arms on a Nigerian driver’s license.
- 7.The id type specified by the user does not match our system’s classification of the document type.
Result codes details what the current (or final) result of a job is. Result Codes for all jobs fall into one of two categories:
- 1.Approved (or Pass) This means that all applicable Actions passed and the overall job was approved.
- 2.Rejected (or Fail) This means that one or more of the applicable Actions for job failed, and thus, the overall job was rejected according to Smile ID standards.
This means no further processing is possible on the job. General failures occur when a job could not be submitted due to a logical/technical issue. These jobs do not show up in the portal and do not have a Smile Job ID.
Code | Text | Description | Category |
0001 | Data Invalid | Uploaded zip is corrupted | Rejected |
0001 | Data Invalid - Images corrupt or not present | info.json lists an image file that was not included in the zip | Rejected |
0001 | ID Card image not provided | There was no ID card image submitted with the job | Rejected |
0001 | System Error | A system error occurred | Rejected |
0903 | Zip Corrupt | The uploaded Zip file is corrupted. | Rejected |
2405 | Error - "You are not authorised to do that" * | An invalid signature was used to sign the request. | - |
2314 | Error - No Zip File Received | No Zip files was uploaded. | - |
2203 | Error - Invalid JSON | The info.json file in the Zip is not properly structured. Ensure all keys are present and properly named. | - |
2213 | Error - A required parameter is missing | Not all the required keys were submitted in the info.json or request payload. Please check request values for this product. | - |
2204 | Error - A parameter is of the wrong data type | - | |
2205 | Error - You are not authorised to do that. * | An invalid signature was used to sign the request. Please ensure you are using the correct signature for the environment (ie: sandbox vs production) | - |
2220 | You have not completed your KYC. | - | |
2212 | Error - Invalid job type | An invalid value was inputted in the job_type key. Change the value to 6. | - |
2209 | Error - Wrong user id. This user is already enrolled with user_id | An existing user_id was inputted. Enter a unique user id. | |
2215 | Error - Job already exists for job_id | An existing job_id was inputted. Enter a unique job id. | - |
Code | Text | Description | Category |
---|---|---|---|
0810 | Document Verified | Images matched, no spoof was detected on Selfie and the document is valid. | Approved |
0811 | Unable to Verify Document - reason | Document image was usable but document verification failed due to any of the following reasons:
- Document is expired
- The selfie did not match the photo on document
- Selfie failed liveness checks
- Some security features were missing on the document
- The information on document is inconsistent i.e. the MRZ information did not match the OCR'ed information
- A wrong document type was uploaded | Rejected |
0812 | Unable to verify Document - reason | Document verification failed because the document image is unusable or an invalid document image was uploaded e.g. work ID card | Rejected |
0816 | Unable to verify Document - Unsupported Document | Provided document is not supported for KYC i.e. document is one of the following:
- Minor's Passport
- Carry Permit
- Hunting Permit
- Sex Offender ID
- SIM Card | Rejected |
1014 | Unsupported ID Type | The country_code and or the id_type in the info.json file is not supported, please use any of the supported country_codes and id_types in the documentation | Rejected |
Document verification can be tested in our sandbox environment. However, you will get a simulated response. In sandbox, the document verification job is processed as described below:
- The selfie is compared to the photo on the identity document, if both images do not match the document verification job fails
- The authenticity of the document is not confirmed and we will always return the document as been valid
- The values you parse in
id_type
andcountry
are not checked with the supported countries and ids
Document verification can be performed on users that have been previously enrolled successfully through an Biometric KYC or SmartSelfie™ Authentication - User Registration.
When performing document verification for an already enrolled user, you do not need to submit a selfie in the info.json file. You only send the user_id of the user, the image of the document ID, and set the flag
use_enrolled_image
to true during prep upload.You need to perform two steps to use this product:
- 1.Make a request to Smile ID for a job to be performed
- 2.Upload the job payload
Request Type: POST
Environment | URL |
---|---|
Sandbox | |
Production |
Keys | Type | Required | Description |
source_sdk | string | Yes | The integration option you are using. For rest api send the value as "rest_api" |
source_sdk_version | string | Yes | The version of the integration option you are using |
signature | string | Yes | Your calculated access signature |
timestamp | string | Yes | The timestamp that was used to calculate the signature (in ISO date/time format) |
smile_client_id | string | Yes | This is your partner id which can be found on the side navigation panel of the Smile ID partner portal |
use_enrolled_image | boolean | No | Perform document verification for a registered user i.e. use the user’s registered selfie |
partner_params | object | Yes | A JSON object containing the partner parameters below as well as any additional key value pairs you wish to include for tracking which will be returned in the response |
{job_type | string | Yes | The type of job you want to perform. This will be set to 6. |
job_id | string | Yes | A value generated by you, so you can track jobs on your end. This value must be unique, can be any string and can follow your identifier convention |
user_id} | string | Yes | An existing user_id. The uploaded document will be compared to the selfie registered to this user. |
model_parameters | string | No | This parameter is specific to mobile SDK, can be left as an empty JSON object |
callback_url | string | Yes | A publicly available endpoint on your system where Smile ID will send the results of a job to in the form of a POST request (with no authorisation headers) |
At the end of the request, you will receive a job number for tracking and a url where you will be uploading your images
{
"signature": "<calculated signature>",
"timestamp": <timestamp e.g. 2021-08-12T17:57:00.614879>,
"smile_client_id": "<partner id>",
"use_enrolled_image": true,
"partner_params":
{
"job_type": 6,
"job_id":"job_09876",
"user_id":"user_12345"
},
"model_parameters": {},
"callback_url": "https://<partner side callback URL>/"
}
In the response body to the prep upload request, you will receive an AWS s3 bucket link. You will upload the images for face and identity document verification to this link. The URL is structured like:
"https://smile-uploads-test.s3.us-west-2.amazonaws.com/videos/
<partner_id>/<partner_id>-<smile_job_id>-<random hash>/attachments.zip
?AWSAccessKeyId=<>
&Content-Type=application%2Fzip
&Expires=1598449184&Signature=<>
&x-amz-security-token=<>&x-amz-server-side-encryption=AES256"
200: OK
A record has now been created waiting for the job to be processed once the required data has been uploaded
{
"upload_url": "https://smile-uploads-test.s3.us-west-2.amazonaws.com/videos/<partner_id>/<partner_id>-<smile_job_id>-<random hash>/selfie.zip?AWSAccessKeyId=<>&Content-Type=application%2Fzip&Expires=1598449184&Signature=<>&x-amz-security-token=<>&x-amz-server-side-encryption=AES256",
"ref_id": "<partner_id>-<smile_job_id>-<random hash>",
"smile_job_id": "0000000001",
"camera_config": "null", ---sdk specific---
"code": "2202"
}
400: Bad Request
Trying to use a job_id in partner_params that has already been used
{
"error": "Job already exists. Did you mean to set the retry flag to true?",
"code": "2215"
}
To perform a job, Smile ID requires a Zip file that contains the following information:
- ID card image
- Info.json file - the structure of the info.json file is detailed below
The Zip file must have the same name as the file_name specified while making a job request (prep upload). In the case of the example request above, the filename will be attachments.zip.
Request Type: PUT
Environment | URL |
---|---|
Sandbox | Upload URL you were supplied while making a Job Request |
Production | Upload URL you were supplied while making a Job Request |
The request body will be of type binary (the zip file)
The info.json file contains the ID card image required to process the document verification job. The image can either be parsed inline as a base64 encoded string or the image files themselves can be zipped with the info.json file. Only .jpg file type is supported.
The structure of the info.json file is detailed below
Parameter | Description |
---|---|
package_information | This contains information about the rest api you’re calling. We recommend you use the following as the package_information: "package_information": { "apiVersion": { "buildNumber": 0, "majorVersion": 2, "minorVersion": 0
} } |
id_info | The country and id type you want to verify. The uploaded ID card image must match the country and id type you specify in this json object. To view the list of supported documents check the supported documents section on this page.
"id_info": { "country":"<country code e.g. KE>", "id_type":"<smile ID type keyword e.g. NATIONAL_ID>" } |
images | The image required for the document verification job. There is only one image type required, since the job will use a registered selfie:
The images can be added as base64 encoded strings or the image files themselves can be added to the zip and the filename specified in the info.json.
{ "image_type_id": “varies based on image type and type of upload either base64 string or filename. Read more on image types in FAQs”, "image": "<base64 string of image>", "file_name": "<name of file in the zip that will be uploaded>" }
Depending on the image_type_id one of the other parameters (image or file_name) will be an empty string (“”) |
The zip file contains the info.json file only (if images are inline i.e. supplied as base64 encoded strings) or both an info.json file and image files (if the image files themselves are uploaded).
Example zip file and info.json when images are inline (i.e. base64 encoded strings)
The zip file contains only the info.json file and no image files.
The content of the info.json file below:
{
"package_information":
{
"apiVersion": {
"buildNumber": 0,
"majorVersion": 2,
"minorVersion": 0
}
},
"id_info":
{
"country":"<country code e.g. NG>",
"id_type":"<smile ID type keyword e.g. PASSPORT>"
},
"images": [
{
<Use this for the ID card>
"Image_type_id": 3,
"image": "iVBORw0KGlDQ1BJQ0MgUHJvZmlsZQAASImVVw- - -truncated base64 string",
"file_name": ""
}
]
}
Example zip file and info.json when images are uploaded as files
The zip file contains the info.json file and the ID card image.
The content of the info.json file below:
{
"package_information":
{
"apiVersion": {
"buildNumber": 0,
"majorVersion": 2,
"minorVersion": 0
}
},
"id_info":
{
"country":"<country code e.g. NG>",
"id_type":"<smile ID type keyword e.g. PASSPORT>"
},
"images": [
{