Getting started with API v2
The Onfido API is based on REST principles. It uses standard HTTP response codes and verbs, and token-based authentication.
If you’re just getting started with our API, read our Quick Start guides.
Requests and responses
You should use a Content-Type: application/json
header with all PUT and POST
requests except when uploading documents or live
photos. For these requests, use a Content-Type:
multipart/form-data
header.
Responses return JSON with a consistent structure, except when downloading documents, photos or videos.
You must make all your requests to the API over HTTPS and TLS 1.2, with Server Name Indication enabled. Any requests made over HTTP will fail.
Text fields support UTF-8, but do not allow certain special characters.
Token authentication
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
require 'onfido'
Onfido.configure do |config|
config.api_key = '<YOUR_API_TOKEN>'
end
api = Onfido::API.new
import sys
import onfido
import datetime
from onfido.rest import ApiException
from pprint import pprint
configuration = onfido.Configuration()
configuration.api_key['Authorization'] = 'token=' + '<YOUR_API_TOKEN>'
configuration.api_key_prefix['Authorization'] = 'Token'
api = onfido.DefaultApi(onfido.ApiClient(configuration))
$config = Onfido\Configuration::getDefaultConfiguration();
$config->setApiKey('Authorization', 'token=' . '<YOUR_API_TOKEN>');
$config->setApiKeyPrefix('Authorization', 'Token');
$api = new Onfido\Api\DefaultApi(
null,
$config
);
package com.onfidodemo.app;
import com.onfido.*;
import com.onfido.auth.*;
import com.onfido.models.*;
import com.onfido.api.DefaultApi;
import com.onfido.ApiException;
import com.onfido.models.Applicant;
import java.time.LocalDate;
import java.io.File;
import java.util.*;
String apiKey = "<YOUR_API_TOKEN>";
ApiClient defaultClient = Configuration.getDefaultApiClient();
ApiKeyAuth tokenAuth = (ApiKeyAuth) defaultClient.getAuthentication("Token");
tokenAuth.setApiKey("token=" + apiKey);
tokenAuth.setApiKeyPrefix("Token");
DefaultApi apiInstance = new DefaultApi();
const Onfido = require('onfido');
const defaultClient = Onfido.ApiClient.instance;
const tokenAuth = defaultClient.authentications['Token'];
tokenAuth.apiKey = 'token=<YOUR_API_TOKEN>';
tokenAuth.apiKeyPrefix = 'Token';
const api = new Onfido.DefaultApi();
The API uses token-based authentication. API tokens must be included in the header of all requests made to the API.
You can generate new tokens and find your existing ones in the ‘Tokens’ page on your Onfido Dashboard.
Requests made with sandbox tokens can be used to test our API before you go live. Requests made in sandbox mode will return dummy responses, and you won’t be charged.
To use the sandbox, you’ll need a sandbox API token. Go to the ‘Tokens’ page of your Onfido Dashboard, then select ‘Generate API token’ and then ‘Sandbox’.
API tokens
You can use API tokens to authenticate any API action described in this documentation.
If you do need to collect applicant data in the frontend of your application, we recommend that you use one of the Onfido SDKs.
You should limit live API token access to only the minimum number of people necessary, but you can use sandbox tokens to freely experiment with the Onfido API. You can read about the differences between the live and sandbox environments.
You should not embed API tokens in your backend code—even if it’s not public—because this increases the risk that they will be discovered. Instead, you should store them in configuration files or environment variables.
You should periodically rotate your live API tokens. When you no longer require your API tokens, you should revoke them.
You can read about token rotation in the next section.
API token rotation
On your Onfido Dashboard, you can create and revoke API tokens, and see when they were last used.
Create a new API token
Replace your old API token
Wherever you use your old API token, replace it with the new one. Your old tokens will continue to work until you revoke them, so you can rotate your tokens without users experiencing any downtime.
Confirm your old token isn’t in use
Revoke your old token
SDK tokens
All of the latest Onfido SDKs authenticate using “SDK tokens”, which are JSON Web Tokens (JWTs).
SDK tokens are restricted to an individual applicant and expire after 90 minutes, so you can safely use them in the frontend of your application.
Read about generating SDK tokens.
Mobile tokens
You should use Mobile tokens to authenticate with the Android and iOS SDKs if:
- you’re using the Android SDK at lower than version 4.11.0
- you’re using the iOS SDK at lower than version 12.2.0
You can generate Mobile tokens in the Onfido Dashboard.
Error codes and what to do
400 bad_request:
Make sure your request is formatted correctly.
401 authorization_error
Make sure you’ve entered your API token correctly.
401 user_authorization_error:
Contact an administrator about user permissions.
401 bad_referrer:
Check the referrer used to generate the SDK token.
401 expired_token:
Request a new SDK token.
403 account_disabled:
Please contact client-support@onfido.com.
403 trial_limits_reached:
Please contact client-support@onfido.com.
404 resource_not_found:
Make sure you’ve formatted the URI correctly.
410 gone:
The resource has been deleted or is scheduled for deletion.
422 validation_error:
Check the fields
property for a specific error message.
422 missing_billing_info:
Make sure you’ve provided your billing information before starting a check.
422 missing_documents:
Make sure you’ve uploaded the required documents before starting a check.
422 invalid_reports_names:
Make sure you’ve entered the report name(s) in the correct format (string).
422 missing_id_numbers:
Make sure you’ve supplied all required ID numbers.
422 invalid_check_type_for_variant:
Read about report types to see which variants are compatible with different check types.
422 facial_similarity_photo_without_document:
For standard checks, Facial Similarity reports must be paired with Document reports.
422 failed_check_requirements:
Check that all required information has been provided and correctly specified.
422 incomplete_checks:
There are other ongoing checks associated with this applicant.
429 rate_limit:
The rate limit has been reached. Please try again later.
500 internal_server_error:
The server encountered an error. If this persists, please contact client-support@onfido.com.
Error object
Validation error object
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"error": {
"type": "validation_error",
"message": "",
"fields": {
"email": {
"messages": [
"invalid format"
]
},
"name": {
"messages": [
"can't be blank"
]
}
}
}
}
Attribute | Description |
---|---|
type | string The type of error returned |
message | string A human-readable message giving more details about the error |
fields | hash The invalid fields and their associated errors. Only applies to validation errors |
Sandbox testing
To use the sandbox, you’ll need a sandbox API token. Go to the ‘Tokens’ page of your Onfido Dashboard, then select ‘Generate API token’ and then ‘Sandbox’.
You’ll find example API responses in the ‘HTTP’ language tab.
By default, sandbox API tokens start with a api_sandbox.
prefix, while live API tokens
start with a api_live.
prefix. This might vary if you’re using a different
region environment.
You can make all the same API requests in the sandbox environment as in the live one. You will also be notified of check and report status changes via your registered webhooks.
You can use the sandbox environment to check:
- your system’s network connectivity with the Onfido API
- your webhooks are working correctly
- you’re posting all required data in the correct format to the Onfido API
- you’re handling the Onfido API responses correctly
Key differences
The key differences between the sandbox and a live environment are:
- check data is not processed by Onfido services or third parties - this means that sandbox responses are faster than live responses
- check results are pre-determined (but contain the same result response structures as live requests)
- checks do not incur any charges
- applicants are isolated from the live environment (but applicant notification emails still get sent out to sandbox applicants)
Sandbox rate limits
For sandbox requests, there is currently a rate limit of 30 requests per minute.
When you hit the limit, you’ll receive a 429 Too Many Requests
error. You can read more about the API’s error codes.
Pre-determined responses
Create an applicant “Jane Unidentified”
POST /v2/applicants/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"first_name": "Jane",
"last_name": "Unidentified",
"dob": "1990-01-01"
}
$ curl https://api.onfido.com/v2/applicants \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "Jane",
"last_name": "Unidentified",
"dob": "1990-01-01"
}'
Create a check (Identity report) for “Jane Unidentified”
POST /v2/applicants/<APPLICANT_ID>/checks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"type": "express",
"reports": [
{
"name": "identity"
}
]
}
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/checks \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"type": "express",
"reports": [
{
"name": "identity"
}
]
}'
Pre-determined response
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2014-05-23T13:50:33Z",
"sandbox": true,
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"type": "express",
"status": "complete",
"result": "consider",
"results_uri": "<RESULTS_URI>",
"redirect_uri": null,
"reports": [
{
"id": "<REPORT_ID>",
"name": "identity",
"created_at": "2014-05-23T13:50:33Z",
"status": "complete",
"result": "unidentified",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>"
...
}
]
}
To help you test your integration, you can trigger pre-determined responses from the API using specific applicant last names:
Report | Variant | Applicant last name | Report result |
---|---|---|---|
Identity | standard | unidentified | unidentified |
Identity | kyc | consider | consider |
Document | n/a | consider | consider |
Watchlist | full | consider | consider |
Watchlist | kyc | consider | consider |
Facial Similarity | n/a | consider | consider |
Right to Work | n/a | consider | consider |
Proof of Address* | n/a | consider | consider |
- For the Proof of Address report, the document’s
issuing_country
must be specified when uploading the document via the document upload endpoint in order to trigger aclear
orconsider
result. If theissuing_country
field is not specified or is from an unsupported country (i.e. it is different from “GBR”), the report result will benull
and the report status will becancelled
.
All normal applicant attribute requirements apply when you create any sandbox check. For example to trigger an Identity report sandbox response, you need to specify:
title
first_name
last_name
gender
dob
addresses
country
Pre-determined responses for multiple-report checks
Create a check (Identity report to return ‘consider’, watchlist report) for “Jane Unidentified”
POST /v2/applicants/<APPLICANT_ID>/checks HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"type": "express",
"reports": [
{
"name": "identity"
},
{
"name": "watchlist"
}
],
"consider": [
"identity"
]
}
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/checks \
-H 'Authorization: Token token=YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"type": "express",
"reports": [
{
"name": "identity"
},
{
"name": "watchlist"
}
],
"consider": [
"identity"
]
}'
Pre-determined response
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-03-27T12:30:12Z",
"status": "complete",
"redirect_uri": null,
"type": "express",
"result": "consider",
"sandbox": true,
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"tags": [],
"results_uri": "<RESULTS_URI>",
"download_uri": "<DOWNLOAD_URI>",
"form_uri": null,
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"reports": [
{
"created_at": "2019-03-27T12:30:12Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "watchlist",
"properties": {
"records": []
},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "full",
"breakdown": {
"legal_and_regulatory_warnings": {
"result": "clear"
},
"politically_exposed_person": {
"result": "clear"
},
"sanction": {
"result": "clear"
}
}
},
{
"created_at": "2019-03-27T12:30:12Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "identity",
"properties": {},
"result": "unidentified",
"status": "complete",
"sub_result": null,
"variant": "standard",
"breakdown": {
"mortality": {
"result": null
},
"date_of_birth": {
"result": "unidentified",
"breakdown": {
"credit_agencies": {
"result": "unidentified",
"properties": {}
},
"voting_register": {
"result": "none",
"properties": {}
}
}
},
"address": {
"result": "unidentified",
"breakdown": {
"credit_agencies": {
"result": "unidentified",
"properties": {
"number_of_credit_agencies": "0"
}
},
"telephone_database": {
"result": "none",
"properties": {}
},
"voting_register": {
"result": "none",
"properties": {}
}
}
}
}
}
],
"paused": false,
"version": "2.0"
}
When you create a sandbox check with multiple reports, you can pass specific report types to the consider
parameter (in an array). Only these reports will return “consider”.
Go live
Add billing information:
Live checks cannot be requested without valid billing information, so please add billing information to your account via the Onfido Dashboard.
Generate a live API token:
You can generate live API tokens on the ‘Tokens’ page of your Onfido Dashboard.
Select ‘Generate API token’ then select ‘Live’.
Use the live API token:
Update your production system to use the live token.
Update webhook endpoints
Update webhook endpoints to handle live check/report status update events.
Rate limits
Rate limit reached error object
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": {
"type": "rate_limit",
"message": "Rate limit exceeded. Please try again later."
}
}
Onfido’s API enforces a maximum volume of requests per minute for all clients. Unless contractually agreed otherwise, the maximum rate is 400 requests per minute.
For sandbox requests, there is currently a rate limit of 30 requests per minute.
Any request over the limit will return a 429 Too Many Requests
error.
Avoiding the limit
To reduce the likelihood of being rate-limited, we recommend:
- running non essential or routine batch API jobs outside your peak hours.
- throttling batch jobs.
- implementing an exponential back-off approach for requests essential to your verification process, with an initial delay of 30 seconds.
- prioritising requests that are essential to verify an active user.
- setting up monitors and alerts for error responses on our API.
Regions
Change the region to ‘US’
$ curl https://api.us.onfido.com/v2/
Onfido.configure do |config|
config.region = 'us'
end
$config->setHost($config->getHostFromSettings(1, array("region" => "us")));
configuration.host = configuration.get_host_from_settings(1, {'region': 'us'})
defaultClient.setBasePath("https://api.us.onfido.com/v2");
defaultClient.basePath = 'https://api.us.onfido.com/v2';
Onfido offers region-specific environments. You can use these to store the data in your Onfido account at rest within a specific geographic region.
Regions have unique base URLs and API token formats:
Region | API base URL | API token format |
---|---|---|
EU Default | https://api.onfido.com/ |
|
US BETA | https://api.us.onfido.com/ |
Tokens prepended with api_live_us. and api_sandbox_us. |
Unless specified, all examples in the documentation refer to the https://api.onfido.com/
base URL and token format.
If you’re using one of the Onfido client libraries, then you must specify the region using the ISO 3166 two-letter country-code in lowercase. For example, us
. The correct base URL will be picked up automatically.
Client libraries
You can use supported client libraries to integrate with the Onfido API.
If you write your own library and would like us to link to it, please email api@onfido.com.
All client libraries are hosted on GitHub.
Java
Use the ‘api-java-client’ library.
JavaScript
Use the ‘api-javascript-client’ library.
Ruby
The team at Hassle have developed an open-source Ruby client library.
Python
Use the ‘api-python-client’ library.
PHP
Use the ‘api-php-client’ library.
Versioning
Backwards compatibility
The following changes are considered backwards compatible:
- adding new API endpoints
- adding new properties to the responses from existing API endpoints
- adding optional request parameters to existing API endpoints
- altering the format or length of IDs
- altering the message attributes returned by validation failures or other errors
- sending webhooks for new event types
- reordering properties returned from existing API endpoints
Changelog
Updated the example webhook event object. | |
Added documentation for using line1, line2, line3 for address. | |
Added documentation for building custom logic around Identity reports. | |
Added documentation on forbidden characters for names and addresses. | |
Added documentation on API token rotation. | |
Updated documentation on Mobile tokens and SDK tokens. | |
Updated documentation for Autofill endpoint and Document report results. | |
Added documentation surrounding logic around Document report results. | |
Added endpoint to download a live video frame. | |
Removed ‘Conditional checks’ section. | |
Added testing data for Proof of Address. | |
Added a ‘Run in Postman’ button linking to a Postman API collection. | |
Removed documentation for UK credit and criminal history reports. | |
Updated the Proof of Address documentation. | |
Added a new rate limits feature. | |
Removed documentation for India Aadhaar and PAN Card reports. | |
Added applicant deletion feature | |
Added Proof of Address report. | |
Added age_validation as a new breakdown on the Document report | |
Removed documentation for US-specific reports. | |
Added documents as a new report argument | |
Added new Autofill endpoint | |
Updated documentation on basic criminal history report Added support for additional criminal history report details for basic criminal history reports in create check Removed support for basic criminal history report as an express check |
|
Added new events to the webhooks section | |
Updated documentation on Facial Similarity checks Added support for Facial Similarity reports under sandbox responses |
|
Added a new token authentication scheme for the web SDK | |
Added report options for Watchlist full report | |
Added support for additional reports under sandbox responses | |
Added new client libraries | |
Added social_insurance as a id number type | |
Added support for basic criminal history report as an express check | |
Added support of testing multiple-report scenarios inside sandbox | |
Added support of additional criminal history report details in create check | |
Added documentation around tag support for checks Added more detailed description of applicant address requirements |
|
Added endpoint to download document for a particular applicant | |
Added charge_applicant_for_check support for standard check Added Drug Test support Updated Right to Work report document requirements Added SSN format specification |
|
Added two new sections:
|
|
Added the referrer argument to the JSON web token endpoint | |
Added endpoint: Added new check: |
|
Added two new endpoints: | |
Added Right to Work support Added documentation on criminal history supported options Added documentation on supported Applicant title values Added documentation on UK Address street attribute character limit restriction Added documentation on Create check suppress_form_email attribute |
|
Added Resume Report endpoint and Conditional Checks documentation | |
Added Report Type Groups (packages) support | |
Released API version v2 :
v1 ) is available here |
Postman
You can run the Onfido API version 2 collection in Postman:
The API version 2 Postman collection is at version 1.3.
In your Postman environment, you’ll need to define the apiToken
variable. If you know you need to use a non-default region API base URL, you should also set the baseUrl
variable in Postman.
You can read more in Postman’s documentation about managing environments.
Sample document, photo
You can use the following files for running test checks:
Applicants
An applicant represents the individual the check is being performed on. An applicant must exist before a check can be initiated.
Applicant object
An example applicant object
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<APPLICANT_ID>",
"created_at": "2014-05-23T13:50:33Z",
"delete_at": "2018-10-31T04:39:52Z",
"href": "/v2/applicants/<APPLICANT_ID>",
"title": "Mr",
"first_name": "John",
"middle_name": null,
"last_name": "Smith",
"gender": "Male",
"dob": "2013-02-17",
"telephone": "02088909293",
"mobile": null,
"country": "GBR",
"mothers_maiden_name": "Johnson",
"previous_last_name": null,
"nationality": "USA",
"country_of_birth": "USA",
"town_of_birth": "New York City",
"id_numbers": [
{
"type": "ssn",
"value": "433-54-3937"
},
{
"type": "driving_license",
"value": "I1234562",
"state_code": "CA"
}
],
"addresses": [
{
"flat_number": null,
"building_name": null,
"building_number": "100",
"street": "Main Street",
"sub_street": null,
"state": null,
"town": "London",
"postcode": "SW4 6EH",
"country": "GBR",
"start_date": "2013-01-01",
"end_date": null
},
{
"flat_number": "Apt 2A",
"building_name": null,
"building_number": "1017",
"street": "Oakland Ave",
"sub_street": null,
"town": "Piedmont",
"state": "CA",
"postcode": "94611",
"country": "USA",
"start_date": "2006-03-07",
"end_date": "2012-12-31"
}
]
}
Attribute | Description |
---|---|
id | string The unique identifier for the applicant |
created_at | datetime The date and time when this applicant was created |
delete_at | datetime The date and time when this applicant is scheduled to be deleted, or null if the applicant is not scheduled to be deleted |
href | string The URI of this resource |
title | string The applicant’s title. Valid values are Mr , Mrs , Miss and Ms |
first_name | string The applicant’s first name |
middle_name | string The applicant’s middle name(s) or initial |
last_name | string The applicant’s surname |
string The applicant’s email address |
|
gender | string The applicant’s gender. Valid values are male and female |
dob | date The applicant’s date of birth in yyyy-mm-dd format |
telephone | string The applicant’s landline phone number |
mobile | string The applicant’s mobile phone number |
country | string The country where this applicant will be checked. This must be a three-letter ISO code e.g. GBR or USA . If not provided the default is GBR . |
mothers_maiden_name | string The applicant’s mother’s maiden name |
previous_last_name | string The applicant’s previous surname |
nationality | string The applicant’s current nationality. This must be a three-letter ISO code e.g. GBR or USA |
country_of_birth | string The applicant’s country of birth. This must be a three-letter ISO code e.g. GBR or USA |
town_of_birth | string The applicant’s town of birth |
id_numbers | list id number A collection of identification numbers belonging to this applicant |
addresses | list address The address history of the applicant |
ID number
Attribute | Description |
---|---|
type | string Type of ID number. Valid values are ssn , social_insurance (e.g. UK National Insurance), tax_id , identity_card and driving_license |
value | string Value of ID number Note that ssn supports both the full SSN or the last four digits. If providing the full SSN the value has to be supplied with dashes in the following format: xxx-xx-xxxx |
state_code | string Two letter code of issuing state (state-issued driving licences only) |
Address
Attribute | Description |
---|---|
flat_number | string The flat number |
building_number | string The building number |
building_name | string The building name |
street | string The street of the applicant’s address. There is a 32-character limit on this field for UK addresses |
sub_street | string The sub-street |
town | string The town |
state | string The address state. US states must use the USPS abbreviation (see also ISO 3166-2:US), for example AK , CA , or TX . |
postcode | string The postcode or ZIP of the applicant’s address. For UK postcode, specify the value in the following format: SW4 6EH |
country | string The 3-character ISO country code of this address. For example, GBR is the country code for the United Kingdom |
start_date | date The date the applicant started living at this address in YYYY-MM-DD format |
end_date | date The date the applicant left this address in YYYY-MM-DD format. If current residence, leave null |
line1 | string Line 1 of the address |
line2 | string Line 2 of the address |
line3 | string Line 3 of the address |
postcode
and country
are required fields. For US addresses, the state
field is also required.
Most addresses will contain other information such as flat_number
. Please
make sure they are supplied as separate fields, and do not try and fit them
all into the street
field. Doing so is likely to affect check performance.
Alternatively, you can provide addresses in the form line1
, line2
and
line3
.
Forbidden characters
For addresses the following characters are forbidden:
!$%^*=<>
For names the following characters are forbidden:
^!#$%*=<>;{}"
Create applicant
Create an applicant
POST /v2/applicants/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"first_name": "Jane",
"last_name": "Doe",
"dob": "1990-01-31",
"country": "GBR",
"addresses": [
{
"building_number": "100",
"street": "Main Street",
"town": "London",
"postcode": "SW4 6EH",
"country": "GBR",
"start_date": "2013-01-31"
}
]
}
$ curl https://api.onfido.com/v2/applicants/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "Jane",
"last_name": "Doe",
"dob": "1990-01-31",
"country": "GBR",
"addresses": [
{
"building_number": "100",
"street": "Main Street",
"town": "London",
"postcode": "SW4 6EH",
"country": "GBR",
"start_date": "2013-01-31"
}
]
}'
applicant_details = {
title: "Ms",
first_name: "Jane",
last_name: "Doe",
dob: Date.new(1990, 1, 31),
country: "GBR",
addresses: [{
building_number: 100,
street: "Main Street",
town: "London",
postcode: "SW4 6EH",
country: "GBR",
start_date: Date.new(2013, 1, 31)
}]
}
api.applicant.create(applicant_details)
address = onfido.Address(
building_number=100,
street='Main Street',
town='London',
postcode='SW4 6EH',
country='GBR',
start_date=datetime.date(2013, 1, 31),
)
applicant_details = onfido.Applicant(
first_name='Jane',
last_name='Doe',
dob=datetime.date(1990, 1, 31),
country='GBR',
addresses=[address]
)
api.create_applicant(applicant_details)
$applicant_details = new Onfido\Model\Applicant();
$applicant_details->setFirstName('Jane');
$applicant_details->setLastName('Doe');
$applicant_details->setDob('1990-01-31');
$applicant_details->setCountry('GBR');
$address1 = new \Onfido\Model\Address();
$address1->setBuildingNumber('100');
$address1->setStreet('Main Street');
$address1->setTown('London');
$address1->setPostcode('SW4 6EH');
$address1->setCountry('GBR');
$applicant_details->setAddresses(array($address1));
$api->createApplicant($applicant_details);
Applicant applicant = new Applicant();
applicant.setFirstName("Jane");
applicant.setLastName("Doe");
applicant.setDob(LocalDate.parse("1990-01-31"));
applicant.setCountry("GBR");
Address address = new Address();
address.setBuildingNumber("100");
address.setStreet("Main Street");
address.setTown("London");
address.setPostcode("SW4 6EH");
address.setCountry("GBR");
List<Address> addresses = new ArrayList<Address>();
addresses.add(address);
applicant.setAddresses(addresses);
Applicant newApplicant = apiInstance.createApplicant(applicant);
String applicantId = newApplicant.getId();
const applicant_details = new Onfido.Applicant();
applicant_details.first_name = 'Jane';
applicant_details.last_name = 'Doe';
applicant_details.dob = new Date('1990-01-31');
(async () => {
try {
const applicant = await api.createApplicant(applicant_details);
console.log(applicant);
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/applicants/
Creates a single applicant.
Before you create any checks, you need to create an applicant.
The parameters required depend on whether you are planning to perform standard or express checks on this applicant. Standard checks require the applicant to provide their information using Onfido’s applicant form, whereas express checks are performed using data provided through the API.
When you create an applicant, some characters are forbidden.
Request body parameters
title | optional The applicant’s title. Valid values are Mr , Mrs , Miss and Ms . |
first_name | required The applicant’s forename. |
last_name | required The applicant’s surname. |
middle_name | optional The applicant’s middle name(s) or initials. |
required if creating a standard check The applicant’s email address. |
|
gender | optional The applicant’s gender. Valid values are male and female . |
dob | optional The applicant’s date of birth in yyyy-mm-dd format. |
telephone | optional The applicant’s landline phone number. |
mobile | optional The applicant’s mobile phone number. |
country | optional The country where this applicant will be checked. This must be a three-letter ISO code e.g. GBR or USA . If not provided the default is GBR . |
mothers_maiden_name | optional The applicant’s mother’s maiden name. |
previous_last_name | optional The applicant’s previous surname. |
nationality | optional The applicant’s current nationality. This must be a three-letter ISO code e.g. GBR or USA . |
country_of_birth | optional The applicant’s country of birth. This must be a three-letter ISO code e.g. GBR or USA . |
town_of_birth | optional The applicant’s town of birth. |
id_numbers | optional A collection of identification numbers belonging to this applicant |
addresses | optional The address history of the applicant |
Retrieve applicant
Retrieve an applicant
GET /v2/applicants/<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.applicant.find('<APPLICANT_ID>')
api.find_applicant('<APPLICANT_ID>')
$api->findApplicant('<APPLICANT_ID>');
String applicantId = "<APPLICANT_ID>";
Applicant result = apiInstance.findApplicant(applicantId);
(async () => {
try {
const applicant = await api.findApplicant('<APPLICANT_ID>');
console.log(applicant);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/{applicant_id}
Retrieves a single applicant.
Update applicant
Update an applicant
PUT /v2/applicants/<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"first_name": "New",
"last_name": "Name"
}
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "New",
"last_name": "Name"
}' \
-X PUT
applicant_details = {
first_name: "New",
last_name: "Name"
}
api.applicant.update('<APPLICANT_ID>', applicant_details)
applicant_details_new = onfido.Applicant()
applicant_details_new.first_name = 'New'
applicant_details_new.last_name = 'Name'
api.update_applicant('<APPLICANT_ID>', applicant_details_new)
$applicant_details = new Onfido\Model\Applicant();
$applicant_details->setFirstName('New');
$api->updateApplicant('<APPLICANT_ID>', $applicant_details);
Applicant applicant = new Applicant();
applicant.setFirstName("New");
applicant.setLastName("Name");
String applicantId = "<APPLICANT_ID>";
Applicant result = apiInstance.updateApplicant(applicantId, applicant);
const applicant_details = new Onfido.Applicant();
applicant_details.first_name = 'New';
applicant_details.last_name = 'Name';
(async () => {
try {
const applicant = await api.updateApplicant('<APPLICANT_ID>', applicant_details);
console.log(applicant);
} catch(e) {
console.log(e)
}
})();
PUT
https://api.onfido.com/v2/applicants/{applicant_id}
Updates an applicant’s information.
- Partial updates
- Addresses and ID numbers present will replace existing ones
- Same applicant validations to create applicant
Request body parameters
title | The applicant’s title. Valid values are Mr , Mrs , Miss and Ms . |
first_name | The applicant’s forename. |
last_name | The applicant’s surname. |
middle_name | The applicant’s middle name(s) or initials. |
The applicant’s email address. | |
gender | The applicant’s gender. Valid values are male and female . |
dob | The applicant’s date of birth in yyyy-mm-dd format. |
telephone | The applicant’s landline phone number. |
mobile | The applicant’s mobile phone number. |
country | The applicant’s country. This must be a three-letter ISO code e.g. GBR or USA . |
mothers_maiden_name | The applicant’s mother’s maiden name. |
previous_last_name | The applicant’s previous surname. |
nationality | The applicant’s current nationality. This must be a three-letter ISO code e.g. GBR or USA . |
country_of_birth | The applicant’s country of birth. This must be a three-letter ISO code e.g. GBR or USA . |
town_of_birth | The applicant’s town of birth. |
id_numbers | A collection of identification numbers belonging to this applicant. |
addresses | The address history of the applicant. |
Delete applicant
Delete an applicant
DELETE /v2/applicants/<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X DELETE
api.applicant.destroy('<APPLICANT_ID>')
api.destroy_applicant('<APPLICANT_ID>')
$api->destroyApplicant('<APPLICANT_ID>');
String applicantId="<APPLICANT_ID>"
apiInstance.destroyApplicant(applicantId);
(async () => {
try {
await api.destroyApplicant('<APPLICANT_ID>');
} catch(e) {
console.log(e)
}
})();
DELETE
https://api.onfido.com/v2/applicants/{applicant_id}
Deletes a single applicant.
Sending a deletion request adds the applicant and all associated documents, photos, videos, checks, reports, and analytics data to our deletion queue. A 204
response is sent back to confirm the deletion request has been received. The objects will be permanently deleted 20 days after a deletion request is made.
Restore applicant
Restore an applicant
POST /v2/applicants/<APPLICANT_ID>/restore HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/restore \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X POST
api.applicant.restore('<APPLICANT_ID>')
api.restore_applicant('<APPLICANT_ID>')
$api->restoreApplicant('<APPLICANT_ID>');
apiInstance.restoreApplicant("<APPLICANT_ID>");
(async () => {
try {
await api.restoreApplicant('<APPLICANT_ID>');
} catch(e) {
console.log(e)
}
})();
POST https://api.onfido.com/v2/applicants/{applicant_id}/restore
Restores a single applicant scheduled for deletion.
A restore request will also restore all associated documents, photos, videos, checks, reports, and analytics data. A 204
response is sent back to confirm the restore request has been received. Applicants that have been permanently deleted cannot be restored.
List applicants
Return all applicants you’ve created
GET /v2/applicants/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.applicant.all(page:1, per_page: 20)
api.list_applicants(page=1, per_page=20)
$page = 1;
$per_page = 20;
$api->listApplicants($page, $per_page);
Integer page = 1;
Integer perPage = 20;
Boolean includeDeleted = false;
ApplicantsList result = apiInstance.listApplicants(page, perPage, includeDeleted);
(async () => {
try {
const { applicants } = await api.listApplicants();
applicants.forEach(applicant_details => console.log(applicant_details));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/
Returns all applicants you’ve created, sorted by creation date in descending order.
Returns data in the form: {"applicants": [<LIST_OF_APPLICANT_OBJECTS>]}
.
Requests to this endpoint will be paginated to 20 items by default.
Query string parameters
include_deleted=true
(optional): include applicants scheduled for deletion.
per_page
(optional): set the number of results per page. Defaults to 20.
page
(optional): return specific pages. Defaults to 1.
Link header
The Link
header contains pagination information. For example:
Link: <https://api.onfido.com/v2/applicants?page=3059>; rel="last", <https://api.onfido.com/v2/applicants?page=2>; rel="next"
Possible rel
values are:
Name | Link relation (description) |
---|---|
next |
Next page of results |
last |
Last page of results |
first |
First page of results |
prev |
Previous page of results |
The custom X-Total-Count
header gives the total resource count.
You can read more about Link
headers on the IETF website.
Documents
If documents are required for your check, they can be uploaded via the upload documents endpoint. Some reports require documents (passport, visas, etc) in order to be processed. Documents belong to a single applicant, so they must be uploaded after an applicant has been created.
Document object
An example document object
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<DOCUMENT_ID>",
"created_at": "2019-02-11T13:49:20Z",
"file_name": "sample_driving_licence.png",
"file_type": "png",
"file_size": 490408,
"type": "driving_licence",
"side": "front",
"issuing_country": null,
"href": "/v2/applicants/<APPLICANT_ID>/documents/<DOCUMENT_ID>",
"download_href": "/v2/applicants/<APPLICANT_ID>/documents/<DOCUMENT_ID>/download"
}
The example given is for a driving licence document.
Attribute | Description |
---|---|
id | string The unique identifier of the document |
created_at | datetime The date and time at which the document was uploaded |
href | string The URI of this resource |
download_href | string The URI that can be used to download the document |
file_name | string The name of the uploaded file |
file_type | string The file type of the uploaded file |
file_size | integer The size of the file in bytes |
type | string The type of document. The possible values are detailed in the “Document types” section |
side | string The side of the document, if applicable. The possible values are front and back |
issuing_country | string The issuing country of the document, in 3-letter ISO code, specified when uploading it |
Document types
The following is a non-exhaustive list of document types as they’re described in the Onfido API:
Type |
---|
national_identity_card |
driving_licence |
passport |
voter_id |
work_permit |
If you’re unsure of the type of document you want to verify, you can
submit documents with type unknown
. In this case, we will attempt to
classify and recognize the document type when processing a Document report.
Upload document
Upload “passport.png”
POST /v2/applicants/<APPLICANT_ID>/documents HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: multipart/form-data
<YOUR FILE DATA (path/to/passport.png)>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/documents \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-F 'type=passport' \
-F 'file=@path/to/passport.png;type=image/png'
applicant_id = '<APPLICANT_ID>'
file = File.new('path/to/passport.png')
type = 'passport'
api.document.create(applicant_id, file: file, type: type)
applicant_id = '<APPLICANT_ID>'
sample_file = 'path/to/passport.png'
document_type = 'passport'
api.upload_document(applicant_id, document_type, sample_file)
$applicant_id = '<APPLICANT_ID>';
$type = 'passport';
$file = 'path/to/passport.png';
$side = null;
$api->uploadDocument($applicant_id, $type, $file, $side);
String type = "passport";
String side = null;
String issuing_country = null;
File file = new File("/path/to/passport.png");
String applicantId = "<APPLICANT_ID>";
Document result = apiInstance.uploadDocument(applicantId, type, file, side, issuing_country);
const fs = require('fs');
const file = fs.createReadStream('sample_driving_licence.png');
(async () => {
try {
const docData = await api.uploadDocument('<APPLICANT_ID>', 'driving_licence', file, {side: 'front', issuing_country: 'GBR'});
console.log(docData);
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/applicants/{applicant_id}/documents/
You can upload documents to this endpoint as part of multipart requests.
The valid file types are: jpg
, png
and pdf
. The file size must be between 32KB and 10MB.
Request body parameters
file | required The file to be uploaded |
type | required The type of document |
side | optional Either the front or back of the document. |
issuing_country | optional The issuing country of the document in 3-letter ISO code. |
Retrieve document
Retrieve a document for a specific applicant
POST /v2/applicants/<APPLICANT_ID>/documents/<DOCUMENT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/documents/<DOCUMENT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
document_id = '<DOCUMENT_ID>'
api.document.find(applicant_id, document_id)
applicant_id = '<APPLICANT_ID>'
document_id = '<DOCUMENT_ID>'
api.find_document(applicant_id, document_id)
$applicant_id = '<APPLICANT_ID>';
$document_id = '<DOCUMENT_ID>';
$api->findDocument($applicant_id, $document_id);
String applicantId = "<APPLICANT_ID>";
String documentId = "<DOCUMENT_ID>";
Document result = apiInstance.findDocument(applicantId, documentId);
(async () => {
try {
const doc = await api.findDocument('<APPLICANT_ID>', '<DOCUMENT_ID>');
console.log(doc);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/{applicant_id}/documents/{document_id}
Retrieves a single document.
List documents
List all documents for a specific applicant
GET /v2/applicants/<APPLICANT_ID>/documents HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/documents \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
api.document.all(applicant_id)
applicant_id = '<APPLICANT_ID>'
api.list_documents(applicant_id)
$applicant_id = '<APPLICANT_ID>';
$api->listDocuments($applicant_id);
String applicantId = "<APPLICANT_ID>";
DocumentsList result = apiInstance.listDocuments(applicantId);
(async () => {
try {
const { documents } = await api.listDocuments('<APPLICANT_ID>');
documents.forEach(document => console.log(document));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/{applicant_id}/documents/
Lists all documents belonging to an applicant.
Returns data in the form: {"documents": [<LIST_OF_DOCUMENT_OBJECTS>]}
.
Download document
Download a document associated with an applicant
GET /v2/applicant/<APPLICANT_ID>/documents/<DOCUMENT_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/documents/<DOCUMENT_ID>/download \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
document_id = '<DOCUMENT_ID>'
api.document.download(applicant_id, document_id)
GET
https://api.onfido.com/v2/applicants/{applicant_id}/documents/{document_id}/download
Downloads specific documents belong to an applicant.
The response will be the binary data representing the image.
Live photos
Live photos are images of the applicant’s face, typically taken at the same time as documents are provided. These photos are used to perform the standard
variant of the Facial Similarity check on the applicant.
Live photo object
An example live photo object
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<LIVE_PHOTO_ID>",
"created_at": "2016-05-11T11:45:26Z",
"href": "/v2/live_photos/<LIVE_PHOTO_ID>",
"download_href": "/v2/live_photos/<LIVE_PHOTO_ID>/download",
"file_name": "localfile.png",
"file_type": "png",
"file_size": 282123
}
Attribute | Description |
---|---|
id | string The unique identifier of the live photo |
created_at | datetime The date and time at which the live photo was uploaded |
href | string The URI of this resource |
download_href | string The URI that can be used to download the live photo |
file_name | string The name of the uploaded file |
file_type | string The file type of the uploaded file |
file_size | integer The size of the file in bytes |
Upload live photo
Upload “sample_photo.png”
POST /v2/live_photos/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: multipart/form-data
<YOUR FILE DATA (path/to/sample_photo.png)>
$ curl https://api.onfido.com/v2/live_photos/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-F 'applicant_id=<APPLICANT_ID>' \
-F 'file=@path/to/sample_photo.png;type=image/png'
sample_file = 'path/to/sample_photo.png'
applicant_id = '<APPLICANT_ID>'
api.upload_live_photo(applicant_id, sample_file)
$file = 'path/to/sample_photo.png';
$applicant_id = '<APPLICANT_ID>';
$api->uploadLivePhoto($applicant_id, $file)
File file = new File("/path/to/sample_photo.png");
Boolean advancedValidation = true;
/* advancedValidation is a required argument of #uploadLivePhoto */
String applicantId = "<APPLICANT_ID>";
LivePhoto result = apiInstance.uploadLivePhoto(applicantId, file, advancedValidation);
applicant_id = '<APPLICANT_ID>'
file = File.new('path/to/sample_photo.png')
api.live_photo.create(applicant_id, file: file)
const fs = require('fs');
const file = fs.createReadStream('sample_photo.png');
(async () => {
try {
const livePhotoData = await api.uploadLivePhoto('<APPLICANT_ID>', file, {'side': 'front', 'issuing_country': 'GBR'});
console.log(livePhotoData);
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/live_photos/
You can upload live photos to this endpoint as part of multipart requests.
Valid file types are jpg
, and png
. The file size must be between 32KB and 10MB. Live photos are validated at the point of upload to check that they contain exactly one face. This validation can be disabled by setting the advanced_validation
argument to false
.
Request body parameters
file | required The file to be uploaded |
applicant_id | required The applicant_id to associate the live photo to |
advanced_validation | optional A boolean which defaults to true Validates that the live photo contains exactly one face |
Retrieve live photo
Retrieve a single live photo’s object
GET /v2/live_photos/<LIVE_PHOTO_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_photos/<LIVE_PHOTO_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
live_photo_id = '<LIVE_PHOTO_ID>'
api.find_live_photo(live_photo_id)
$live_photo_id = '<LIVE_PHOTO_ID>';
$api->findLivePhoto($live_photo_id);
String livePhotoId = "<LIVE_PHOTO_ID>";
LivePhoto result = apiInstance.findLivePhoto(livePhotoId);
applicant_id = '<APPLICANT_ID>'
live_photo_id = '<LIVE_PHOTO_ID>'
api.live_photo.find(applicant_id, live_photo_id)
(async () => {
try {
const photo = await api.findLivePhoto('<LIVE_PHOTO_ID>');
console.log(photo);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/live_photos/{live_photo_id}
Retrieves a single live photo. Returns the corresponding live photo object.
List live photos
List all live photo (objects) for a specific applicant
GET /v2/live_photos/live_photos?applicant_id=<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_photos/live_photos?applicant_id=<APPLICANT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
api.list_live_photos(applicant_id)
$applicant_id = '<APPLICANT_ID>';
$api->listLivePhotos($applicant_id);
String applicantId = "<APPLICANT_ID>";
LivePhotosList result = apiInstance.listLivePhotos(applicantId);
applicant_id = '<APPLICANT_ID>'
api.live_photo.all(applicant_id)
(async () => {
try {
const { live_photos } = await api.listLivePhotos('<APPLICANT_ID>');
live_photos.forEach(photo => console.log(photo));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/live_photos/
Lists the live photos that belong to an applicant. Returns the corresponding live photo objects.
Returns data in the form: {"live_photos": [<LIST_OF_LIVE_PHOTO_OBJECTS>]}
.
Query string parameters
applicant_id
(required): the ID of the applicant whose live photos you want to list.
Download live photo
Download the data representing a photo
GET /v2/live_photos/<LIVE_PHOTO_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_photos/<LIVE_PHOTO_ID>/download HTTP/1.1 \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
live_photo_id = '<LIVE_PHOTO_ID>'
api.live_photo.download(applicant_id, live_photo_id)
GET
https://api.onfido.com/v2/live_photos/{live_photo_id}/download
Downloads a live photo.
The response is the binary data representing the image.
Live videos
Live videos are footage of the applicant’s face, recorded and uploaded by the Onfido iOS, Android or Web SDKs, at the same time as the document image is captured. These videos are used to perform the video
variant of the Facial Similarity check on the applicant.
Live video object
An example live video object
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<LIVE_VIDEO_ID>",
"created_at": "2018-05-14T16:44:53Z",
"href": "/v2/live_videos/<LIVE_VIDEO_ID>",
"download_href": "/v2/live_videos/<LIVE_VIDEO_ID>/download",
"file_name": "video_name.mp4",
"file_type": "video/mp4",
"file_size": 1431121,
"challenge": [
{
"type": "recite",
"query": [
1,
2,
3
]
},
{
"type": "movement",
"query": "turnRight"
}
]
}
During the video recording end users are asked to perform randomily generated actions, represented in challenge
. Challenges always have two parts recite
and movement
, but the order in which these happen can vary. The order of the challenges is maintained in the live video object. recite
asks the user to say three randomly generated digits, whearas movement
asks the user to look over their right or left shoulder.
Attribute | Description |
---|---|
id | string The unique identifier of the live video |
created_at | datetime The date and time at which the live video was uploaded |
href | string The URI of this resource |
download_href | string The URI that can be used to download the live video |
file_name | string The name of the uploaded file |
file_type | string The file type of the uploaded file |
file_size | integer The size of the file in bytes |
challenge | hash Challenge the end user was asked to perform during the video recording |
Retrieve live video
Retrieve a single live video’s object
GET /v2/live_videos/<LIVE_VIDEO_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_videos/<LIVE_VIDEO_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
live_video_id = '<LIVE_VIDEO_ID>'
api.find_live_video(live_video_id)
$live_video_id = '<LIVE_VIDEO_ID>';
$api->findLiveVideo($live_video_id);
String liveVideoId = "<LIVE_VIDEO_ID>";
LiveVideo result = apiInstance.findLiveVideo(liveVideoId);
(async () => {
try {
const video = await api.findLiveVideo('<LIVE_VIDEO_ID>');
console.log(video);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/live_videos/{live_video_id}
Retrieves a single live video. This will return the corresponding live video object.
List live videos
List all live videos for a specific applicant
GET /v2/live_videos?applicant_id=<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_videos?applicant_id=<APPLICANT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'
api.list_live_videos(applicant_id)
$applicant_id = '<APPLICANT_ID>';
$api->listLiveVideos($applicant_id);
String applicantId = "<APPLICANT_ID>";
LiveVideosList result = apiInstance.listLiveVideos(applicantId);
(async () => {
try {
const { live_videos } = await api.listLiveVideos('<APPLICANT_ID>');
live_videos.forEach(video => console.log(video));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/live_videos/
Lists all the live videos that belong to an applicant.
Returns data in the form: {"live_videos": [<LIST_OF_LIVE_VIDEO_OBJECTS>]}
.
Query string parameters
applicant_id
(required): the ID of the applicant whose live videos you want to list.
Download live video
Download the data representing a live video
GET /v2/live_videos/<LIVE_VIDEO_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_videos/<LIVE_VIDEO_ID>/download \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
GET
https://api.onfido.com/v2/live_videos/{live_video_id}/download
Downloads a live video.
The response is the binary data representing the video.
Download live video frame
Download the data representing a live video frame
GET /v2/live_videos/<LIVE_VIDEO_ID>/frame HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/live_videos/<LIVE_VIDEO_ID>/frame \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
GET
https://api.onfido.com/v2/live_videos/{live_video_id}/frame
Instead of the whole video, a single frame can be downloaded using this endpoint.
The response is the binary data representing the frame.
Unsuccessful frame extraction
Unsuccessful frame extraction response: failure
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"type": "frame_extraction_failed",
"message": "<Reason>"
}
}
Unsuccessful frame extraction response: temporarily unavailable
HTTP/1.1 503 Service Unavailable
Content-Type: application/json
{
"error": {
"type": "frame_extraction_unavailable",
"message": "Frame extraction is temporarily unavailable"
}
}
If a frame cannot be extracted from the live video, a frame_extraction_failed
response will be returned. On the other hand, if the extraction feature is temporarily unavailable, a frame_extraction_unavailable
response will be returned instead.
Checks
Checks are performed on an applicant.
A check consists of one or more reports. You can also read about what applicant information is required for each report in the relevant section under “Report Types”. For example, for Document Reports.
Depending on the type of check you wish to perform, different information will be required when you create an applicant.
If your system already has the information you require, you can use the default option for checks. The steps for this are:
An applicant object is created.
If required: documents, photos and videos are uploaded to the applicant object.
A check is constructed consisting of one or more reports.
After a check is created, it will start processing immediately.
Standard checks
If you require Onfido to collect information from an applicant, you may wish to use standard checks.
Standard checks require applicants to enter their information in a form, which is sent to applicants via email.
A standard check will only start processing when the applicant has submitted the form.
Check object
An example check object
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2014-05-23T13:50:33Z",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"type": "express",
"status": "complete",
"result": "clear",
"redirect_uri": "https://somewhere.else",
"results_uri": "<RESULTS_URI>",
"download_uri": "<DOWNLOAD_URI>",
"reports": [
"<REPORT_ID>",
"<REPORT_ID>"
],
"tags": [
"My tag",
"Another tag"
]
}
The check object is used to track the type and status of a check, and contains the nested resource reports.
Attribute | Description |
---|---|
id | string The unique identifier for the check. |
created_at | datetime The date and time at which the check was initiated. |
href | string The API endpoint to retrieve the check. |
type | string The type of check: standard or express. |
status | string The current state of the check in the checking process. |
tags | list [string] A list of tags associated with this check. |
result | string The overall result of the check, based on the results of the reports used in the check. |
download_uri | string A link to a PDF output of the check results. Append .pdf to get the pdf file. |
form_uri | string A link to the applicant form, if the check is of type standard |
redirect_uri | string For standard checks, redirect to this URI when the applicant has submitted their data. |
results_uri | string A link to the corresponding results page on the Onfido Dashboard |
reports | list reports expandable The list of report objects associated with the check. |
Check status
Status | Description |
---|---|
in_progress | We are currently processing the check. |
awaiting_applicant | Applicant has not yet submitted the applicant form, either because they have not started filling the form out or because they have started but have not finished. |
complete | All reports for the applicant have been completed or withdrawn. |
withdrawn | Check has been withdrawn. |
paused | Check is paused until you, i.e. the client, switch it on manually. Special case used by clients who wants to collect data and run the checks when they want and not immediately. |
reopened | Insufficient/inconsistent information is provided by the applicant, and the report has been bounced back for further information. |
Check results
The value of the check is derived from the results of the individual reports that it contains:
Check result | |
---|---|
clear | If all the reports contained in the check have clear as their results. |
consider | If some of the reports contained in the check have either consider or unidentified as their results. |
Create check
Create a check (Document report, Facial Similarity report)
POST /v2/applicants/<APPLICANT_ID>/checks HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"type": "express",
"reports": [
{
"name": "document"
},
{
"name": "facial_similarity",
"variant": "standard"
}
]
}
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/checks \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"type": "express",
"reports": [
{
"name": "document"
},
{
"name": "facial_similarity",
"variant": "standard"
}
]
}'
reports = [{name: 'document'}, {name: 'facial_similarity', variant: 'standard'}]
check = api.check.create(applicant_id, type: 'express', reports: reports)
applicant_id = '<APPLICANT_ID>'
check_data = onfido.Check(type='express')
document_report = onfido.Report(name='document')
facial_similarity_report = onfido.Report(name='facial_similarity', variant='standard')
check_data.reports = [document_report, facial_similarity_report]
api.create_check(applicant_id, check_data)
$check_data = new Onfido\Model\Check();
$check_data->setType('express');
$document_report = new Onfido\Model\Report();
$document_report->setName('document');
$facial_similarity_report = new Onfido\Model\Report();
$facial_similarity_report->setName('facial_similarity');
$facial_similarity_report->setVariant('standard');
$check_data->setReports(array($document_report, $facial_similarity_report));
$check = $api->createCheck($applicant_id, $check_data);
Check check = new Check();
check.setType("express");
check.setAsynchronous(true);
Report report_one = new Report();
report_one.setName("document");
Report report_two = new Report();
report_two.setName("facial_similarity");
report_two.setVariant("standard");
List<Report> reports = new ArrayList<Report>();
reports.add(report_one);
reports.add(report_two);
check.setReports(reports);
String applicantId = "<APPLICANT_ID>";
Check newCheck = apiInstance.createCheck(applicantId, check);
const check = new Onfido.Check();
check.type = 'express';
const document_report = new Onfido.Report();
document_report.name = 'document';
const facial_similarity_report = new Onfido.Report();
facial_similarity_report.name = 'facial_similarity';
check.reports = [document_report, facial_similarity_report];
(async () => {
try {
const checkData = await api.createCheck('<APPLICANT_ID>', check);
console.log(checkData);
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/applicants/{applicant_id}/checks/
Initiates a check for an applicant.
Certain reports are generated instantly and their results are returned in the response, while other reports take longer to be processed. You will need to set up a webhook to listen for the results of non-instant reports.
Having created the first check, you are allowed to create further checks for the same applicant, as long as the previous check is not still ongoing (i.e. check has been completed, withdrawn or cancelled). You will receive an error message if you try to create a check for an applicant with an ongoing check. Applicant details can be updated between check creations.
Request body parameters
type | requiredstandard or express . See “Checks”. |
reports | required if report_type_grpups not providedArray of reports being requested for this check. |
report_type_groups | required if reports not providedArray containing ids of the report type groups** being requested for |
redirect_uri | optional For standard checks, redirect to this URI when the applicant has submitted their data. |
tags | optional Array of tags being assigned to this check. |
suppress_form_emails | optional For standard checks, applicant form will not be automatically sent if this is set to true . You can manually send the form at any time after the check has been created, using the link found in the form_uri attribute of the check object.Defaults to false (i.e., form will be sent automatically by default) |
async asynchronous (alias) |
recommended If this is set to true , checks will be queued for processing. You can configure webhooks to notify you when the report is complete.Defaults to false Note: async and asynchronous cannot be provided together. |
charge_applicant_for_check | optional For standard checks, applicants will be presented with a mandatory payment screen before they can submit the applicant form, if this is set to true . In this case, your account will not be charged. Defaults to false |
consider | optional Array of names of the reports to return consider as their results. This is a sandbox testing specific argument for testing multiple-report scenarios. |
Request body parameters (report)
name | required The name of the report type. You can read about the different report types. |
variant | optional The name of the report type variant, if required. |
options | optional Array of report options hashes |
documents | optional Array of report documents hashes. This argument allows you to specify which document to use as part of the Document report. If unspecified, the most recently uploaded document (or documents for a two-sided ID document) will be used. |
Request body parameters (report options)
name | required The option to be applied (used by Watchlist ‘full’ reports). |
Request body parameters (report documents)
id | required ID of uploaded document to use. |
Retrieve check
Retrieve a single check
POST /v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID> \
-H 'Authorization: Token token=YOUR_API_TOKEN'
api.check.find('<APPLICANT_ID>', '<CHECK_ID>')
applicant_id = '<APPLICANT_ID>'
check_id = '<CHECK_ID>'
check = api.find_check(applicant_id, check_id)
$applicant_id = '<APPLICANT_ID>';
$check_id = '<CHECK_ID>';
$api->findCheck($applicant_id, $check_id);
String applicantId = "<APPLICANT_ID>";
String checkId = "<CHECK_ID>";
CheckWithReportIds result = apiInstance.findCheck(applicantId, checkId);
(async () => {
try {
const check = await api.findCheck('<APPLICANT_ID>', '<CHECK_ID>');
console.log(check);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/{applicant_id}/checks/{check_id}
Retrieves a single check.
List checks
List all checks associated with an applicant
GET /v2/applicants/<APPLICANT_ID>/checks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/applicants/<APPLICANT_ID>/checks/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.check.all('<APPLICANT_ID>')
applicant_id = '<APPLICANT_ID>'
checks = api.list_checks(applicant_id)
$applicant_id = '<APPLICANT_ID>';
$api->listChecks($applicant_id);
Integer page = 1;
Integer perPage = 20;
Boolean includeDeleted = false;
String applicantId = "<APPLICANT_ID>";
ChecksList result = apiInstance.listChecks(applicantId, page, perPage);
(async () => {
try {
const { checks } = await api.listChecks('<APPLICANT_ID>');
checks.forEach(check => console.log(check));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/applicants/{applicant_id}/checks/
Returns all checks for an applicant.
Returns data in the form: {"checks": [<LIST_OF_CHECK_OBJECTS>]}
.
You can expand the reports
value to return a list of the report objects in the response instead of the default list of report IDs.
Query string parameters
expand=reports
(Optional)
Resume check
Resume a paused check
GET /v2/checks/<CHECK_ID>/resume HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/checks/<CHECK_ID>/resume
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X POST
check_id = '<CHECK_ID>'
api.resume_check(check_id)
$check_id = '<CHECK_ID>';
$api->resumeCheck($check_id);
check_id = '<CHECK_ID>'
api.check.resume(check_id)
String checkId = "<CHECK_ID>";
apiInstance.resumeCheck(checkId);
(async () => {
try {
await api.resumeCheck('<CHECK_ID>');
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/checks/{check_id}/resume
Resumes a paused check.
A check is paused if all the reports that it contains are in the paused state. A 204 No Content
response is sent back to confirm the request has been received.
When a standard check gets resumed, all its reports are going to start processing immediately if the applicant has already submitted the form. The check status will automatically change to in_progress. Otherwise, the check will remain as awaiting_applicant and the reports are only going to start processing after the applicant submits the form.
Reports
Report object
An example report object (Identity report, awaiting data)
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<REPORT_ID>",
"name": "identity",
"created_at": "2014-05-23T13:50:33Z",
"status": "awaiting_data",
"result": null,
"sub_result": null,
"variant": null,
"options": {},
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"breakdown": {},
"properties": {},
"documents": []
}
The report object contains the state and relevant details of the particular report. The structure of the object is listed at right, under the shell
tab.
The breakdown
hash contains the details of the particular report and differs for each report type. The format of the breakdown and properties for each report type is listed in the “Report types” section.
Attribute | Description |
---|---|
id | string The unique identifier for the report |
created_at | datetime The date and time at which the report was first initiated |
name | string Report type string identifier. See “Report types” |
href | string The API endpoint to retrieve the report |
status | string The current state of the report in the checking process |
result | string The result of the report |
sub_result | string The sub_result of the report. It gives a more detailed result for Document reports only, and will be null otherwise |
variant | string Report variant string identifier. Some reports have sub-types, which are identified by this field. These are detailed in the “Report types” section |
options | array Report options usable with Watchlist ‘full’ reports |
breakdown | hash The details of the report. This is specific to each type of report |
properties | hash The properties associated with the report, if any |
documents | array The document ids that were processed. Only for Document reports |
Report status
Status | Description |
---|---|
awaiting_data | Onfido has made a request to one of its data providers and we are waiting on their reply. |
awaiting_approval | Report is going through manual review. |
complete | Report is done. |
withdrawn | Report has been cancelled. |
paused | Report is paused until you, i.e. the client, switch it on manually. Special case used by clients who wants to collect data and run the reports when they want and not immediately. |
Report results
The result
field indicates the overall result of a report. The possible values of this field are:
Report result | |
---|---|
clear | If all underlying verifications pass, the overall result will be clear |
consider | If the report has returned information that needs to be evaluated, the overall result will be consider . |
unidentified | Identity report (standard variant only) - this is returned if the applicant fails an identity check. This indicates there is no identity match for this applicant on any of the databases searched. |
Sub results
The sub_result
field indicates a more detailed result for Document reports.
Report sub_result | |
---|---|
clear | If all underlying verifications pass, the overall sub result will be clear |
rejected | If the report has returned information where the check cannot be processed further (poor quality image or an unsupported document). |
suspected | If the document that is analysed is suspected to be fraudulent. |
caution | If any other underlying verifications fail but they don’t necessarily point to a fraudulent document (such as the name provided by the applicant doesn’t match the one on the document) |
Retrieve report
Retrieve a single report
GET /v2/checks/<CHECK_ID>/reports/<REPORT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/checks/<CHECK_ID>/reports/<REPORT_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.report.find('<CHECK_ID>', '<REPORT_ID>')
check_id = '<CHECK_ID>'
report_id = '<REPORT_ID>'
report = api.find_report(check_id, report_id)
$check_id = '<CHECK_ID>';
$report_id = '<REPORT_ID>';
$api->findReport($check_id, $report_id);
String reportId = "<REPORT_ID>";
String checkId = "<CHECK_ID>";
Report result = apiInstance.findReport(checkId, reportId);
(async () => {
try {
const report = await api.findReport('<CHECK_ID>', '<REPORT_ID>');
console.log(report);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/checks/{check_id}/reports/{report_id}
Retrieves a single report.
List reports
List all reports associated with a check
GET /v2/checks/<CHECK_ID>/reports/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/checks/<CHECK_ID>/reports/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.report.all('<CHECK_ID>')
check_id = '<CHECK_ID>'
api.list_reports(check_id)
$check_id = '<CHECK_ID>';
$api->listReports($check_id);
String checkId = "<CHECK_ID>";
ReportsList result = apiInstance.listReports(checkId);
(async () => {
try {
const { reports } = await api.listReports('<CHECK_ID>');
reports.forEach(report => console.log(report));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/checks/{check_id}/reports/
Lists all reports belonging to a particular check.
Returns data in the form: {"reports": [<LIST_OF_REPORT_OBJECTS>]}
.
Resume report
Resume a single paused report
POST /v2/checks/<CHECK_ID>/reports/<REPORT_ID>/resume HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/checks/<CHECK_ID>/reports/<REPORT_ID>/resume \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X POST
check_id = '<CHECK_ID>'
report_id = '<REPORT_ID>'
api.resume_report(check_id, report_id)
$check_id = '<CHECK_ID>';
$report_id = '<REPORT_ID>';
$api->resumeReport($check_id, $report_id);
String checkId = "<CHECK_ID>";
String reportId = "<REPORT_ID>";
apiInstance.resumeReport(checkId, reportId);
report_id = '<REPORT_ID>'
check_id = '<CHECK_ID>'
api.report.resume(check_id, report_id)
(async () => {
try {
await api.resumeReport('<REPORT_ID>');
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/checks/{check_id}/reports/{report_id}/resume
Resumes a single paused report.
A 204 No Content
response is sent back to confirm the request has been received.
When an individual report gets resumed in a standard check, it will start processing immediately if the applicant has already submitted the form. The report status will automatically change from paused to awaiting_data. Otherwise, the status change will happen but the report processing will only start after the applicant submits the form.
Note that you can resume all reports within a check by resuming the check itself.
Cancel report
Cancel a single paused report
POST /v2/checks/<CHECK_ID>/reports/<REPORT_ID>/cancel HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/checks/<CHECK_ID>/reports/<REPORT_ID>/cancel \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X POST
check_id = '<CHECK_ID>'
report_id = '<REPORT_ID>'
api.cancel_report(check_id, report_id)
$check_id ='<CHECK_ID>';
$report_id = '<REPORT_ID>';
$api->cancelReport($check_id, $report_id);
String checkId = "<CHECK_ID>";
String reportId = "<REPORT_ID>";
apiInstance.cancelReport(checkId, reportId);
report_id = '<REPORT_ID>'
check_id = '<CHECK_ID>'
api.report.cancel(check_id, report_id)
(async () => {
try {
await api.cancelReport('<CHECK_ID>', '<REPORT_ID>');
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/checks/{check_id}/reports/{report_id}/cancel
Cancels single paused reports. If successful, returns a 204 No Content
response.
When a report gets cancelled in a standard check, its status will change from paused to cancelled and the report will never get processed.
Document report
An example check object with a Document report
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-07-29T15:14:29Z",
"status": "complete",
"redirect_uri": null,
"type": "express",
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"download_uri": "<DOWNLOAD_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-07-29T15:14:30Z",
"documents": [
{
"id": "<DOCUMENT_ID>"
}
],
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "document",
"properties": {
"nationality": "",
"last_name": "Smith",
"issuing_country": "GBR",
"gender": "",
"first_name": "John",
"document_type": "passport",
"document_numbers": [
{
"value": "9999999999",
"type": "passport"
}
],
"date_of_expiry": "1900-01-01",
"date_of_birth": "1900-01-01"
},
"result": "clear",
"status": "complete",
"sub_result": "clear",
"variant": "standard",
"breakdown": {
"age_validation": {
"result": "clear",
"breakdown": {
"minimum_accepted_age": {
"result": "clear",
"properties": {}
}
}
},
"compromised_document": {
"result": "clear"
},
"data_comparison": {
"result": "clear",
"breakdown": {
"issuing_country": {
"result": "clear",
"properties": {}
},
"gender": {
"result": "clear",
"properties": {}
},
"date_of_expiry": {
"result": "clear",
"properties": {}
},
"last_name": {
"result": "clear",
"properties": {}
},
"document_type": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"first_name": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
}
}
},
"data_consistency": {
"result": "clear",
"breakdown": {
"date_of_expiry": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"issuing_country": {
"result": "clear",
"properties": {}
},
"document_type": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
},
"gender": {
"result": "clear",
"properties": {}
},
"first_name": {
"result": "clear",
"properties": {}
},
"last_name": {
"result": "clear",
"properties": {}
},
"nationality": {
"result": "clear",
"properties": {}
}
}
},
"data_validation": {
"result": "clear",
"breakdown": {
"gender": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"document_expiration": {
"result": "clear",
"properties": {}
},
"expiry_date": {
"result": "clear",
"properties": {}
},
"mrz": {
"result": "clear",
"properties": {}
}
}
},
"visual_authenticity": {
"result": "clear",
"breakdown": {
"fonts": {
"result": "clear",
"properties": {}
},
"picture_face_integrity": {
"result": "clear",
"properties": {}
},
"template": {
"result": "clear",
"properties": {}
},
"security_features": {
"result": "clear",
"properties": {}
},
"original_document_present": {
"result": "clear",
"properties": {
"photo_of_screen": "consider"
}
},
"digital_tampering": {
"result": "clear",
"properties": {}
},
"other": {
"result": "clear",
"properties": {}
},
"face_detection": {
"result": "clear",
"properties": {}
}
}
},
"image_integrity": {
"result": "clear",
"breakdown": {
"image_quality": {
"result": "clear",
"properties": {
"glare_on_photo": "consider",
"blurred_photo": "consider"
}
},
"conclusive_document_quality": {
"result": "clear",
"properties": {
"obscured_security_features": "consider"
}
},
"supported_document": {
"result": "clear",
"properties": {}
},
"colour_picture": {
"result": "clear",
"properties": {}
}
}
},
"police_record": {
"result": "clear"
}
}
}
],
"paused": false,
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Document report | document |
- | yes | yes |
The Document report is composed of data integrity, visual authenticity and police record checks. It checks the internal and external consistency of the most recent identity document provided by the applicant to identify potential discrepancies.
In addition, any data extracted from the document through OCR is returned in the properties attribute.
The Document report combines software and an expert team to maximise fraud detection. The majority of documents will be processed instantly. However, when document analysis falls back to expert review, the report status will be delivered asynchronously via webhook notifications.
Expert review is required when we encounter images that use sophisticated counterfeiting techniques, or the image is of poor quality (blurred, low resolution, obscured, cropped, or held at an unreadable angle).
Required applicant data
For Document reports, first_name
and last_name
must be provided but can be
dummy values if you don’t know an applicant’s name.
Results
The result
field indicates the overall report result. Possible values for
Document reports are clear
and consider
:
Report result | |
---|---|
clear | If all underlying verifications pass, the overall result will be clear |
consider | If the report has returned information that needs to be evaluated, the overall result will be consider . |
Sub-results
The sub_result
field indicates a more detailed result. sub_result
is only
applicable to Document reports. Possible values are as follows:
Sub-result | |
---|---|
clear | If all underlying verifications pass, the overall sub result will be clear . There are no indications the document is fraudulent. |
caution | We can’t successfully complete all verifications, but this doesn’t necessarily point to a suspected document (for example, expired document). |
suspected | Document shows signs of suspect fraud. |
rejected | We can’t process the document image, or the document isn’t supported by Onfido for processing. Another reason is if the age of the applicant is too low (the standard threshold is 16 years old but you can write to your Onfido contact to have this changed). |
Breakdowns
Breakdowns can have the values clear
and consider
.
A breakdown will have the result consider
when at least one sub-breakdown
contains a consider
or unidentified
result. For example, a consider
result
for the mrz
sub-breakdown will produce a consider
result for the
data_validation
breakdown. This will then also set the report sub_result
value to suspected
.
Some breakdowns contain sub-breakdowns. For example, the image_integrity
breakdown comprises the sub-breakdowns supported_document
, image_quality
,
colour_picture
and conclusive_document_quality
.
The possible values for sub-breakdowns are clear
, consider
, null
and
unidentified
.
Breakdown order priority
Breakdown sub-results have the following order of priority:
rejected
->suspected
->caution
->clear
For example, a caution
sub-result will only ever be asserted when the following
conditions are met:
- no individual breakdown has caused a
rejected
orsuspected
sub-result - a breakdown which maps to a
caution
sub-result has been flagged
Breakdown descriptions and logic
police_record
:Asserts whether the document has been identified as lost, stolen or otherwise compromised.
compromised_document
:Asserts whether the image of the document has been found in our internal database of compromised documents.
data_consistency
:Asserts whether data represented in multiple places on the document is consistent. For example, between MRZ lines and OCR extracted text on passports. Uses the following sub-breakdowns:
document_type
gender
date_of_expiry
nationality
issuing_country
document_numbers
date_of_birth
last_name
first_name
data_validation
:Asserts whether algorithmically validatable elements are correct. Uses the following sub-breakdowns:
document_expiration
gender
document_numbers
expiry_date
date_of_birth
mrz
visual_authenticity
:Asserts whether visual (non-textual) elements are correct given the type. Uses the following sub-breakdowns:
original_document_present
:The document was not present when the photo was taken. For example, a photo of a photo of a document or a photo of a computer screen. Configurable to map to
caution
instead ofsuspected
.digital_tampering
:Indication of digital tampering in the image (for example, name altered).
picture_face_integrity
:The pictures of the person identified on the document show signs of tampering or alteration. In most cases this will focus on the primary picture yet it may also apply to the secondary and tertiary pictures when documents contain them.
security_features
:Security features expected on the document are missing or wrong.
template
:The document doesn’t match the expected template for the document type and country it is from.
fonts
:Fonts in the document don’t match the expected ones.
face_detection
:No face was detected on the document.
other
:This sub-breakdown is returned for backward compatibility reasons. Its value will be consider when at least one of the other breakdowns is consider, and clear when all the other breakdowns are clear.
image_integrity
:Asserts whether the document was of sufficient quality to verify. Uses the following sub-breakdowns:
colour_picture
:Asserts whether the image was a colour one. A black and white picture will map to a
caution
Document report sub-result. Configurable to map torejected
.conclusive_document_quality
:A result of
clear
for this sub-breakdown will assert if the document was of enough quality to be able to perform a fraud inspection. A result ofconsider
will mean that even if sub breakdowns ofvisual_authenticity
fail, we cannot positively say the document is fraudulent or not (in cases such as parts of the document are not visible).supported_document
:Asserts whether the submitted document is supported. Takes value of
clear
orunidentified
.image_quality
:Asserts whether the quality of the image was sufficient for processing.
data_comparison
:Asserts whether data on the document is consistent with data provided when creating an applicant through the API. The Onfido name comparison system uses a Levenshtein-like fuzzy matching for these fields. The purpose of this inexact matching is to avoid unnecessary failures if the names are mathematically close enough. This breakdown can switched off if needed. Uses the following sub-breakdowns:
gender
date_of_birth
first_name
last_name
age_validation
:Asserts whether the age calculated from the document’s date of birth data point is greater than or equal the minimum accepted age set at account level. The standard threshold is 16 years old but you can write to your Onfido contact to have this changed.
Breakdown Properties
We will return a reason whenever a report flags for one of the following breakdowns:
Image Integrity - Image Quality
Image Integrity - Conclusive Document Quality
Visual Authenticity - Original Document Present
This works by returning the contributing reason and corresponding fail result (a Consider
result) in the breakdown properties.
There can be more than one reason per breakdown, as they aren’t mutually exclusive.
All other signals and potential reasons will be omitted.
Image Quality reasons:
dark_photo
- When an image of the document is too dark to be able to see data points
glare_on_photo
- When there is light reflecting on the document causing glare to obstruct data points
blurred_photo
- When data points are blurred and no reference can be made elsewhere in the document or if the data points are too blurry and ‘they could be something else’ (e.g. “I” could be “1”, “B” could be “8”)
covered_photo
- When data points have been covered either by the applicant or by another object such as a sticker
other_photo_issue
- Any other reason not listed, such as when holograms are obscuring data points
damaged_document
- When a document is damaged and we are unable to make out data points
incorrect_side
- When the incorrect side of a document has been uploaded, and we have not received the front
cut_off_document
- When data points are not included in the image due to the document being cut off (i.e. out of the frame of the image)
no_document_in_image
- If no document has been uploaded or there is a blank image
two_documents_uploaded
- When two different identity documents are submitted in the same check
Conclusive Document Quality reasons:
obscured_data_points
- This refers to whenever any personal data points that aren’t meant to be extracted are obscured, e.g.: Address, Place of Birth, Nationality, Signature, Personal Number, Issue Date (when not extracted), Expiry date (when not extracted)
obscured_security_features
- This refers to whenever a critical security feature is obscured. This can also refer to when the holder’s wet signature, necessary for the document to be valid, is not present
abnormal_document_features
- One of three reasons: (1) OCR Assisted Scans (i.e. when you’re able to move the mouse and highlight part of text), (2) Severely Washed out Background, (3) Overlapping Text
watermarks_digital_text_overlay
- Any digital text or electronic watermarks on the document
corner_removed
- If the corner has been physically cut off. This can be found on some documents that are no longer valid
punctured_document
- A punched hole is present. This can be found on DLs that are no longer valid, for example
missing_back
- When the back of a document is needed for processing (e.g. for key data points to extract, or to perform Consistency), but is not available (e.g. if the same front was uploaded twice)
Original Document Present reasons:
photo_of_screen
- When we can see that the applicant’s document is on a physical screen or device, e.g. when the device is visible, software applications are seen, a computer cursor is present, or the pixels on the image appearing to have a different texture than expected
screenshot
- When the applicant has used their mobile phone, tablet, or computer to take a photo within the device, e.g. when software applications are seen, the time and mobile provider are visible, or any digitally added component that wouldn’t be seen on a physical document, such as an upload icon
document_on_printed_paper
- when the applicant has previously captured an image of the document, printed it out, and has now taken a photo of this print out to upload, e.g. when the edges of the paper are visible, when there are fold creases on the paper, or the document’s edges blending into the background and appearing flat
text_around_document
- When there is written or digital text in the same image as the document, but does not interact with the document
Breakdowns which map to caution
image_integrity
*
colour_picture
(configurable to map to rejected)*
conclusive_document_quality
data_comparison
:gender
date_of_birth
first_name
last_name
data_validation
:document_expiration
Breakdowns which map to suspected
data_validation
:date_of_birth
expiry_date
mrz
gender
document_numbers
visual_authenticity
:original_document_present
(configurable to map tocaution
)digital_tampering
picture_face_integrity
security_features
template
fonts
face_detection
data_consistency
:date_of_expiry
document_type
gender
date_of_birth
nationality
issuing_country
document_numbers
first_name
last_name
compromised_document
: Document has been found in our databasepolice_record
Document has been recorded as lost, stolen or compromised
Breakdowns which map to rejected
image_integrity
:image_quality
supported_document
age_comparison
:minimum_accepted_age
Example client actions
clear
sub-result
Potential contributing breakdown | Potential client action |
---|---|
All relevant breakdowns clear | Onboard applicant |
The Document report employs a variety of techniques designed to identify fraudulent documents. We support this with expert manual processing to ensure a check is subject to a thorough analysis. If a document is deemed to have passed across these vectors, it is considered a “clear”.
If a document triggers flags based on a number of factors (including image quality, or potential fraudulent activity), our manual team will also check the document and apply their knowledge to supplement the machine.
caution
sub-result
Potential contributing breakdown | Potential client action(s) |
---|---|
data_validation : document_expiration |
a. Ignore b. Refer to manual team for review c. Request an additional document |
Onfido’s document_expiration
breakdown validates the expiry date extracted
from a document and checks its validity, flagging if a document’s expiry date
has passed.
Potential contributing breakdown | Potential client action(s) |
---|---|
image_integrity : conclusive_document_quality |
a. Ignore b. Refer to manual team for review c. Request an additional document |
This breakdown is applied by our expert manual review team when both product and human analysis fail to yield a concrete result either way.
Our manual team will apply this breakdown for documents they receive which are unclassifiable as fraudulent or genuine.
Potential contributing breakdown | Potential client action(s) |
---|---|
image_integrity : colour_picture (can be configured to rejected ) |
a. Ignore b. Refer to manual team for review c. Request an additional document |
The Onfido engine deploys color reading algorithms designed to detect whether or not a black and white image has been submitted, flagging these.
suspected
sub-result
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : original_document_present (can be configured to caution ) |
a. Ignore b. Refer to manual team for review c. Request an additional document |
Onfido deploys a number of texture analysis algorithms to detect whether or not an image contains any of the following:
- screenshots
- pictures of pictures
- printouts
Original document scanning presents a difficult challenge that in our experience is best solved via the combination of tech and human expertise. Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : picture_face_integrity |
a. Block b. Refer to manual team for review |
Onfido deploys a number of algorithms designed to analyse whether the picture in a document image may be a physical insertion or otherwise digitally tampered.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : fonts |
a. Block b. Refer to manual team for review |
Our machine learning models are constantly refining their ability to recognise, categorise and distinguish between fraudulent fonts and genuine travel document font types such as OCRB.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engine’s decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : template |
a. Block b. Refer to manual team for review |
The template breakdown is triggered by algorithms trained to recognise genuine templates and formats of documents, and is supplemented by our manual team’s expert knowledge.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : digital_tampering |
a. Block b. Refer to manual team for review |
We analyse a document to recognise if the document is suspected of being created digitally or digitally tampered as opposed to being created physically or tampered in a physical manor.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
visual_authenticity : security_features |
a. Block b. Refer to manual team for review |
The Onfido engine is trained to pick out a number of distinct security features in each document, and is supplemented by the work of our manual team of experts.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
data_validation : mrz , date_of_birth , expiry_date , mrz , gender , document_numbers |
a. Block b. Refer to manual team for review |
The Onfido engine asserts whether algorithmically-validatable elements are correct. For example, MRZ lines and document numbers.
Should our algorithms fail to produce a result beyond a certain degree of certainty, documents will be referred to manual analysts to supplement the engines decision.
Potential contributing breakdown | Potential client action(s) |
---|---|
data_validation : mrz , date_of_birth , expiry_date , mrz , gender , document_numbers |
a. Block b. Refer to manual team for review |
rejected
sub-result
Potential contributing breakdown | Potential client action(s) |
---|---|
supported_document |
Verify that the document is supported |
When this is unidentified
, the result of the image_integrity
breakdown
will be consider
. This will trigger a rejected
sub-result.
Potential contributing breakdown | Potential client action(s) |
---|---|
image_quality |
Request an additional image of the same document |
Any document which is deemed to be “unprocessable” is likely to have key data points which cannot be seen, are cropped, or are in some way obscured. Such documents are rejected for poor image quality.
Potential contributing breakdown | Potential client action(s) |
---|---|
supported_document |
Request a different image |
You can review the full list of documents Onfido supports.
Potential contributing breakdown | Potential client action(s) |
---|---|
age_validation |
Block |
Applicant age calculated from document date_of_birth
data point.
Facial Similarity report
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Facial Similarity report | facial_similarity |
standard video |
yes* no |
yes yes |
The Facial Similarity report will compare the most recent live photo or live video provided by the applicant to the face on the most recent identity document provided, where the attribute side
is front. If none exists the latest document will be used.
When side
is not specified, it will take a default value of front. It is recommended that all documents contain the side
attribute, as this minimises the cases where the back of the document is used for comparison and thus failed as no face is detected.
There are 2 different variants of Facial Similarity report: Standard which uses live photos and Video which uses live videos.
Required applicant data
For all Facial Similarity report variants, first_name
and last_name
must be provided but can be dummy values if you don’t know an applicant’s name.
Facial Similarity Standard
An example check object with a Facial Similarity Standard report
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-09-24T14:11:05Z",
"status": "complete",
"redirect_uri": null,
"result": "consider",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-09-24T14:11:05Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "facial_similarity",
"properties": {
"score": 0.1512
},
"result": "consider",
"status": "complete",
"sub_result": null,
"variant": "standard",
"breakdown": {
"face_comparison": {
"result": "consider"
},
"image_integrity": {
"result": "clear",
"breakdown": {
"face_detected": {
"result": "clear",
"properties": {}
},
"source_integrity": {
"result": "clear",
"properties": {}
}
}
},
"visual_authenticity": {
"result": "consider"
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
The Facial Similarity Standard report uses live photos. The photo needs to be a live photo taken at the time of check submission, so that it can assess whether the holder of the identity document is the same person as the one on the document.
Facial Similarity Standard Object
The following table describes the unique fields returned in the Onfido API (v2) for the Facial Similarity Standard report:
Attribute | Format | Possible values |
---|---|---|
result |
String or null |
"clear" , "consider" , null |
image_integrity |
String or null |
"clear" , "consider" , null |
(sub-breakdown) face_detected |
String or null |
"clear" , "consider" , null |
(sub-breakdown) source_integrity |
String or null |
"clear" , "consider" , null |
face_comparison |
String or null |
"clear" , "consider" , null |
visual_authenticity |
String or null |
"clear" , "consider" , null |
properties |
||
score |
Floating point number between 0 and 1 |
Facial Similarity Standard Breakdowns
image_integrity | hash Asserts whether the quality and integrity of the uploaded files were sufficient to perform a face comparison |
(sub-breakdown) face_detected | hash Asserts a single face of good enough quality has been found on both the document image and the live photo |
(sub-breakdown) source_integrity | hash Asserts whether the live photo is trustworthy - i.e. not digitally tampered, from a fake webcam, or from other dubious sources |
face_comparison | hash Asserts whether the face in the document matches the face in the live photo |
visual_authenticity | hash Asserts whether the person in the live photo is real (not a spoof) |
We will return a reason whenever a report flags for source_integrity
. This
works by returning the contributing reason and a consider
result in the
source_integrity
breakdown properties. There can be more than one reason,
because they aren’t mutually exclusive. All other signals and potential
reasons will be omitted.
For Facial Similarity Standard, the source_integrity
sub-breakdown is composed of the following properties:
digital_tampering
- when evidence is found that the image was manipulated by Photoshop, or other softwarefake_webcam
- when evidence is found that a fake webcam was usedreasons
- additional comma separated details such as the exact digital tampering software used, or the name of the fake webcam
Properties
The score
property is a number between 0 and 1 that expresses how similar the two faces are, where 1 is a perfect match. If the face matching algorithm fails to detect a face, the score
property will not be present and the face matching task will be done manually.
The score
only measures how similar the faces are, and does not make an assessment of the nature of the photo. If tampering is detected, the applicant will be rejected independently of the score
. Examples of tampering are photos of printed photos, or photos of digital screens.
Facial Similarity Video
An example check object with a Facial Similarity Video report
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-09-25T11:41:22Z",
"status": "complete",
"redirect_uri": null,
"result": "consider",
"sandbox": false,
"tags": [
"Under 18"
],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-09-25T11:41:22Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "facial_similarity",
"properties": {
"score": 0.1252
},
"result": "consider",
"status": "complete",
"sub_result": null,
"variant": "video",
"breakdown": {
"face_comparison": {
"result": "consider"
},
"image_integrity": {
"result": "consider",
"breakdown": {
"face_detected": {
"result": "clear",
"properties": {}
},
"source_integrity": {
"result": "consider",
"properties": {
"fake_webcam": "consider",
"reasons": "Used fake webcam Perfect Fake Webcam"
}
}
}
},
"visual_authenticity": {
"result": "consider",
"breakdown": {
"liveness_detected": {
"result": "consider",
"properties": {}
},
"spoofing_detection": {
"result": null,
"properties": {}
}
}
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
In the Video variant of the Facial Similarity report, live videos are collected and uploaded by the Onfido iOS, Android or JS SDKs.
In addition to confirming the two faces match, Facial Similarity Video
assesses liveness by asking users to repeat randomly generated numbers and
perform a random head movement. This prevents impersonation - for example
photos of photos, or photos of screens. This process is reflected in
visual_authenticity
, which is composed of the sub-breakdowns
spoofing_detection
and liveness_detected
. See the sections Facial
Similarity Video Object and Facial
Similarity Video Breakdowns.
In order for a Facial Similarity Video report to complete automatically, the user needs to turn their head in the correct direction and correctly say the 3 randomly generated digits in one of our supported languages (see table below).
Language name | Language code |
---|---|
English | “en” |
Spanish | “es” |
Italian | “it” |
German | “de” |
French | “fr” |
Portuguese | “pt” |
Polish | “pl” |
Japanese | “ja” |
Dutch | “nl” |
Romanian | “ro” |
Basque | “eu” |
Catalan | “ca” |
Galician | “gl” |
SDK localization
We recommend that you localize the strings if you’re using one of the Onfido SDKs, so the user is more likely to understand the liveness headturn and speaking instructions.
The Onfido voice processor will attempt to detect the language the user is speaking. This will be more successful if you pass the code for the expected language to the locale
mechanism, in any of the Onfido SDKs:
- iOS SDK - pass the
onfido_locale
parameter - Android SDK - pass the
onfido_locale
parameter - Web SDK - pass the
locale
parameter
Some string localisations are available out of the box, but this differs depending on the SDK.
You can also provide your own custom translations to your users.
Facial Similarity Video Object
The following table describes the unique fields returned in the Onfido API (v2) for the Facial Similarity Video report:
Attribute | Format | Possible values |
---|---|---|
result |
String or null |
"clear" , "consider" , null |
image_integrity |
String or null |
"clear" , "consider" , null |
(sub-breakdown) face_detected |
String or null |
"clear" , "consider" , null |
(sub-breakdown) source_integrity |
String or null |
"clear" , "consider" , null |
face_comparison |
String or null |
"clear" , "consider" , null |
visual_authenticity |
String or null |
"clear" , "consider" , null |
(sub-breakdown) spoofing_detection |
String or null |
"clear" , "consider" , null |
(sub-breakdown) liveness_detected |
String or null |
"clear" , "consider" , null |
properties |
||
score |
Floating point number between 0 and 1, or null |
Facial Similarity Video Breakdowns
face_comparison | hash Asserts whether the face in the document matches the face in the live video |
image_integrity | hash Asserts whether the quality of the uploaded files and the content contained within them were sufficient to perform a face comparison |
(sub-breakdown) face_detected | hash Asserts a single face of good enough quality has been found on both the document image and in the live video |
(sub-breakdown) source_integrity | hash Asserts whether the live video is trustworthy - e.g. not from a fake webcam |
visual_authenticity | hash Asserts whether the person in the live video is real (not a spoof) and live |
(sub-breakdown) spoofing_detection | hash Asserts whether the live video is not a spoof (such as videos of digital screens) |
(sub-breakdown) liveness_detected | hash Asserts whether the numbers and head movements were correctly executed |
We will return a reason whenever a report flags for source_integrity
. This
works by returning the contributing reason and a consider
result in the
source_integrity
breakdown properties. There can be more than one reason,
because they aren’t mutually exclusive. All other signals and potential
reasons will be omitted.
For Facial Similarity Video, the source_integrity
sub-breakdown is composed of the following properties:
fake_webcam
- when evidence is found that a fake webcam was usedreasons
- additional comma separated details, such as the name of the fake webcam
Properties
The score
property is a number between 0 and 1 that expresses how similar the two faces are, where 1 is a perfect match. If the face matching algorithm fails to detect a face, the score
property will not be present and the face matching task will be done manually.
The score
only measures how similar the faces are, and does not make an assessment of the nature of the video. If tampering is detected, the applicant will be rejected independently of the score
. Examples of tampering are videos of digital screens, videos of masks, videos of print outs.
Identity report
An example check object with an Identity report (‘standard’ variant)
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-10-08T14:27:08Z",
"status": "complete",
"redirect_uri": null,
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-10-08T14:27:08Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "identity",
"properties": {
"matched_address": <MATCHED_ADDRESS_ID>,
"matched_addresses": [
{
"id": <MATCHED_ADDRESS_ID>,
"match_types": [
"credit_agencies",
"voting_register"
]
}
]
},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "standard",
"breakdown": {
"address": {
"result": "clear",
"breakdown": {
"credit_agencies": {
"result": "clear",
"properties": {
"number_of_credit_agencies": "1"
}
},
"telephone_database": {
"result": "clear",
"properties": {}
},
"voting_register": {
"result": "clear",
"properties": {}
}
}
},
"date_of_birth": {
"result": "clear",
"breakdown": {
"credit_agencies": {
"result": "clear",
"properties": {}
},
"voting_register": {
"result": "clear",
"properties": {}
}
}
},
"mortality": {
"result": null
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
An example check object with an Identity report (US Identity report with social security number provided)
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<REPORT_ID>",
"name": "identity",
"created_at": "2014-05-23T13:50:33Z",
"status": "complete",
"result": "clear",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"breakdown": {
"date_of_birth": {
"result": "clear",
"breakdown": {
"date_of_birth_matched": {
"result": "clear",
"properties": {
"sources": "Credit Agencies"
}
}
}
},
"address": {
"result": "clear",
"breakdown": {
"address_matched": {
"result": "clear",
"properties": {
"sources": "Credit Agencies, Telephone Database"
}
}
}
},
"ssn": {
"result": "clear",
"breakdown": {
"last_4_digits_match": {
"result": "clear",
"properties": {}
},
"full_match": {
"result": "clear",
"properties": {}
}
}
},
"properties": {}
}
}
An example check object with an Identity report (for jurisdictions other than UK and US)
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<REPORT_ID>",
"name": "identity",
"created_at": "2014-05-23T13:50:33Z",
"status": "complete",
"result": "clear",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"breakdown": {
"date_of_birth": {
"result": "clear",
"breakdown": {
"date_of_birth_matched": {
"result": "clear",
"properties": {
"sources": "Credit Agencies"
}
}
}
},
"address": {
"result": "clear",
"breakdown": {
"address_matched": {
"result": "clear",
"properties": {
"sources": "Credit Agencies, Telephone Database"
}
}
}
}
},
"properties": {}
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Identity report | identity |
kyc standard |
yes yes |
yes yes |
An Identity report validates an applicant’s address, date of birth, name, and mortality (where applicable) by cross-referencing their details against a range of verified databases.
For applicants in the United States, the Identity report can optionally match the Social Security Number, either the full 9 digits or the last 4.
The result breakdowns indicate which of these elements was positively matched, and the underlying source or sources of that database match.
The Identity report will be run in the jurisdiction specified as country
in the applicant object, not the applicant’s address country
field. The country
field in the applicant object will default to GBR
if not provided.
Please make sure that the applicant object’s country
field matches the applicant’s address country
field when creating an applicant, and that the country is supported for Identity reports.
Report results vary depending on the jurisdiction they were run in. The examples to the right detail:
- UK: Results for an Identity report conducted in the United Kingdom, where sources (
credit_agencies
,voting_register
,telephone_database
) are displayed as breakdowns with their ownresult
value. - US with SSN: Results for an Identity report conducted in the United States, which includes Social Security Number as an additional breakdown, and lists sources as comma separated under
properties
. - Non-UK: Results for an Identity report conducted on a jurisdiction other than United Kingdom, where sources are shown as comma separated under
properties
.
When a match for date of birth or address cannot be found (i.e. result
is not clear
) the corresponding properties
bucket will be empty as such "properties":{}
.
Supported countries for Identity reports
You can review the full list of supported countries for Identity reports.
The column Onfido Identity Report on that page lists supported
and
unsupported
countries.
Required applicant data
For all Identity report variants, the following applicant data must be provided:
first_name
last_name
dob
country
(the country of jurisdiction, where the check will be performed. Must be a three-letter ISO code e.g. “GBR”)
address[]state
(US only)
address[]postcode
(ZIP code in US)
address[]country
(must be a three-letter ISO code e.g. “GBR”)
Recommended applicant data
address[]street
Source names and definitions
Source name |
Definition |
Credit Agencies | Data comprised of consumer credit applications |
Voting Register | Data comprised of voter registration within a country |
Telephone Database | Data provided by both landline and mobile providers. In the UK, this is landline only |
Government | Any standard publicly accessible data collected by government entities. These include driving licence data, motor vehicle registration, court filings, property ownership registers, permanent place of residence registration and other similar data sets |
Business Registration | Data comprised of business registrations, corporate directors filings and business hierarchy data |
Consumer Database | Opt-in consumer data leveraging database marketing and other similar opt-in data sources |
Utility Registration | Data comprised of utility registrations such as electricity, gas, water accounts |
Postal Authorities | Data provided by postal authorities |
Commercial Database | These are corporate/private databases where users have opted-in and allowed for their information to be used for the purpose of verification of their identities |
Proprietary | This is when a data provider chooses not to divulge the source of the data to us for varied reasons, and also includes social media based data |
Register of Deaths | Negative source for known deaths (UK only) |
There are two different variants of the Identity report: kyc
and standard
. To specify which one you want, pass variant
with the create check request. If not provided the default is standard
.
Identity KYC
This check should be used for “Know Your Customer” (KYC) purposes, for instance, if you are providing a financial service.
Overall result logic:
If the applicant address is in the UK:
"result": "clear"
the applicant is not found in mortality lists AND- at least one match on the applicant’s name and current address, and a match on the applicant’s name and date of birth (either in the same or different source) OR
- two matches on the applicant’s name and current address from two different sources
"result": "consider"
either:- the applicant is found in mortality lists, or;
- only one match on the applicant’s name and current address or name and date of birth
"result": "unidentified"
no matches are found
This follows the definition of 2+2 as per the JMLSG Guidelines 2014 Section 5.3.69.
If the applicant address is outside of the UK:
"result": "clear"
at least one source matches the applicant’s name and current address"result": "consider"
the name and date of birth is matched, but no name and address matches are found"result": "unidentified"
no matches are found
When the SSN or the last four digits of the SSN are provided:
"result": "clear"
at least one source matches the applicant’s name and address, and the last four digits of the SSN are matched"result": "unidentified"
no matches are found"result": "consider"
otherwise
Number of addresses: As per JMLSG definitions, this check will only attempt to find a match using the applicant’s current address.
Mortality: Only checked in the UK.
Identity Standard
This check should be used for employment or recruitment purposes, or where identity verification is performed in an unregulated industry.
Overall result logic:
"result": "clear"
at least one source matches the applicant’s name and address"result": "consider"
the name and date of birth is matched, but no name and address matches are found"result": "unidentified"
no matches are found
When the SSN or the last four digits of the SSN are provided:
"result": "clear"
at least one source matches the applicant’s name and address, and the last four digits of the SSN are matched"result": "unidentified"
no matches are found"result": "consider"
otherwise
Number of addresses: This check will attempt to find an address match for the current applicant address. If no match is found it will attempt to match the previous address (if provided), up to a total of 3 applicant addresses.
Mortality: Not checked.
Identity report custom logic
Partial Identity report result for custom logic example
HTTP/1.1 201 Created
Content-Type: application/json
...
"breakdown": {
"address": {
"result": "clear",
"breakdown": {
"credit_agencies": {
"result": "clear",
"properties": {
"number_of_credit_agencies": "1" ## --< ADD ">=2" CRITERIA HERE>
}
},
"telephone_database": {
"result": "clear",
"properties": {}
},
"voting_register": {
"result": "clear",
"properties": {}
}
}
},
"date_of_birth": {
"result": "clear",
"breakdown": {
"credit_agencies": {
"result": "clear", ## --< ADD "=clear" CRITERIA HERE>
"properties": {}
},
...
You can (optionally) build your own logic around report results.
For example, you may use Identity reports for the credit_agencies
sub-breakdown result. You may require 2 or more hits against the address
breakdown but only 1 against the date_of_birth
breakdown.
In this example, you would add criteria of:
>=2
againstnumber_of_credit_agencies
under thecredit_agencies
sub-breakdown that is under theaddress
parent breakdown.clear
against theresult
value under thecredit_agencies
sub-breakdown that is under thedate_of_birth
parent breakdown.
See also the comments against the partial example in the right-hand column.
Watchlist KYC report
An example check object with a Watchlist ‘KYC’ report
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-10-08T14:31:20Z",
"status": "complete",
"redirect_uri": null,
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-10-08T14:31:20Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "watchlist",
"properties": {
"records": []
},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "kyc",
"breakdown": {
"politically_exposed_person": {
"result": "clear"
},
"sanction": {
"result": "clear"
},
"adverse_media": {
"result": "clear"
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Watchlist report | watchlist |
kyc |
yes | yes |
A Watchlist ‘KYC’ check provides a granular breakdown of any records found when searching global watchlists. These include: Government Sanctions Lists, Politically Exposed Persons (PEP) Lists, and more generally Adverse Media, including Terrorism, Money Laundering, Regulatory Action, and Most Wanted lists.
If no match is found against the subject, the records
field will read []
and the overall result
will be clear
.
If one or more matches are found, each match will be returned under records
and includes, but is not limited to: name and date of birth of match, aliases and associates, and relevant events and sources. Each event will correspond to a relevant category of list, which drives one of the breakdowns (see “Response breakdowns”, and the overall result
will be consider
.
When available, URLs to data sources are provided, as well as pictures of the individual found in the match. This, along with other detail in the response, allows you to quickly assess the relevancy of the match and eliminate false positives.
Required applicant data
For Watchlist (KYC) reports, the following applicant data must be provided:
first_name
last_name
Recommended applicant data
dob
address[]street
address[]postcode
(ZIP code in US)
address[]country
Date of birth
Submitting a date_of_birth
with the name is optional but recommended, to narrow the search of the relevant individual.
More than one date of birth might be found per match due to the nature of the data sources, such as newspaper articles, which might include someone’s age but not their full date of birth.
Address
Submitting an address
with the name is also optional but recommended. This will narrow the search to the country specified in the address, for all lists except for Sanctions and Terrorist lists.
If a match is found but the date_of_birth
or address
fields are null
, this means there is no date_of_birth
or address
data on file associated with that match.
Response breakdowns
adverse_media |
|
politically_exposed_person |
|
sanction |
Watchlist full report
An example check object with a Watchlist ‘full’ report
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-10-08T14:32:40Z",
"status": "complete",
"redirect_uri": null,
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-10-08T14:32:40Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "watchlist",
"properties": {
"records": []
},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "full",
"breakdown": {
"sanction": {
"result": "clear"
},
"politically_exposed_person": {
"result": "clear"
},
"legal_and_regulatory_warnings": {
"result": "clear"
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Watchlist report | watchlist |
full |
yes | yes |
A Watchlist ‘full’ check provides a granular breakdown of any records found when searching global watchlists. The watchlists include: government sanctions lists, politically exposed persons lists, and more generally: warnings lists such as anti-terrorism watchlists, anti-money-laundering (AML) watchlists and most wanted watchlists.
Required applicant data
For Watchlist ‘full’ checks, the following applicant data must be provided:
first_name
last_name
Recommended applicant data
dob
Extra report options
For Watchlist ‘full’ reports, you can use the options
array when creating a
check. You can populate this with the following:
peps
- will search only politically exposed persons listssanctions
- will search sanctions lists and warnings lists
If no options
are specified, all types will be searched: PEPs, Sanctions and
Warnings.
Each match will be returned under records
and includes, but is not limited
to: name of match, associates, date of birth, related keywords, type of list,
name of list, and when the entry was last updated. When available, URLs to
data sources are provided, as well as pictures of the individual found in the
match. This allows you to quickly assess the relevancy of the match and
eliminate false positives.
More than one date of birth might be found per match, due to the nature of the data sources, such as news papers articles, which might include someone’s age but not their full date of birth.
Breakdowns
legal_and_regulatory_warnings | hash |
politically_exposed_person | hash |
sanction | hash |
Street Level report
An example check object with a Street Level report
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-10-08T14:35:55Z",
"status": "complete",
"redirect_uri": null,
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-10-08T14:35:55Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "street_level",
"properties": {},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "standard",
"breakdown": {
"slv_address": {
"result": "clear"
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Street Level report | street_level |
- | yes | yes |
A Street Level report confirms a person’s address by sending a letter to their home with a unique verification code. The applicant enters this code online to confirm their address, which yeilds a "result": "clear"
. If after 15 days no response is received, the report will return a "result": "consider"
.
Required applicant data
For Street Level reports, the following applicant data must be provided:
first_name
last_name
address[]street
address[]postcode
(ZIP code in US)
address[]country
Delivery times
The time at which the 15 day counter starts depends on the check type. For express checks, it starts from the report creation date. For standard checks, time starts counting from the moment the applicant has submitted their details in the applicant form.
Letters to UK addresses are sent out by Royal Mail second class postal service. Letters to countries other than the UK are sent out by Royal Mail first class postal service.
All mail is collected Monday-Friday at 3:00pm UK time, excluding UK bank holidays. This means that letters for any reports created after 3pm on a Friday will only be collected on the following Monday at 3pm.
Delivery times from time of mail collection:
- UK: 2 to 3 working days, including Saturdays.
- Europe: 3 to 5 working days.
- Rest of the World: 5 to 7 working days.
Remote areas may take longer.
Royal Mail claim to have a 99% deliverability rate in the UK and 93% for Rest of the World. Providing good quality address data, with all fields correctly filled in the applicant object, greatly increases the deliverability of the letter. Do note that deliverability of the letter is not enough to clear
the report. The applicant must enter the code online within the 15 days in order for the report to return as clear
.
Customisation
The default letter is Onfido branded and directs the applicant to enter their code at https://onfido.com/slv.
Alternatively the letter can be customised with your branding of choice. If you wish to discuss this please contact your account manager or email client-support@onfido.com.
You can also build your own front end for the applicant to input their code using the submit code endpoint.
Breakdowns
address | hash Contains the result and details of an address match |
Proof of Address report
The Onfido Proof of Address (PoA) solution allows users to upload PoA documents from anywhere in the world. Currently, the Onfido platform can only process UK PoA documents.
The document’s issuing country must be specified when uploading the document via the document upload endpoint by setting the issuing_country
field.
If the issuing_country
field is not specified or is from an unsupported country (i.e. it is different from “GBR”), the document will be uploaded on the system however it will not be processed and the report will complete with the status set to cancelled
and the result set to null
.
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Proof of Address report | proof_of_address |
- | no | yes |
Required applicant data
For Proof of Address reports, the following applicant data must be provided:
first_name
last_name
address[]street
address[]town
address[]postcode
address[]country
(must be a three-letter ISO code e.g. “GBR”)
Supported document types
Bank Statement/Building Society Statements | bank_building_society_statement |
Utility Bill (electricity, water, gas, broadband ) | utility_bill |
Council Tax | council_tax |
Benefits Letter (i.e. Job seeker allowance, House benefits, Tax credits) | benefit_letters |
For PoA documents from unsupported countries (i.e. non-UK PoA documents), the following document types can be uploaded to the system:
“Capture Only” Document Types
Bank Statement/Building Society Statements | bank_building_society_statement |
Utility Bill (electricity, water, gas, broadband ) | utility_bill |
Government Letters | government_letter |
A PoA report upon completion is composed of three breakdowns: image integrity, document classification and data comparison.
Breakdowns
image_integrity | hash Asserts whether the quality of the uploaded document was sufficient to verify the address |
document_classification | hash Asserts whether the document is of a valid type as PoA |
data_comparison | hash Asserts whether the first name, last name and address provided by the applicant match those on the PoA document |
In addition, data points extracted from PoA documents are returned in the properties
attribute:
Properties
document_type | This property provides the document type according to the set of supported documents |
issue_date | This property provides the issue date of the document |
summary_period_start | This property provides the summary period start date |
summary_period_end | This property provides the summary period end date |
issuer | This property provides the document issuer (e.g. HSBC, British Gas) |
first_names | This property provides the first names on the document, including any initials and middle names |
last_names | This property provided the last names on the document |
address | This property provides the address on the document |
The summary period and the issue date are mutually exclusive, in the sense that only one of them is returned in the report properties attribute (either the summary period start and end dates or the issue date).
Overall result logic
The PoA report can return a result of clear
or consider
or null
.
The overall report result will be clear
if all of the following are true:
- the quality of the provided PoA document is sufficient to process it
- the provided PoA document is a supported UK PoA document
- the data provided by the applicant matches the data that is on their PoA document
The overall report result will be null
if any of the following is true:
- the
issuing_country
field set when uploading the document is from an unsupported country (i.e. it is different from “GBR”) - the
issuing_country
field is not provided when uploading the document
Please note that if the report result is null
, the report status will be cancelled
.
The overall report result will be consider
if any of the following is true:
- the document was not of enough quality to be processed (e.g. image blurred, data points not visible on the document). In this scenario, the value of the
image_quality
breakdown (which is part of theimage_integrity
breakdown) will beunidentified
and no data will be extracted from the document, hence the report properties attribute will be empty and all the other breakdowns will benull
- the document is not a valid UK PoA document (i.e. it does not feature in the list of supported document types). In this scenario the value of the
supported_document
breakdown (which is part of thedocument_classification
breakdown) will beunidentified
, no data will be extracted from the document, hence the report properties attribute will be empty and the data comparison breakdowns will be set tonull
- the data provided by the applicant does not match the data extracted from the PoA document. In this scenario the breakdowns
first_name
,last_name
andaddress
(which are part of thedata_comparison
breakdown) will have a value ofunidentified
. Data is extracted from the document and returned as part of the report properties attribute.
Right to Work report
An example check object with a Right to Work report
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<CHECK_ID>",
"created_at": "2019-10-08T14:38:21Z",
"status": "complete",
"redirect_uri": null,
"result": "clear",
"sandbox": true,
"tags": [],
"results_uri": "<RESULTS_URI>",
"form_uri": null,
"reports": [
{
"created_at": "2019-10-08T14:38:21Z",
"href": "/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"id": "<REPORT_ID>",
"name": "right_to_work",
"properties": {
"nationality": "",
"last_name": "Smith",
"issuing_country": "GBR",
"gender": "",
"first_name": "John",
"document_type": "passport",
"document_numbers": [
{
"value": "9999999999",
"type": "passport"
}
],
"date_of_expiry": "1900-01-01",
"date_of_birth": "1900-01-01"
},
"result": "clear",
"status": "complete",
"sub_result": null,
"variant": "standard",
"breakdown": {
"data_comparison": {
"result": "clear",
"breakdown": {
"issuing_country": {
"result": "clear",
"properties": {}
},
"gender": {
"result": "clear",
"properties": {}
},
"date_of_expiry": {
"result": "clear",
"properties": {}
},
"last_name": {
"result": "clear",
"properties": {}
},
"document_type": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"first_name": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
}
}
},
"data_validation": {
"result": "clear",
"breakdown": {
"gender": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"document_expiration": {
"result": "clear",
"properties": {}
},
"expiry_date": {
"result": "clear",
"properties": {}
},
"mrz": {
"result": "clear",
"properties": {}
}
}
},
"image_integrity": {
"result": "clear",
"breakdown": {
"image_quality": {
"result": "clear",
"properties": {}
},
"supported_document": {
"result": "clear",
"properties": {}
},
"colour_picture": {
"result": "clear",
"properties": {}
}
}
},
"visual_authenticity": {
"result": "clear",
"breakdown": {
"fonts": {
"result": "clear",
"properties": {}
},
"picture_face_integrity": {
"result": "clear",
"properties": {}
},
"template": {
"result": "clear",
"properties": {}
},
"security_features": {
"result": "clear",
"properties": {}
},
"original_document_present": {
"result": "clear",
"properties": {}
},
"digital_tampering": {
"result": "clear",
"properties": {}
},
"other": {
"result": "clear",
"properties": {}
},
"face_detection": {
"result": "clear",
"properties": {}
}
}
},
"data_consistency": {
"result": "clear",
"breakdown": {
"date_of_expiry": {
"result": "clear",
"properties": {}
},
"document_numbers": {
"result": "clear",
"properties": {}
},
"issuing_country": {
"result": "clear",
"properties": {}
},
"document_type": {
"result": "clear",
"properties": {}
},
"date_of_birth": {
"result": "clear",
"properties": {}
},
"gender": {
"result": "clear",
"properties": {}
},
"first_name": {
"result": "clear",
"properties": {}
},
"last_name": {
"result": "clear",
"properties": {}
},
"nationality": {
"result": "clear",
"properties": {}
}
}
},
"police_record": {
"result": "clear"
},
"right_to_work": {
"result": "clear",
"breakdown": {
"applicant_has_the_right_to_work": {
"result": "clear",
"properties": {}
}
}
},
"compromised_document": {
"result": "clear"
}
}
}
],
"paused": false,
"type": "express",
"report_type_groups": [
"<REPORT_TYPE_GROUP_ID>"
],
"download_uri": "<DOWNLOAD_URI>",
"href": "/v2/applicants/<APPLICANT_ID>/checks/<CHECK_ID>",
"version": "2.0"
}
Report | Name | Variants | Standard check | Express check |
---|---|---|---|---|
Right to work report | right_to_work |
yes | yes |
The Right to Work report is for use in the United Kingdom only.
A Right to Work report identifies whether an applicant has the right to work within the United Kingdom.
Required applicant data
For Right to Work reports, first_name
and last_name
must be provided but can be
dummy values if you don’t know an applicant’s name.
Document requirements
UK citizens
UK citizens - document requirements |
---|
Passport |
UK birth certificate AND proof of national insurance number |
UK adoption certificate AND proof of national insurance number |
UK Certificate of Naturalisation (or Registration) AND proof of national insurance number |
EU/EEA/Swiss citizens
EU/EEA/Swiss citizens - document requirements |
---|
Passport |
National Identity Card |
Registration Certificate |
Citizens of other nationalities
Non-UK/EU/EEA/Swiss citizens - document requirements |
---|
Biometric Residence Permit (or Biometric Residence Card) - cannot be expired |
Passport AND visa within current passport - cannot be expired |
UK Immigration Status Document AND proof of national insurance number |
Home Office letter - must have been issued within the last 6 months |
Application Registration Card - cannot be expired |
Positive Verification Notice - cannot be expired |
Supporting documents
Depending on documents already provided, additional documents may be required for proof of a name change, student status, Tier 2 or Tier 5 visa status, or National Insurance number. Additional documents that may be required are detailed in the next sections.
Proof of name change
One of the following:
- Marriage certificate
- Divorce decree (absolute)
- Deed poll
- Adoption certificate
Tier 4 (General) student
- Proof of term (and vacation) dates
Tier 2 and Tier 5 Permit visas
- Certificate of Sponsorship
Proof of National Insurance number
One of the following:
- P45 or P60
- Payslip
- HMRC letter
- Benefits letter
Ping
Ping (check api.onfido.com can receive requests)
GET /ping HTTP/1.1
Host: api.onfido.com
curl https://api.onfido.com/ping
GET
https://api.onfido.com/ping
Runs a health check on the Onfido API.
If api.onfido.com
is operational, the ping
endpoint will return OK
in
Text format.
You can also subscribe to webhook notifications from https://status.onfido.com.
Webhooks
An example webhook object (check started)
HTTP/1.1 200 OK
Content-Type: application/json
{
"webhooks": [
{
"id": "<WEBHOOK_ID>",
"url": "https://demo.com",
"enabled": false,
"href": "/v2/webhooks/<WEBHOOK_ID>",
"token": "<WEBHOOK_TOKEN>",
"environments": [
"sandbox"
],
"events": [
"check.started"
]
}
]
}
Onfido provides webhooks to alert you of changes in the status of your resources (i.e. checks and reports). These are POST requests to your server that are sent as soon as an event occurs. The body of the request contains details of the event.
Sandbox checks and reports also trigger webhook notifications. You can create and configure webhooks to receive status changes from sandbox, live or both environments.
Upon receiving a webhook notification, you should acknowledge success by
responding with an HTTP 20x
response within 10 seconds. Otherwise, we will
attempt to resend the notification 5 times according to the following schedule:
- 30 seconds after the first attempt
- 2 minutes after the first attempt
- 15 minutes after the first attempt
- 2 hours after the first attempt
- 10 hours after the first attempt
We also use circuit breaking for webhooks: if any 5 requests to the same webhook fail in a row, then that webhook will be disabled for one minute.
IP addresses
All webhook requests will come from the following IPs:
Europe:
52.51.171.25
52.51.228.228
52.51.234.203
United States:
34.232.2.222
52.55.124.58
34.224.182.19
Please make sure that you’ve whitelisted these IPs in order to receive webhook notifications.
Events
By default, webhooks are subscribed to all events, but can be subscribed to a
subset using the events
array.
You can configure the following events to trigger a message to registered webhooks:
Resource | Events | Description |
---|---|---|
check | check.started | A check has been started. When check.type = standard , this indicates the applicant has submitted all required information. |
check | check.reopened | A check has been reopened. This indicates the applicant needs to re-submit required information. |
check | check.withdrawn | A check has been withdrawn. |
check | check.completed | A check has been completed. |
check | check.form_completed | An applicant has submitted their information using the check form. |
report | report.withdrawn | A report has been withdrawn. |
report | report.resumed | A paused report has been resumed. |
report | report.cancelled | A paused report has been cancelled. |
report | report.awaiting_approval | A report has transitioned to the “Awaiting Approval” status. |
report | report.completed | A report has been completed and results are available. |
Event object
An example event object (report completed)
HTTP/1.1 201 Created
Content-Type: application/json
{
"payload": {
"resource_type": "report",
"action": "report.completed",
"object": {
"id": "<REPORT_ID>",
"status": "complete",
"completed_at_iso8601":"2019-11-25T10:11:36Z",
"href": "https://api.onfido.com/v2/checks/<CHECK_ID>/reports/<REPORT_ID>",
"completed_at": "2019-11-25 10:11:36 UTC"
}
}
}
Attributes
Attribute | Description |
---|---|
payload | hash The top level element |
resource_type | string Indicates the resource affected by this event |
action | string The event that triggered this webhook, e.g. report.completed |
object | hash The object affected by this event. This will contain an id and an href to retrieve that resource |
Webhook security
X-SHA2-Signature: <HMAC_VALUE>
Validating the X-SHA2-Signature in Sinatra
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), <YOUR_SECRET_TOKEN>, <PAYLOAD_OBJECT>)
return halt 500, "Signatures did not match!" unless Rack::Utils.secure_compare(signature, request.env['X_SHA2_SIGNATURE'])
You should verify request signatures on your server to prevent attackers from imitating valid webhooks.
You only need to register a webhook once. Each webhook is associated with a
single secret token, which is used to generate an
HMAC using SHA-256
. When you first
register a webhook, this secret token will be returned in
the API response body. The token for each webhook is also displayed on the
Onfido Dashboard ‘Webhook Management’
page.
Events sent to your application will have an X-SHA2-Signature
header in the
request, containing the HMAC. When you receive an event, you should use your
secret token to compute a hash based on the complete event payload. You should
make sure that this matches the X-SHA2-Signature
header sent by Onfido.
Register webhook
Register a webhook
POST /v2/webhooks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"url": "https://<URL>",
"enabled": true,
"environments": [
"live",
"sandbox"
],
"events": [
"report.completed",
"report.withdrawn",
"check.completed",
"check.started",
"check.form_completed"
]
}
curl https://api.onfido.com/v2/webhooks/ \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-F 'url=https://<URL>'
url = {url: "https://<URL>"}
api.webhook.create(url)
webhook = onfido.Webhook(url='https://<URL>')
api.create_webhook(webhook)
$webhook = new \Onfido\Model\Webhook();
$webhook->setUrl('https://<URL>');
$api->createWebhook($webhook);
Webhook webhook = new Webhook();
webhook.setUrl("https://<URL>");
webhook.setEnvironments(null);
Webhook result = apiInstance.createWebhook(webhook);
const webhook = new Onfido.Webhook();
webhook.url = 'https://<URL>';
(async () => {
try {
const create_webhook = await api.createWebhook(webhook);
console.log(create_webhook);
} catch(e) {
console.log(e)
}
})();
Example response (register webhook)
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<WEBHOOK_ID>",
"url": "https://webhookendpoint.url",
"token": "<WEBHOOK_TOKEN>",
"enabled": true,
"href": "/v2/webhooks/<WEBHOOK_ID>",
"environments": [
"live",
"sandbox"
],
"events": [
"report.completed",
"report.withdrawn",
"check.completed",
"check.started",
"check.form_completed"
]
}
POST
https://api.onfido.com/v2/webhooks/
Registers a webhook.
Read the “Webhook security” section for more context, and to learn more about how to verify request signatures on your server.
Request body parameters
url | required The url that will listen to notifications (must be HTTPS). |
enabled | optional Determine if the webhook should be active. If omitted, will be set to true by default. |
environments | optional The environments from which the webhook will receive events. Allowed values are “sandbox” and “live”. If omitted, the webhook will receive events from both environments. |
events | optional The events that should be published to the webhook. If omitted, all events will be subscribed by default. You can read about the supported events. |
Register a webhook using the Dashboard
You can also register webhooks through the Onfido dashboard.
Webhook logs
To help you diagnose webhook issues, you can review logs on the Onfido Dashboard.
List webhooks
List all webhooks you’ve created
GET /v2/webhooks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
curl https://api.onfido.com/v2/webhooks/ \
-H 'Authorization: Token token=test_vrkuXHTuZL6g_I1fy9K5I4UQoSq1ObaR' \
api.webhook.all
api.list_webhooks()
$api->listWebhooks();
WebhooksList result = apiInstance.listWebhooks();
(async () => {
try {
const { webhooks } = await api.listWebhooks();
webhooks.forEach(webhook => console.log(webhook));
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/webhooks/
Lists all webhooks you’ve created.
Retrieve webhook
Retrieve a single webhook
GET /v2/webhooks/<WEBHOOK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
curl https://api.onfido.com/v2/webhooks/<WEBHOOK_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
api.webhook.find('<WEBHOOK_ID>')
api.find_webhook('<WEBHOOK_ID>')
$api->findWebhook('<WEBHOOK_ID>');
String webhookId = "<WEBHOOK_ID>";
Webhook result = apiInstance.findWebhook(webhookId);
(async () => {
try {
const webhook = await api.findWebhook('<WEBHOOK_ID>');
console.log(webhook);
} catch(e) {
console.log(e)
}
})();
GET
https://api.onfido.com/v2/webhooks/{webhook_id}
Retrieves a single webhook.
Edit webhook
Edit a webhook (change the URL)
PUT /v2/webhooks/<WEBHOOK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"url": "https://<NEW_URL>"
}
curl https://api.onfido.com/v2/webhooks/<WEBHOOK_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://<NEW_URL>"
}' \
-X PUT
update_webhook = onfido.Webhook(url='https://<NEW_URL>')
webhook_id = '<WEBHOOK_ID>'
api.edit_webhook(webhook_id, update_webhook)
$update_webhook = new \Onfido\Model\Webhook();
$update_webhook->setUrl('https://<NEW_URL>');
$api->editWebhook('<WEBHOOK_ID>', $update_webhook));
Webhook webhook = new Webhook();
webhook.setEnvironments(null);
webhook.setEvents(null);
webhook.setUrl("https://<NEW_URL>");
String webhookId = "<WEBHOOK_ID>";
Webhook result = apiInstance.editWebhook(webhookId, webhook);
const update_webhook = new Onfido.Webhook();
update_webhook.url = 'https://<NEW_URL>';
(async () => {
try {
const webhook = await api.editWebhook('<WEBHOOK_ID>', update_webhook);
console.log(webhook);
} catch(e) {
console.log(e)
}
})();
PUT
https://api.onfido.com/v2/webhooks/{webhook_id}
Edits a webhook.
Delete webhook
Delete a webhook
DELETE /v2/webhooks/<WEBHOOK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
curl https://api.onfido.com/v2/webhooks/<WEBHOOK_ID> \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-X DELETE
webhook_id = '<WEBHOOK_ID>'
api.delete_webhook(webhook_id)
$webhook_id = '<WEBHOOK_ID>';
$api->deleteWebhook($webhook_id);
String webhookId = "<WEBHOOK_ID>";
apiInstance.deleteWebhook(webhookId);
(async () => {
try {
await api.deleteWebhook('<WEBHOOK_ID>');
} catch(e) {
console.log(e)
}
})();
DELETE
https://api.onfido.com/v2/webhooks/{webhook_id}
Deletes a webhook.
Report type groups
Report type groups provide a convenient way to group and organize different types of reports, so that you can easily request different sets of reports for different buckets of applicants. For example, you may want to only run an identity
report and a right_to_work
report on a junior-level role, but you may want additional reports on a more senior-level role.
To set up or update your report type groups, please contact client-support@onfido.com.
Report type group object
An example report type group object (Identity, Right to Work)
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "<REPORT_TYPE_GROUP_ID>",
"name": "Junior level",
"group_only": false,
"report_types": [
{
"id": "<REPORT_ID>",
"name": "identity"
},
{
"id": "<REPORT_ID>",
"name": "right_to_work"
}
]
}
The report type group object defines the set of reports to be requested in a check.
Note that more than one report type group can be requested in a single check.
Attribute | Description |
---|---|
id | string The unique identifier for the group. |
name | string The group’s name, as specified under your account. |
group_only | boolean If false, individual reports in that group can be requested; if true, all reports must be requested together. |
report_types | list [object] A list of objects containing information regarding the different report types included in this group. |
Retrieve report type group
Retrieve a single report type group
GET /v2/report_type_groups/<REPORT_TYPE_GROUP_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
GET
https://api.onfido.com/v2/report_type_groups/{report_type_group_id}
A single report type group can be retrieved by calling this endpoint with the group’s unique identifier.
List report type groups
List report type groups
GET /v2/report_type_groups/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
GET
https://api.onfido.com/v2/report_type_groups/
All report type groups belonging to your account can be listed from this endpoint.
Address picker
Search for an address using a postcode
GET /v2/addresses/pick?postcode=SW46EH HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v2/addresses/pick?postcode=SW46EH \
-H 'Authorization: Token token=<YOUR_API_TOKEN>'
api.address.all('SW4 6EH')
api.find_addresses('SW4 6EH')
$postcode = 'SW4 6EH';
$api->findAddresses($postcode);
String postcode = "SW4 6EH";
GenericAddressesList result = apiInstance.findAddresses(postcode);
(async () => {
try {
const address = await api.findAddresses('SW4 6EH');
console.log(address);
} catch(e) {
console.log(e)
}
})();
Example response (search for an address using a postcode)
HTTP/1.1 201 Created
Content-Type: application/json
{
"addresses": [
{
"flat_number": "",
"building_number": "100",
"building_name": "",
"street": "Main Street",
"sub_street": "",
"town": "London",
"postcode": "SW4 6EH",
"country": "GBR"
},
{
"flat_number": "",
"building_number": "101",
"building_name": "",
"street": "Main Street",
"sub_street": "",
"town": "London",
"postcode": "SW4 6EH",
"country": "GBR"
}
]
}
GET
https://api.onfido.com/v2/addresses/pick?postcode={postcode}
The address picker endpoint performs a search for addresses by postcode (UK only).
This resource can be used to aid in ensuring addresses passed to /applicants are valid.
Query string parameters
postcode
(required): the applicant’s postcode.
Generate SDK token
Generate a new SDK token with a referrer
POST /v2/sdk_token HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"applicant_id": "<APPLICANT_ID>",
"referrer:": "https://<URL>"
}
curl https://api.onfido.com/v2/sdk_token \
-H 'Authorization: Token token=<YOUR_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"applicant_id": "<APPLICANT_ID>",
"referrer": "https://*.example.com/example_page/**"
}' \
-X POST
api.sdk_token.create(applicant_id: '<APPLICANT_ID>', referrer: 'https://*.example.com/example_page/*')
sdk_token_request = onfido.SdkTokenRequest(applicant_id, 'https://*.example.com/example_page/*')
api.generate_sdk_token(sdk_token_request)
$sdk_token_request = new Onfido\Model\SdkTokenRequest();
$sdk_token_request->setApplicantId('<APPLICANT_ID>');
$sdk_token_request->setReferrer('https://*.example.com/example_page/*');
$api->generateSDKToken($sdk_token_request);
SdkTokenRequest sdkTokenRequest = new SdkTokenRequest();
sdkTokenRequest.setApplicantId("<APPLICANT_ID>");
sdkTokenRequest.setReferrer("https://*.example.com/example_page/*");
SdkTokenResponse sdkToken = apiInstance.generateSdkToken(sdkTokenRequest);
const sdk_token_request = new Onfido.SdkTokenRequest();
sdk_token_request.applicant_id='<APPLICANT_ID>';
sdk_token_request.referrer='https://*.example.com/example_page/*';
(async () => {
try {
const sdk_token = await api.generateSdkToken(sdk_token_request);
console.log(sdk_token);
} catch(e) {
console.log(e)
}
})();
POST
https://api.onfido.com/v2/sdk_token
Generates an SDK token.
SDK tokens are JWTs. These are restricted to an individual applicant and expire after 90 minutes, so you can safely use them in the frontend of your application.
Read more about the Onfido SDKs.
The SDK token object returned in the response is of the form: {"token":
"header.payload.signature"}
.
Request body parameters
applicant_id |
required Specifies the applicant for the SDK instance |
application_id |
required if referrer not provided The application ID (or “application bundle ID”) - used with the iOS and Android SDKs |
referrer |
required if application_id not provided The referrer URL pattern - used with the Web SDK |
Each authenticated instance of the SDK will correspond to a single Onfido
applicant as specified by the applicant_id
.
The referrer argument
The referrer argument specifies the URL of the web page where the Web SDK will be used. The referrer sent by the browser must match the referrer URL pattern in the JWT for the SDK to successfully authenticate. The referrer is based on the Google Chrome match pattern URLs. URLs can contain wild card characters.
The referrer pattern included in the JWT guarantees that other malicious websites cannot reuse the JWT in case it is lost. You can read more about referrer policy in Mozilla’s documentation.
Permitted referrer patterns are as follows:
Section | Format | Example |
---|---|---|
Referrer | scheme://host/path |
https://*.<DOMAIN>/<PATH>/* |
Scheme | * or http or https |
https |
Host | * or *. then any char except / and * |
*.<DOMAIN> |
Path | Any char or none | <PATH>/* |
An example of a valid referrer is https://*.example.com/example_page/*
.
Autofill (beta)
POST
https://api.onfido.com/v2/ocr
Autofill takes an uploaded document and returns information extracted from the document. This is a synchronous request, which means the extracted information will be presented immediately in the API response.
Return information extracted from a document
POST /v2/ocr HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"document_id": "<DOCUMENT_ID>"
}
Request body parameters
document_id | required The unique identifier of the uploaded document to run extraction on |
Extraction result
Example response (return information extracted from a document)
HTTP/1.1 201 Created
Content-Type: application/json
{
"document_id": "<DOCUMENT_ID>",
"document_classification": {
"issuing_country": "FRA",
"document_type": "national_identity_card"
},
"extracted_data": {
"date_of_birth": "1965-09-08",
"document_number": "400925733",
"first_name": "MARIE",
"gender": "Female",
"last_name": "MAVARINE",
"mrz_line1": "P<GBRDU<MARIE<<MAVARINE<<<<<<<<<<<<<<<<<<<<<",
"mrz_line2": "4009257333GBR6509088F1307072<<<<<<<<<<<<<<06",
"nationality": "BRITISH CITIZEN",
"full_name": "MAVARINE DU MARIE",
"date_of_expiry": "2013-07-07",
"middle_name": "DU",
"address_line_1": "52 RUE DES FLEURS",
"address_line_2": "33500 BORDEAUX",
"address_line_3": "FRANCE"
}
}
If data has been successfully extracted, the API response will contain the properties document_classification
and extracted_data
.
document_classification
has the following properties:
issuing_country | Document country in three-letter ISO code |
document_type | Type of document. See “Document types”. Note that only certain document types are supported by Autofill. Please contact client-support@onfido.com to find out more. |
issuing_state | The state that issued the document |
extracted_data
has the following properties:
document_number | The official document number |
first_name | First name |
last_name | Last name |
middle_name | Middle name |
full_name | Full name |
gender | Gender. Valid values are Male and Female . |
date_of_birth | Date of birth in yyyy-mm-dd format |
date_of_expiry | Date of expiry in yyyy-mm-dd format |
nationality | Nationality in three-letter ISO code |
mrz_line1 | Line 1 of the MRZ code |
mrz_line2 | Line 2 of the MRZ code |
mrz_line3 | Line 3 of the MRZ code |
address_line_1 | Line 1 of the address |
address_line_2 | Line 2 of the address |
address_line_3 | Line 3 of the address |
address_line_4 | Line 4 of the address |
address_line_5 | Line 5 of the address |
Unsuccessful extraction
Unsuccessful extraction response: classification failure
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"document_id": "<DOCUMENT_ID>",
"error": {
"type": "classification_failure",
"message": "We couldn’t recognise the type of this document."
}
}
Unsuccessful extraction response: extraction failure
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"document_id": "<DOCUMENT_ID>",
"error": {
"type": "extraction_failure",
"message": "We couldn’t extract data from this document."
}
}
If the document cannot be recognised, a classification_failure
will be returned. On the other hand, if no data can be extracted, an extraction_failure
will be returned.
Street Level code
The Street Level report sends applicants a letter with a unique verification code. This code then needs to be submitted for the address to be validated.
Submit code
Submit a street level code
POST /v2/slv HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json
{
"code": "<STREET_LEVEL_CODE>"
}
Example response (submit a street level code)
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true
}
POST
https://api.onfido.com/v2/slv
You can submit Street Level report codes to this endpoint.
Request body parameters
code | required The unique code present in the Street Level report letter |