NAV Navbar
Logo
v3
v3
v2

Getting started with API v3

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.

Or, you can skip straight to reading about testing the API.

Request, response format

You’ll find example API request headers and JSON-encoded responses in the ‘HTTP’ language tab.

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/v3/<AN_ENDPOINT> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
require 'onfido'

Onfido.configure do |config|
  config.api_key = '<YOUR_API_TOKEN>'
end

onfido = Onfido::API.new
const onfido = new Onfido({
  apiToken: "<YOUR_API_TOKEN>",
});
import onfido

configuration = onfido.Configuration()
configuration.api_key['Authorization'] = 'token=' + '<YOUR_API_TOKEN>'
configuration.api_key_prefix['Authorization'] = 'Token'

api_instance = onfido.DefaultApi(onfido.ApiClient(configuration))
$config = Onfido\Configuration::getDefaultConfiguration();
$config->setApiKey('Authorization', 'token=' . '<YOUR_API_TOKEN>');
$config->setApiKeyPrefix('Authorization', 'Token');

$onfido = new Onfido\Api\DefaultApi(
  null,
  $config
);
import com.onfido.Onfido;
import com.onfido.OnfidoException;
import com.onfido.ApiException;

Onfido onfido = Onfido.builder()
        .apiToken("<YOUR_API_TOKEN>")
        .build();

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.

  1. Create a new API token

  2. 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.

  3. Confirm your old token isn’t in use

  4. 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 can generate Mobile tokens in the Onfido Dashboard.

Errors

{
  "error": {
    "type": <TYPE>,
    "message": <MESSAGE>,
    "fields": <FIELDS - NOT ALWAYS PRESENT>
  }
}

All errors are returned in the same format (see the “HTTP” example).

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 report_names_blank:

Make sure you’ve specified report_names in your request.

422 report_names_format:

report_names must be an array of strings, not an array of objects.

422 check_type_deprecated:

type is not used in API v3. Please read about the applicant_provides_data feature.

422 document_ids_without_document_report:

You should only specify document_ids when creating a check containing a document report.

422 facial_similarity_photo_without_document:

For applicant_provides_data checks, Facial Similarity reports must be paired with Document reports.

422 facial_similarity_video_not_supported:

The Facial Similarity Video report is not supported for checks where applicant_provides_data is true.

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 object
The invalid fields and their associated errors. Only applies to validation errors

Test the API

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.

You can use the sandbox to test your technical integration with Onfido’s software and to simulate API requests. You should never upload confidential information, including personal data, to the sandbox.

To use the sandbox, you’ll need a sandbox API token.

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:

Sandbox and live differences

The key differences between the sandbox and a live environment are:

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 /v3/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/v3/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 Enhanced report)

POST /v3/checks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json

{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": ["identity_enhanced"]
}
$ curl https://api.onfido.com/v3/checks \
  -H 'Authorization: Token token=YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": ["identity_enhanced"]
}'

Pre-determined response

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "<CHECK_ID>",
  "applicant_id": "<APPLICANT_ID>",
  "created_at": "2019-05-23T13:50:33Z",
  "sandbox": true,
  "href": "/v3/checks/<CHECK_ID>",
  "applicant_provides_data": "false",
  "status": "complete",
  "result": "consider",
  "results_uri": "<RESULTS_URI>",
  "redirect_uri": null,
  "report_ids": [
    "<REPORT_ID>"
  ]
}

To help you test your integration, you can trigger pre-determined responses from the API using specific applicant last names:

ReportApplicant last nameReport result
Identity Enhancedconsiderconsider
Documentconsiderconsider
Watchlist Standardconsiderconsider
Watchlist Enhancedconsiderconsider
Facial Similarity Photoconsiderconsider
Right to Workconsiderconsider

All normal applicant attribute requirements apply when you create any sandbox check.

Pre-determined responses for multiple-report checks


Create a check (Watchlist Standard report to return ‘consider’ result)

POST /v3/checks HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json

{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": [
    "watchlist_standard",
    "identity_standard"
  ],
  "consider": [
    "watchlist_standard"
  ]
}
$ curl https://api.onfido.com/v3/checks \
  -H 'Authorization: Token token=YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": [
    "watchlist_standard",
    "identity_standard"
  ],
  "consider": [
    "watchlist_standard"
  ]
}'

Pre-determined response (report retrieval for Watchlist Standard report in previous example)

HTTP/1.1 201 Created
Content-Type: application/json

{
    "created_at": "2020-01-20T15:58:23Z",
    "href": "/v3/reports/<REPORT_ID>",
    "id": "<REPORT_ID>",
    "name": "watchlist_standard",
    "properties": {
        "records": [
            {
                "associates": "",
                "keywords": "secretary",
                "last_updated_utc": "2016-07-01T04:16:46Z",
                "entity_type": "person",
                "sources": "PEPs list",
                "types": "pep, pep-class-2",
                "name": "JohnJoeDoe",
                "external_id": "",
                "match_types": "fuzzy",
                "related_urls": "",
                "picture_urls": "",
                "all_dobs": "",
                "entity_fields_countries": "UnitedKingdom",
                "report_id": 123
            },
            {
                "associates": "",
                "keywords": "judiciary",
                "last_updated_utc": "2016-02-01T23:48:54Z",
                "entity_type": "person",
                "sources": "PEPs list",
                "types": "warning",
                "name": "JimmyJoeDoe",
                "external_id": "",
                "match_types": "fuzzy",
                "related_urls": "",
                "picture_urls": "",
                "all_dobs": "",
                "entity_fields_countries": "UnitedKingdom",
                "report_id": 123
            },
            {
                "associates": "JayJayDoe, Doe,JayandJeanne, Doe,JamesandMary",
                "keywords": "",
                "last_updated_utc": "2016-08-12T14:17:34Z",
                "entity_type": "person",
                "sources": "PEPs list",
                "types": "pep, pep-class-1",
                "name": "JamesDoe",
                "external_id": "",
                "match_types": "fuzzy",
                "related_urls": "",
                "picture_urls": "",
                "all_dobs": "",
                "report_id": 123
            }
        ]
    },
    "result": "consider",
    "status": "complete",
    "sub_result": null,
    "breakdown": {
        "sanction": {
            "result": "clear"
        },
        "politically_exposed_person": {
            "result": "consider"
        },
        "legal_and_regulatory_warnings": {
            "result": "consider"
        }
    },
    "check_id": "<CHECK_ID>",
    "documents": []
}

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”.

Sample document, photo

You can use the following files for running test checks:

Postman

You can run the Onfido API version 3 collection in Postman:

Run in Postman

The API version 3 Postman collection is at version 1.1.

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.

Go live

Before you go live, you can test your integration in the sandbox environment.

  1. Add billing information:

    Live checks cannot be requested without valid billing information, so please add billing information to your account via the Onfido Dashboard.

  2. 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’.

  3. Use the live API token:

    Update your production system to use the live token.

  4. 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

The tips below are some simple suggestions to help reduce the possibility of being rate limited. We recommend:

Client libraries

You can use our supported client libraries to integrate with the Onfido API.

Please email api@onfido.com if you write your own library and would like us to link to it, or if you have any feedback about our OpenAPI specification.

Ruby

Use the onfido-ruby library.

Java

Use the onfido-java library.

JavaScript (Node.js)

Use the onfido-node library.

Python

Use the api-python-client library.

PHP

Use the api-php-client library.

OpenAPI specification

We use an OpenAPI specification to generate our Python and PHP libraries for API v3. We host the specification on GitHub.

Regions

Change the region to ‘US’

$ curl https://api.us.onfido.com/v3/
Onfido.configure do |config|
  config.region = 'us'
end
const onfido = new Onfido({
  apiToken: "<YOUR_API_TOKEN>",
  region: Region.US
});
$config->setHost($config->getHostFromSettings(1, array("region" => "us")));
configuration.host = configuration.get_host_from_settings(1, {'region': 'us'})
Onfido onfido = Onfido.builder()
                .apiToken(<YOUR_API_TOKEN_HERE>)
                .regionUS()
                .build();

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.

For the ‘EU’ region: data is physically stored in the Republic of Ireland, with backup storage in Germany.

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.

Versioning

Backwards compatibility

The following changes are considered backwards compatible:

Changelog

2020-05-04 Updated documentation on verifying webhook signatures.
2020-04-07 Added documentation on the Facial Similarity Photo Fully Auto report.
2020-03-12 Added documentation on the Known Faces report (beta).
2020-03-09 Updated Java code examples to use the onfido-java client library.
2020-01-13 General release of API version 3

Applicants


About applicants

An applicant represents an individual who will be the subject of a check. 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": "2019-10-09T16:52:42Z",
  "sandbox": true,
  "first_name": "Jane",
  "last_name": "Doe",
  "email": null,
  "dob": "1990-01-01",
  "delete_at": null,
  "href": "/v3/applicants/<APPLICANT_ID>",
  "id_numbers": [],
  "address": {
    "flat_number": null,
    "building_number": null,
    "building_name": null,
    "street": "Second Street",
    "sub_street": null,
    "town": "London",
    "state": null,
    "postcode": "S2 2DF",
    "country": "GBR",
    "line1": null,
    "line2": null,
    "line3": null
  }
}
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
first_name string
The applicant’s first name
last_name string
The applicant’s surname
email string
The applicant’s email address
dob date
The applicant’s date of birth in yyyy-mm-dd format
id_numbers array of id number objects
A collection of identification numbers belonging to this applicant
address address object
The address 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_licence
value string
Value of ID number
Note that ssn supports both the full SSN or the last 4 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 object

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 postcodes, 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
line1 string
Line 1 of the address
line2 string
Line 2 of the address
line3 string
Line 3 of the address

The applicant address object is nested inside the address object.

postcode and country are required fields if an address is provided for an applicant. For US addresses, state is also a required field.

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 /v3/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",
  "address": {
    "building_number": "100",
    "street": "Main Street",
    "town": "London",
    "postcode": "SW4 6EH",
    "country": "GBR"
  }
}
$ curl https://api.onfido.com/v3/applicants/ \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "first_name": "Jane",
  "last_name": "Doe",
  "dob": "1990-01-31",
  "address": {
    "building_number": "100",
    "street": "Main Street",
    "town": "London",
    "postcode": "SW4 6EH",
    "country": "GBR"
  }
}'
applicant_details = {
  first_name: "Jane",
  last_name: "Doe",
  dob: "1990-01-01",
  address: {
    building_number: "100",
    street: "Second Street",
    town: "London",
    postcode: "S2 2DF",
    country: "GBR"
  }
}

onfido.applicant.create(applicant_details)
const newApplicant = await onfido.applicant.create({
  firstName: "Jane",
  lastName: "Doe",
  dob: "1990-01-31",
  address: {
    postcode: "S2 2DF",
    country: "GBR"
  }
});
applicant_address = onfido.Address(
    building_number=100,
    street='Main Street',
    town='London',
    postcode='SW4 6EH',
    country='GBR'
)

applicant_details = onfido.Applicant(
    first_name='Jane',
    last_name='Doe',
    address=applicant_address
)

api_instance.create_applicant(applicant_details)
$applicantDetails = new Onfido\Model\Applicant();

$applicantDetails->setFirstName('Jane');
$applicantDetails->setLastName('Doe');
$applicantDetails->setDob('1990-01-31');

$address = new \Onfido\Model\Address();
$address->setBuildingNumber('100');
$address->setStreet('Main Street');
$address->setTown('London');
$address->setPostcode('SW4 6EH');
$address->setCountry('GBR');

$applicantDetails->setAddress($address);

$onfido->createApplicant($applicantDetails);
import com.onfido.models.Address;
import com.onfido.models.Applicant;

Address.Request addressRequest = Address.request()
        .street("Main Street")
        .town("London")
        .postcode("SW4 6EH")
        .country("GBR");

Applicant.Request applicantRequest = Applicant.request()
        .firstName("Jane")
        .lastName("Doe")
        .dob(LocalDate.parse("1990-01-31"))
        .address(addressRequest);

Applicant applicant = onfido.applicant.create(applicantRequest);

POST https://api.onfido.com/v3/applicants/

Creates a single applicant. Returns an applicant object.

When you create an applicant, some characters are forbidden.

Required applicant data differs depending on report type. For example, for Document reports.

Request body parameters

first_name required
The applicant’s forename.
last_name required
The applicant’s surname.
email required only if creating a check where applicant_provides_data is true
The applicant’s email address.
dob optional
The applicant’s date of birth in yyyy-mm-dd format.
id_numbers optional
A collection of identification numbers belonging to this applicant
address optional
The address of the applicant

Retrieve applicant

Retrieve an applicant

GET /v3/applicants/<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/applicants/<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
onfido.applicant.find('<APPLICANT_ID>')
const applicant = await onfido.applicant.find("<APPLICANT_ID>");
api_instance.find_applicant('<APPLICANT_ID>')
$onfido->findApplicant('<APPLICANT_ID>');
import com.onfido.models.Applicant;

String applicantId = "<APPLICANT_ID>";

Applicant applicant = onfido.applicant.find(applicantId);

GET https://api.onfido.com/v3/applicants/{applicant_id}

Retrieves a single applicant. Returns an applicant object.

Update applicant

Update an applicant

PUT /v3/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/v3/applicants/<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "first_name": "New",
  "last_name": "Name"
}' \
  -X PUT
new_applicant_details = {
  first_name: "New",
  last_name: "Name"
}

onfido.applicant.update('<APPLICANT_ID>', new_applicant_details)
const updatedApplicant = await onfido.applicant.update("<APPLICANT_ID>", {
  firstName: "New",
  lastName: "Name"
});
new_applicant_details = onfido.Applicant()

new_applicant_details.first_name = 'New'
new_applicant_details.last_name = 'Name'

api_instance.update_applicant('<APPLICANT_ID>', new_applicant_details)
$newApplicantDetails = new Onfido\Model\Applicant();
$newApplicantDetails->setFirstName('New');

$onfido->updateApplicant('<APPLICANT_ID>', $newApplicantDetails);
import com.onfido.models.Applicant;

Applicant.Request newApplicantDetails = Applicant.request()
        .firstName("New")
        .lastName("Name");

String applicantId = "<APPLICANT_ID>";

Applicant applicant = onfido.applicant.update(applicantId, newApplicantDetails);

PUT https://api.onfido.com/v3/applicants/{applicant_id}

Updates an applicant’s information. Returns the updated applicant object.

Request body parameters

first_name The applicant’s forename.
last_name The applicant’s surname.
email The applicant’s email address.
dob The applicant’s date of birth in yyyy-mm-dd format.
id_numbers A collection of identification numbers belonging to this applicant.
address The address of the applicant.

Delete applicant

Delete an applicant

DELETE /v3/applicants/<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/applicants/<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X DELETE
onfido.applicant.destroy('<APPLICANT_ID>')
await onfido.applicant.delete("<APPLICANT_ID>");
api_instance.destroy_applicant('<APPLICANT_ID>')
$onfido->destroyApplicant('<APPLICANT_ID>');
import com.onfido.models.Applicant;

String applicantId = "<APPLICANT_ID>";

onfido.applicant.delete(applicantId);

DELETE https://api.onfido.com/v3/applicants/{applicant_id}

Deletes a single applicant. If successful, returns a 204 No Content response.

Sending a deletion request adds the applicant object and all associated documents, photos, videos, checks, reports and analytics data to our deletion queue. The objects will be permanently deleted from Onfido’s production object storage and relational database system, after a deletion delay which can be configured by emailing our client support team. After deletion, applicant details cannot be recovered or queried, and Onfido will not be able to troubleshoot. Within the delay period, the applicant can be restored. For more information about Onfido’s deletion service, see our Data Deletion FAQ.

Restore applicant

Restore an applicant

POST /v3/applicants/<APPLICANT_ID>/restore HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/applicants/<APPLICANT_ID>/restore \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X POST
onfido.applicant.restore('<APPLICANT_ID>')
await onfido.applicant.restore("<APPLICANT_ID>");
api_instance.restore_applicant('<APPLICANT_ID>')
$onfido->restoreApplicant('<APPLICANT_ID>');
import com.onfido.models.Applicant;

String applicantId = "<APPLICANT_ID>";

onfido.applicant.restore(applicantId);

POST https://api.onfido.com/v3/applicants/{applicant_id}/restore

Restores a single applicant scheduled for deletion. If successful, returns a 204 No Content response.

A restore request will also restore all associated documents, photos, videos, checks, reports and analytics data.

Applicants that have been permanently deleted cannot be restored.

List applicants

Return all applicants you’ve created

GET /v3/applicants/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/applicants/ \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
onfido.applicant.all(page: 1, per_page: 20)
const applicants = await onfido.applicant.list();
api_instance.list_applicants(page=1, per_page=20, include_deleted=True)
$onfido->listApplicants();
import com.onfido.models.Applicant;

Integer page = 1;
Integer perPage = 20;
Boolean includeDeleted = false; 

List<Applicant> applicants = onfido.applicant.list(page, perPage, includeDeleted);

GET https://api.onfido.com/v3/applicants/

Lists 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.

The Link header contains pagination information. For example:

Link: <https://api.onfido.com/v3/applicants?page=3059>; rel="last", <https://api.onfido.com/v3/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


About documents

In the Onfido API, documents belong to a single applicant, so they must be uploaded after an applicant has been created.

Some reports require identity documents in order to be processed successfully. For example, Document reports.

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,
  "applicant_id": "<APPLICANT_ID>",
  "href": "/v3/documents/<DOCUMENT_ID>",
  "download_href": "/v3/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.
applicant_id string
The id of the applicant to whom the document belongs.

Document types

Identity documents

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

For some document types, both sides are required for processing.

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 /v3/documents/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: multipart/form-data
$ curl https://api.onfido.com/v3/documents \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -F 'type=passport' \
  -F 'file=@path/to/passport.png;type=image/png' \ 
  -F 'applicant_id=<APPLICANT_ID>'
applicant_id = '<APPLICANT_ID>'
file = File.new('path/to/passport.png')
type = 'passport'

onfido.document.create(applicant_id: applicant_id, file: file, type: type)
const document = await onfido.document.upload({
  applicantId: "<APPLICANT_ID>",
  file: fs.createReadStream("path/to/passport.png"),
  type: "passport"
});
applicant_id = '<APPLICANT_ID>'
sample_file = 'path/to/passport.png'
document_type = 'passport'

api_instance.upload_document(applicant_id, document_type, sample_file)
$applicantId = '<APPLICANT_ID>';
$type = 'passport';
$file = 'path/to/passport.png';
$side = null;

$onfido->uploadDocument($applicantId, $type, $file, $side);
import com.onfido.models.Document;

InputStream is = new FileInputStream("/path/to/passport.png");

Document.Request documentRequest = Document.request()
        .applicantId("<APPLICANT_ID>")
        .issuingCountry("GBR")
        .side("front")
        .type("passport");

Document document = onfido.document.upload(is, "<FILE_NAME>.png", documentRequest);

POST https://api.onfido.com/v3/documents/

Uploads a document as part of a multipart request. Returns a document object.

We provide a sample document to test this endpoint.

Valid file formats for documents are jpg, png and pdf. The file size must be between 32KB and 10MB.

Request body parameters

applicant_id required
The ID of the applicant who owns the document
file required
The file to be uploaded
type required
The type of document. For example, passport
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 /v3/documents/<DOCUMENT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/documents/<DOCUMENT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
document_id = '<DOCUMENT_ID>'

onfido.document.find(document_id)
const documentId = "<DOCUMENT_ID>";

const document = await onfido.document.find(documentId);
document_id = '<DOCUMENT_ID>'

api_instance.find_document(document_id)
$documentId = '<DOCUMENT_ID>';

$onfido->findDocument($document_id);
import com.onfido.models.Document;

String documentId = "<DOCUMENT_ID>";

Document document = onfido.document.find(documentId);

GET https://api.onfido.com/v3/documents/{document_id}

Retrieves a single document. Returns the corresponding document object.

List documents

List all documents for a specific applicant

GET /v3/documents?applicant_id=<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/documents?applicant_id=<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'

onfido.document.all(applicant_id)
const applicantId = "<APPLICANT_ID>";

const documents = await onfido.document.list(applicantId);
applicant_id = '<APPLICANT_ID>'

api_instance.list_documents(applicant_id)
$applicantId = '<APPLICANT_ID>';

$onfido->listDocuments($applicant_id);
import com.onfido.models.Document;

String applicantId = "<APPLICANT_ID>";

List<Document> documents = onfido.document.list(applicantId);

GET https://api.onfido.com/v3/documents?applicant_id={applicant_id}

Lists all documents belonging to an applicant.

Returns data in the form: {"documents": [<LIST_OF_DOCUMENT_OBJECTS>]}.

Query string parameters

applicant_id (required): the ID of the applicant ID whose documents you want to list.

Download document

Download a document associated with an applicant

GET /v3/documents/<DOCUMENT_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/documents/<DOCUMENT_ID>/download \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
document_id = '<DOCUMENT_ID>'

onfido.document.download(document_id)
const documentId = "<DOCUMENT_ID>";

const documentDownload = await onfido.document.download(documentId);
import com.onfido.models.Document;

String documentId = "<DOCUMENT_ID>";

FileDownload fileDownload = onfido.document.download(documentId);

GET https://api.onfido.com/v3/documents/{document_id}/download

Downloads specific documents belong to an applicant.

If successful, the response will be the binary data representing the image.

Live photos


About live photos

In the Onfido API, “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 checks with Facial Similarity Photo reports 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": "2019-10-09T16:59:06Z",
  "file_name": "<FILE_NAME>.png",
  "file_type": "image/png",
  "file_size": 536630,
  "href": "/v3/live_photos/<LIVE_PHOTO_ID>",
  "download_href": "/v3/live_photos/<LIVE_PHOTO_ID>/download"
}
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 /v3/live_photos/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: multipart/form-data
$ curl https://api.onfido.com/v3/live_photos/ \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -F 'applicant_id=<APPLICANT_ID>' \
  -F 'file=@path/to/sample_photo.png;type=image/png'
file = File.new('path/to/sample_photo.png')

applicant_id = '<APPLICANT_ID>'

onfido.live_photo.create(applicant_id: applicant_id, file: file)
const livePhoto = await onfido.livePhoto.upload({
  applicantId: "<APPLICANT_ID>",
  file: fs.createReadStream("/path/to/sample_photo.png")
});
sample_photo = 'path/to/sample_photo.png'

applicant_id = '<APPLICANT_ID>'

api_instance.upload_live_photo(applicant_id, sample_photo)
$applicantId = '<APPLICANT_ID>';
$file = 'path/to/sample_photo.png';

$onfido->uploadLivePhoto($applicantId, $file)
import com.onfido.models.LivePhoto;

InputStream is = new FileInputStream("/path/to/livephoto.png");

LivePhoto.Request livePhotoRequest = LivePhoto.request()
        .applicantId("<APPLICANT_ID>");

LivePhoto livePhoto = onfido.livePhoto.upload(is, "<FILE_NAME>.png", livePhotoRequest);

POST https://api.onfido.com/v3/live_photos/

Uploads a live photo as part of a multipart request. Returns a live photo object.

We provide a sample photo to test this endpoint.

Valid file formats for live photos 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 /v3/live_photos/<LIVE_PHOTO_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_photos/<LIVE_PHOTO_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
live_photo_id = '<LIVE_PHOTO_ID>'

onfido.live_photo.find(live_photo_id)
const livePhotoId = "<LIVE_PHOTO_ID>";

const livePhoto = await onfido.livePhoto.find(livePhotoId);
live_photo_id = '<LIVE_PHOTO_ID>'

api_instance.find_live_photo(live_photo_id)
$livePhotoId = '<LIVE_PHOTO_ID>';

$onfido->findLivePhoto($livePhotoId);
import com.onfido.models.LivePhoto;

String livePhotoId = "<LIVE_PHOTO_ID>";

LivePhoto livePhoto = onfido.livePhoto.find(livePhotoId);

GET https://api.onfido.com/v3/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 /v3/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/v3/live_photos?applicant_id=<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'

onfido.live_photo.all(applicant_id)
const applicantId = "<APPLICANT_ID>";

const livePhotos = await onfido.livePhoto.list(applicantId);
applicant_id = '<APPLICANT_ID>'

api_instance.list_live_photos(applicant_id)
$applicantId = '<APPLICANT_ID>';

$onfido->listLivePhotos($applicantId);
import com.onfido.models.LivePhoto;

String applicantId = "<APPLICANT_ID>";

List<LivePhoto> livePhotos = onfido.livePhoto.list(applicantId);

GET https://api.onfido.com/v3/live_photos/?applicant_id={applicant_id}

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 /v3/live_photos/<LIVE_PHOTO_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_photos/<LIVE_PHOTO_ID>/download HTTP/1.1 \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
onfido.live_photo.download('<LIVE_PHOTO_ID>')
const livePhotoDownload = await onfido.livePhoto.download("<LIVE_PHOTO_ID>");
import com.onfido.models.LivePhoto;

String livePhotoId = "<LIVE_PHOTO_ID>";

FileDownload fileDownload = onfido.livePhoto.download(livePhotoId);

GET https://api.onfido.com/v3/live_photos/{live_photo_id}/download

Downloads a live photo.

If successful, the response will be the binary data representing the image.

Live videos


About live videos

In the Onfido platform, “live videos” are footage of the applicant’s face, recorded and uploaded by the Onfido SDKs (iOS, Android or Web), at the same time as the document image is captured - also by the SDK. These videos are used to perform Facial Similarity Video checks 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": "/v3/live_videos/<LIVE_VIDEO_ID>",
  "download_href": "/v3/live_videos/<LIVE_VIDEO_ID>/download",
  "file_name": "<FILE_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 2 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 3 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 object
Challenge the end user was asked to perform during the video recording

Retrieve live video

Retrieve a single live video’s object

GET /v3/live_videos/<LIVE_VIDEO_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_videos/<LIVE_VIDEO_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
live_video_id = '<LIVE_VIDEO_ID>'

api_instance.find_live_video(live_video_id)
$liveVideoId = '<LIVE_VIDEO_ID>';

$onfido->findLiveVideo($liveVideoId);
import com.onfido.models.LiveVideo;

String liveVideoId = "<LIVE_VIDEO_ID>";

LiveVideo liveVideo = onfido.liveVideo.find(liveVideoId);

GET https://api.onfido.com/v3/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 /v3/live_videos?applicant_id=<APPLICANT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_videos?applicant_id=<APPLICANT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'

api_instance.list_live_videos(applicant_id)
$applicantId = '<APPLICANT_ID>';

$onfido->listLiveVideos($applicantId);
import com.onfido.models.LiveVideo;

String applicantId = "<APPLICANT_ID>";

List<LiveVideo> liveVideos = onfido.liveVideo.list(applicantId);

GET https://api.onfido.com/v3/live_videos?applicant_id={applicant_id}

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 /v3/live_videos/<LIVE_VIDEO_ID>/download HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_videos/<LIVE_VIDEO_ID>/download \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
import com.onfido.models.LiveVideo;

liveVideoId = "<LIVE_VIDEO_ID>";

FileDownload fileDownload = onfido.liveVideo.download(liveVideoId);

GET https://api.onfido.com/v3/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 /v3/live_videos/<LIVE_VIDEO_ID>/frame HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/live_videos/<LIVE_VIDEO_ID>/frame \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
import com.onfido.models.LiveVideo;

String liveVideoId = "<LIVE_VIDEO_ID>";

FileDownload fileDownload = onfido.liveVideo.download(liveVideoId);

GET https://api.onfido.com/v3/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.

For best results, you should use this endpoint only after the Facial Similarity Video report has completed.

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


About checks

Checks are performed on an applicant. Depending on the type of check you wish to perform, different information will be required when you create an applicant. A check consists of one or more reports.

Applicant provides data

If you need applicants to fill out the Onfido applicant form as part of your checks, you can pass the following Boolean as part of your check request:

"applicant_provides_data": "true"

By default, this is set to false.

Check object

An example check object

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "<CHECK_ID>",
  "created_at": "2019-10-09T17:01:59Z",
  "status": "in_progress",
  "redirect_uri": null,
  "result": null,
  "sandbox": true,
  "tags": [],
  "results_uri": "<RESULTS_URI>",
  "form_uri": null,
  "paused": false,
  "version": "3.0",
  "report_ids": [
    "<REPORT_ID>"
  ],
  "href": "/v3/checks/<CHECK_ID>",
  "applicant_id": "<APPLICANT_ID>",
  "applicant_provides_data": false
}

The check object is used to track the type and status of a check.

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.
applicant_provides_data boolean
Run a applicant_provides_data check or not. Default is false.
applicant_id string
The ID for the applicant associated with the check.
status string
The current state of the check in the checking process.
tags array of strings
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.
form_uri string
A link to the applicant form, if applicant_provides_data is true.
redirect_uri string
For checks where applicant_provides_data is true, 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
report_ids array of strings
The list of report object ids 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 /v3/checks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json

{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": [
    "document",
    "facial_similarity_photo"
  ]
}
$ curl https://api.onfido.com/v3/checks \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "applicant_id": "<APPLICANT_ID>",
  "report_names": ["document", "facial_similarity_photo"]
}'
applicant_id = '<APPLICANT_ID>'

onfido.check.create(applicant_id: applicant_id, report_names: ['document', 'facial_similarity_photo'])
const applicantId = "<APPLICANT_ID>";

const newCheck = await onfido.check.create({
  applicantId,
  reportNames: ["document", "facial_similarity_photo"]
});
applicant_id = '<APPLICANT_ID>'

check_data = onfido.Check()
check_data.applicant_id = applicant_id 
check_data.report_names = ['document', 'facial_similarity_photo']

api_instance.create_check(check_data)
$applicantId = '<APPLICANT_ID>';

$checkData = new Onfido\Model\Check();
$checkData->setApplicantId($applicantId);
$checkData->setReportNames(array('document', 'facial_similarity_photo'));

$onfido->createCheck($check_data);
import com.onfido.models.Check;

Check.Request checkRequest = Check.request()
        .applicantId("<APPLICANT_ID>")
        .reportNames("document", "facial_similarity_photo");

Check check = onfido.check.create(checkRequest);

POST https://api.onfido.com/v3/checks/

Initiates a check for an applicant, which can contain one or more reports. Returns a check object.

When creating checks, you must use the report_names field (which takes an array of strings). For example, to create a check with 2 reports:

"report_names": ["report_name_1", "report_name_2"]

Read more about checks in the Onfido API.

You can read more about individual reports in the “Report Types” section of this documentation (using the left-hand navigation).

Request body parameters

applicant_id required
The ID of the applicant to run the check on.
report_names required
Array of strings describing reports requested for the check.
document_ids optional
Array of strings describing which document to process in a Document Report check creation.
applicant_provides_data optional
Default is false. If true, applicant provides required information and documents using the Onfido applicant form.
asynchronous optional
Default is true. If set to false, the request to create a check will only return a response when all reports are complete, or the request times out after 55 seconds. You can configure webhooks to notify you when a report is complete.
tags optional
Array of tags being assigned to this check.
suppress_form_emails optional
For checks where applicant_provides_data is true, applicant form will not be automatically sent if suppress_form_email is 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).
redirect_uri optional
For checks where applicant_provides_data is true, redirect to this URI when the applicant has submitted their data.
consider optional
Array of names of particular reports to return consider as their results. This is a feature available in sandbox testing which you can read more about.

Report names in API

Pass the following as strings in the report_names array in check creation requests:

API report name(s)
Document document
Facial Similarity facial_similarity_photo
facial_similarity_photo_fully_auto
facial_similarity_video
Known Faces (beta) known_faces
Identity identity_enhanced
Watchlist watchlist_enhanced
watchlist_standard
watchlist_peps_only
watchlist_sanctions_only
Proof of Address proof_of_address
Right to Work right_to_work

Retrieve check

Retrieve a single check

GET /v3/checks/<CHECK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/checks/<CHECK_ID> \
  -H 'Authorization: Token token=YOUR_API_TOKEN'
check_id = '<CHECK_ID>'

onfido.check.find(check_id)
const checkId = "<CHECK_ID>";

const check = await onfido.check.find(checkId);
check_id = '<CHECK_ID>'

api_instance.find_check(check_id)
$checkId = '<CHECK_ID>';

$onfido->findCheck($checkId);
import com.onfido.models.Check;

String checkId = "<CHECK_ID>";

Check check = onfido.check.find(checkId);

GET https://api.onfido.com/v3/checks/{check_id}

Retrieves a single check. Returns a check object.

List checks

List all checks associated with an applicant

GET /v3/checks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/checks/ \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
applicant_id = '<APPLICANT_ID>'

onfido.check.all(applicant_id)
const applicantId = "<APPLICANT_ID>";

const checks = await onfido.check.list(applicantId);
applicant_id = '<APPLICANT_ID>'

api_instance.list_checks(applicant_id)
$applicantId = '<APPLICANT_ID>';

$onfido->listChecks($applicantId);
import com.onfido.models.Check;

String applicantId = "<APPLICANT_ID>";

List<Check> checks = onfido.check.list(applicantId);

GET https://api.onfido.com/v3/checks/

Returns all checks for an applicant.

Returns data in the form: {"checks": [<LIST_OF_CHECK_OBJECTS>]}.

Query string parameters

applicant_id (required): the ID of the applicant whose checks you want to list.

Resume check

Resume a paused check

GET /v3/checks/<CHECK_ID>/resume HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/checks/<CHECK_ID>/resume
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X POST
check_id = '<CHECK_ID>'

onfido.check.resume(check_id)
const checkId = "<CHECK_ID>";

await onfido.check.resume(checkId);
check_id = '<CHECK_ID>'

api_instance.resume_check(check_id)
$checkId = '<CHECK_ID>';

$onfido->resumeCheck($checkId);
import com.onfido.models.Check;

String checkId = "<CHECK_ID>";

onfido.check.resume(checkId);

POST https://api.onfido.com/v3/checks/{check_id}/resume

Resumes a paused check. If successful, returns a 204 No Content response.

A check is paused if all the reports that it contains are in the paused state.

When a check where applicant_provides_data is true 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


About reports

In the Onfido API, checks are composed of one or more reports. You can read about specific reports in the “Report Types” section in this documentation. For example, for Document reports.

Report object

The report object will differ depending on which report it concerns (see “About reports” above).

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 the “Report Types” section of this documentation
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 (null if report is incomplete)
sub_result string
The sub_result of the report. It gives a more detailed result for Document reports only, and will be null otherwise
breakdown object
The details of the report. This is specific to each type of report
properties object
The properties associated with the report, if any
documents array
The document IDs that were processed. Populated for Document reports, otherwise an empty array.
check_id array
The ID of the check to which the report belongs.

The breakdown object differs for each report type. For example, 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.

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 /v3/reports/<REPORT_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/reports/<REPORT_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
report_id = '<REPORT_ID>'

onfido.report.find(report_id)
const reportId = "<REPORT_ID>";

const report = await onfido.report.find(reportId);
report_id = '<REPORT_ID>'

api_instance.find_report(report_id)
$reportId = '<REPORT_ID>';

$onfido->findReport($reportId);
import com.onfido.models.Report;

String reportId = "<REPORT_ID>";

Report report = onfido.report.find(reportId);

GET https://api.onfido.com/v3/reports/{report_id}

Retrieves a single report. Returns a report object.

List reports

List all reports associated with a check

GET /v3/reports?check_id=<CHECK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/reports?check_id=<CHECK_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
check_id = '<CHECK_ID>'

onfido.report.all(check_id)
const checkId = "<CHECK_ID>";

const reports = await onfido.report.list(checkId);
check_id = '<CHECK_ID>'

api_instance.list_reports(check_id)
$checkId = '<CHECK_ID>';

$onfido->listReports($checkId);
import com.onfido.models.Report;

String checkId = "<CHECK_ID>";

List<Report> reports = onfido.report.list(checkId);

GET https://api.onfido.com/v3/reports?check_id={check_id}

Lists all reports belonging to a particular check.

Returns data in the form: {"reports": [<LIST_OF_REPORT_OBJECTS>]}.

Query string parameters

check_id (required): the ID of the check whose reports you want to list.

Resume report

Resume a single paused report

POST /v3/reports/<REPORT_ID>/resume HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/reports/<REPORT_ID>/resume \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X POST
report_id = '<REPORT_ID>'

onfido.report.resume(report_id)
const reportId = "<REPORT_ID>";

await onfido.report.resume(reportId);
report_id = '<REPORT_ID>'

api_instance.resume_report(report_id)
$reportId = '<REPORT_ID>';

$onfido->resumeReport($reportId);
import com.onfido.models.Report;

String reportId = "<REPORT_ID>";

onfido.report.resume(reportId);

POST https://api.onfido.com/v3/reports/{report_id}/resume

Resumes a single paused report. If successful, returns a 204 No Content response.

When an individual report gets resumed in a check where applicant_provides_data is true, 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 /v3/reports/<REPORT_ID>/cancel HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/reports/<REPORT_ID>/cancel \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X POST
report_id = '<REPORT_ID>'

onfido.report.cancel(report_id)
const reportId = "<REPORT_ID>";

await onfido.report.cancel(reportId);
report_id = '<REPORT_ID>'

api_instance.cancel_report(report_id)
$reportId = '<REPORT_ID>';

$onfido->cancelReport($reportId);
import com.onfido.models.Report;

String reportId = "<REPORT_ID>";

onfido.report.cancel(reportId);

POST https://api.onfido.com/v3/reports/{report_id}/cancel

Cancels single paused reports. If successful, returns a 204 No Content response.

When a report gets cancelled in a check where applicant_provides_data is true, its status will change from paused to cancelled and the report will never get processed.

Document report

An example Document report object (UK passport)

HTTP/1.1 201 Created
Content-Type: application/json

{
  "created_at": "2019-10-03T14:05:48Z",
  "documents": [
    {
      "id": "<DOCUMENT_ID>"
    }
  ],
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "document",
  "properties": {
    "nationality": "",
    "last_name": "Names",
    "issuing_country": "GBR",
    "gender": "",
    "first_name": "Report",
    "document_type": "passport",
    "document_numbers": [
      {
        "value": "123456789",
        "type": "document_number"
      }
    ],
    "date_of_expiry": "2030-01-01",
    "date_of_birth": "1990-01-01"
  },
  "result": "clear",
  "status": "complete",
  "sub_result": "clear",
  "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": {}
        }
      }
    },
    "age_validation": {
      "result": "clear",
      "breakdown": {
        "minimum_accepted_age": {
          "result": "clear",
          "properties": {}
        }
      }
    },
    "image_integrity": {
      "result": "clear",
      "breakdown": {
        "image_quality": {
          "result": "clear",
          "properties": {}
        },
        "conclusive_document_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"
    },
    "compromised_document": {
      "result": "clear"
    }
  },
  "check_id": "<CHECK_ID>"
}

To request a Document report as part of a check in the API, use the report_names field (which takes an array of strings):

"report_names": ["document"]

By default, the most recently uploaded document will be used.

To specify which uploaded document to run the Document report against in the API, use the document_ids field (which takes an array of strings):

"document_ids": ["<DOCUMENT_ID>"]

The Document report is composed of data integrity, visual authenticity and police record checks. It checks the internal and external consistency of the 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.

Document report object

We host a separate page which contains a detailed description of the Document report object.

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:

Breakdown descriptions and logic

Breakdown Properties

We will return a reason whenever a report flags for one of the following breakdowns:

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 2 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 3 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)

digital_document - When a document has been published digitally, there aren’t enough security features to review so we cannot perform a full fraud assessment

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

scan - When the document has clearly been captured using a scanner and there are visible indicators of this, e.g. unusual shadows on the edges of the document, or written text around the document

Breakdowns which map to caution

Breakdowns which map to suspected

Breakdowns which map to rejected

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:

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 reports

There are 3 different types of Facial Similarity report:

Report name Request body in API
Photo "report_names": ["facial_similarity_photo"]
Photo Fully Auto "report_names": ["facial_similarity_photo_fully_auto"]
Video "report_names": ["facial_similarity_video"]

The report_names field takes an array of strings.

All Facial Similarity reports will compare the most recent photo or 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.

Required applicant data

For all Facial Similarity report types, first_name and last_name must be provided but can be dummy values if you don’t know an applicant’s name.

Photo

An example Facial Similarity Photo object

HTTP/1.1 200 OK
Content-Type: application/json

{
  "created_at": "2019-12-11T09:39:05Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "facial_similarity_photo",
  "properties": {},
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "face_comparison": {
      "result": "clear",
      "breakdown": {
        "face_match": {
          "result": "clear",
          "properties": {
            "score": 0.6512
          }
        }
      }
    },
    "image_integrity": {
      "result": "clear",
      "breakdown": {
        "face_detected": {
          "result": "clear",
          "properties": {}
        },
        "source_integrity": {
          "result": "clear",
          "properties": {}
        }
      }
    },
    "visual_authenticity": {
      "result": "clear",
      "breakdown": {
        "spoofing_detection": {
          "result": "clear",
          "properties": {
            "score": 0.9512
          }
        }
      }
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

The Facial Similarity Photo report uses a live photo. 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 Photo: Object

The following table describes the unique fields returned in the Onfido API (v3) for a completed Facial Similarity Photo report:

Attribute Format Possible values
result String "clear", "consider"
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
(sub-breakdown) face_match* String or null "clear", "consider", null
visual_authenticity String or null "clear", "consider", null
(sub-breakdown) spoofing_detection* String or null "clear", "consider", null

Facial Similarity Photo: Breakdowns

image_integrity object
Asserts whether the quality and integrity of the uploaded files were sufficient to perform a face comparison
(sub-breakdown) face_detected object
Asserts a single face of good enough quality has been found in both the document image and the live photo
(sub-breakdown) source_integrity object
Asserts whether the live photo is trustworthy - i.e. not digitally tampered, from a fake webcam, or from other dubious sources
face_comparison object
Asserts whether the face in the document matches the face in the live photo
(sub-breakdown) face_match object
Contains a score value under the properties bag (see the section “Facial Similarity Photo: Match Score”)
visual_authenticity object
Asserts whether the person in the live photo is real (not a spoof)
(sub-breakdown) spoofing_detection object
Contains a score value under the properties bag (see the section “Facial Similarity Photo: Spoofing Detection Score”)

Facial Similarity Photo: Source Integrity

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 Photo, the source_integrity sub-breakdown is composed of the following properties:

Facial Similarity Photo: Face Match Score

The face_match breakdown contains a properties object with a score value. This score is a floating point 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 spoofing (such as photos of printed photos or photos of digital screens) is detected the applicant will be rejected independently of the face match score.

Facial Similarity Photo: Spoofing Detection Score

The spoofing_detection breakdown contains a properties object with a score value. This score is a floating point number between 0 and 1. The closer the score is to 0, the more likely it is to be a spoof (i.e. photos of printed photos, or photos of digital screens). Conversely, the closer it is to 1, the less likely it is to be a spoof.

Photo Fully Auto

An example Photo Fully Auto object

HTTP/1.1 200 OK
Content-Type: application/json

{
  "created_at": "2020-01-01T14:16:21Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "facial_similarity_photo_fully_auto",
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "visual_authenticity": {
      "result": "clear",
      "breakdown": {
        "spoofing_detection": {
          "result": "clear",
          "properties": {
            "score": 0.9901
          }
        }
      }
    },
    "image_integrity": {
      "result": "clear",
      "breakdown": {
        "face_detected": {
          "result": "clear",
          "properties": {}
        },
        "source_integrity": {
          "result": "clear",
          "properties": {}
        }
      }
    },
    "face_comparison": {
      "result": "consider",
      "breakdown": {
        "face_match": {
          "result": "consider",
          "properties": {
            "score": 0.2097
          }
        }
      }
    }
  },
  "check_id": "<CHECK_ID>"
}

Like the Facial Similarity Photo report, the Photo Fully Auto report uses a live photo. The photo needs to be a live photo taken at the time of check submission, so that the report can assess whether the holder of the identity document is the same person as the one on the document.

Unlike the other Facial Similarity reports, the Facial Similarity Photo Fully Auto report only uses algorithms to return a result, and does not include expert review by Onfido’s super recogniser analysts. This guarantees faster results, but it also means more reports are likely to end with faces not being detected, or with users incorrectly rejected.

Photo Fully Auto: Object

The following table describes the unique fields returned in the Onfido API (v3) for a completed Photo Fully Auto report:

Attribute Format Possible values
result String "clear", "consider"
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
(sub-breakdown) face_match* String or null "clear", "consider", null
visual_authenticity String or null "clear", "consider", null
(sub-breakdown) spoofing_detection* String or null "clear", "consider", null

Photo Fully Auto: Breakdowns

image_integrity object
Asserts whether the quality and integrity of the uploaded files were sufficient to perform a face comparison
(sub-breakdown) face_detected object
Asserts a single face of good enough quality has been found in both the document image and the live photo
(sub-breakdown) source_integrity object
Asserts whether the live photo is trustworthy - i.e. not digitally tampered, from a fake webcam, or from other dubious sources
face_comparison object
Asserts whether the face in the document matches the face in the live photo
(sub-breakdown) face_match object
Contains a score value under the properties bag (see the section “Face Match Score” for Fully Auto)
visual_authenticity object
Asserts whether the person in the live photo is real (not a spoof)
(sub-breakdown) spoofing_detection object
Contains a score value under the properties bag (see the section “Spoofing Detection Score” for Fully Auto)

Photo Fully Auto: Source Integrity

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 Photo Fully Auto, the source_integrity sub-breakdown is composed of the following properties:

Photo Fully Auto: Face Match Score

The face_match breakdown contains a properties object with a score value. This score is a floating point 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.

The score only measures how similar the faces are, and does not make an assessment of the nature of the photo. If spoofing (such as photos of printed photos or photos of digital screens) is detected the applicant will be rejected independently of the face match score.

Photo Fully Auto: Spoofing Detection Score

The spoofing_detection breakdown contains a properties object with a score value. This score is a floating point number between 0 and 1. The closer the score is to 0, the more likely it is to be a spoof (i.e. photos of printed photos, or photos of digital screens). Conversely, the closer it is to 1, the less likely it is to be a spoof.

If the anti-spoofing algorithm fails to detect a face, the score property will not be present.

Video

An example Facial Similarity Video object

HTTP/1.1 200 OK
Content-Type: application/json

{
  "created_at": "2019-12-11T10:06:38Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "facial_similarity_video",
  "properties": {},
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "face_comparison": {
      "result": "clear",
      "breakdown": {
        "face_match": {
          "result": "clear",
          "properties": {
            "score": 0.6512
          }
        }
      }
    },
    "image_integrity": {
      "result": "clear",
      "breakdown": {
        "face_detected": {
          "result": "clear",
          "properties": {}
        },
        "source_integrity": {
          "result": "clear",
          "properties": {}
        }
      }
    },
    "visual_authenticity": {
      "result": "clear",
      "breakdown": {
        "liveness_detected": {
          "result": "clear",
          "properties": {}
        },
        "spoofing_detection": {
          "result": "clear",
          "properties": {
            "score": 0.9512
          }
        }
      }
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

In the Facial Similarity Video report, live videos are collected and uploaded by one of the Onfido SDKs (iOS, Android or JS).

In addition to confirming the two faces match, Facial Similarity Video assesses active liveness by asking users to repeat randomly generated numbers and perform a random head movement. This prevents impersonation - for example masks, and deep fakes displayed on digital 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:

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 (v3) for a completed Facial Similarity Video report:

Attribute Format Possible values
result String "clear", "consider"
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
(sub-breakdown) face_match* 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

Facial Similarity Video: Breakdowns

face_comparison object
Asserts whether the face in the document matches the face in the live video
(sub-breakdown) face_match object
Contains a score value (see the section “Facial Similarity Video Match Score”)
image_integrity object
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 object
Asserts a single face of good enough quality has been found in both the document image and in the live video
(sub-breakdown) source_integrity object
Asserts whether the live video is trustworthy - e.g. not from a fake webcam
visual_authenticity object
Asserts whether the person in the live video is real (not a spoof) and live
(sub-breakdown) spoofing_detection object
Asserts whether the live video is not a spoof (such as videos of digital screens)
(sub-breakdown) liveness_detected object
Asserts whether the numbers and head movements were correctly executed

Facial Similarity Video: Source Integrity

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:

Facial Similarity Video: Face Match Score

The face_match breakdown contains a properties object with a score value. This score is a floating point 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 live video. If spoofing (such as videos of digital screens, masks or print-outs) is detected the applicant will be rejected independently of the face match score.

Facial Similarity Video: Spoofing Detection Score

The spoofing_detection breakdown contains a properties object with a score value. This score is a floating point number between 0 and 1. The closer the score is to 0, the more likely it is to be a spoof (i.e. videos of digital screens, masks or print-outs). Conversely, the closer it is to 1, the less likely it is to be a spoof.

The score value is based on passive facial information only, regardless of whether or not the user said the expected digits or turned their head in the correct direction. For example, a user who performs no action but is a real person should receive a score close to 1.

Known Faces report BETA

An example Known Faces report object

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": "<REPORT_ID>",
  "created_at": "2020-03-10T10:49:08Z",
  "documents": [],
  "result": "consider",
  "href": "/v3/reports/<REPORT_ID>",
  "name": "known_faces",
  "properties": {
    "matches": [
      {
        "applicant_id": "<1ST_MATCHED_APPLICANT_ID>",
        "score": 0.9216
      },
      {
        "applicant_id": "<2ND_MATCHED_APPLICANT_ID>",
        "score": 0.9373
      },
      {
        "applicant_id": "<3RD_MATCHED_APPLICANT_ID>",
        "score": 0.9832
      }
    ]
  },
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "previously_seen_faces": {
      "result": "consider"
    },
    "image_integrity": {
      "result": "clear"
    }
  },
  "check_id": "<CHECK_ID>"
}

Known Faces is currently a BETA product. Please contact client-support@onfido.com if you would like to find out more.

The Known Faces report compares a specific applicant’s likeness in their most recent live photo to live photos from all applicants in your Onfido account database. It alerts you to faces which have already been through your identity verification flow, so you can catch repeat identity fraud attempts, and help confused users who may have forgotten they already registered with you to recover their accounts.

Each applicant you run a Known Faces report against must have an uploaded live photo.

As a standalone report, Known Faces will not make an assessment of whether the face on the live photo is real and not a spoof (e.g. photos of photos, photos of screens): it is only concerned with the matching of faces, regardless of whether they are real faces or not. Combining Known Faces with the Document and Facial Similarity reports will guarantee the live photo is real and not a spoof, as this is assessed as part of the Facial Similarity report.

No matches will be returned against any permanently deleted applicants. If you delete an individual’s applicant object, then that individual goes through the identity verification flow again and then you run a Known Faces report against them, this will not return any matches. This is because no data would be available to match against.

To request a Known Faces report as part of a check in the API, use the report_names field (which takes an array of strings):

"report_names": ["known_faces"]

The report_names field takes an array of strings.

Required applicant data

For Known Face reports, first_name and last_name must be provided but can be dummy values if you don’t know an applicant’s name.

Known Faces Object

The following table describes the unique fields returned in the Onfido API (v3) for a completed Known Faces report:

Attribute Format Possible values
result String "clear", "consider"
previously_seen_faces String or null "clear", "consider" , null
image_integrity String "clear", "consider"

Known Faces Breakdowns

previously_seen_faces object
Asserts whether the applicant’s most recent live photo matches any other live photos already in your Onfido account database
image_integrity object
Asserts whether the uploaded live photo and the content contained within it were of sufficient quality to perform a face comparison

Known Faces Score

The Known Faces response will return any matching applicant IDs as entries inside a matches array, each with a corresponding score.

This score is a floating point number between 0 and 1 that expresses how similar the two faces are, where 1 is a perfect match.

For example:

“matches”: [
  {
    “applicant_id”: “NTH_MATCHED_APPLICANT_ID”,
    “score”: 0.9915
  }
]

If any matches are found, the response will also contain "result": "consider".

Identity Enhanced report

An example Identity Enhanced report object

HTTP/1.1 200 OK
Content-Type: application/json

{
  "created_at": "2019-10-03T15:54:20Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "identity_enhanced",
  "properties": {
    "matched_address": 19099121,
    "matched_addresses": [
      {
        "id": 19099121,
        "match_types": [
          "credit_agencies",
          "voting_register"
        ]
      }
    ]
  },
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "address": {
      "result": "clear",
      "breakdown": {
        "credit_agencies": {
          "result": "clear",
          "properties": {
            "number_of_matches": "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": "clear"
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

An Identity Enhanced 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.

Identity Enhanced is the API v3 Identity report. It is typically used for “Know Your Customer” (KYC) purposes. For example, if you are providing a financial service.

To request an Identity Enhanced report as part of a check in the API, use the report_names field (which takes an array of strings):

"report_names": ["identity_enhanced"]

The report_names field takes an array of strings.

For applicants in the United States, the Identity Enhanced 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.

Identity Enhanced reports will be run in the country of the applicants address. Please make sure that the country is supported for Identity Enhanced reports.

Report results vary depending on the address country they were run in.

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 Enhanced

You can review the full list of supported countries for Identity Enhanced reports. The column Identity Enhanced Report on that page lists supported and unsupported countries.

This is not a list of documents that Onfido supports: you can review that list separately.

Required applicant data

For Identity Enhanced reports, the following applicant data must be provided:

first_name

last_name

dob

address[]state (US only)

address[]postcode (ZIP code in US)

address[]country (must be a 3-letter ISO code e.g. “GBR”)

address[]street The applicant address object is nested inside the applicant object. If you create an applicant object with an address, you must provide postcode and country, and state for US addresses.

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)

Overall result logic:

If the applicant address is in the UK:

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:

When the SSN or the last 4 digits of the SSN are provided:

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 Enhanced report custom logic

Partial Identity Enhanced 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_matches": "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 Enhanced 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:

  1. >=2 against number_of_matches under the credit_agencies sub-breakdown that is under the address parent breakdown.

  2. clear against the result value under the credit_agencies sub-breakdown that is under the date_of_birth parent breakdown.

See also the comments against the partial example under ‘HTTP’.

Watchlist report

There are 4 different types of Watchlist report:

Report name Request body in API
Watchlist Standard "report_names": ["watchlist_standard"]
Watchlist Enhanced "report_names": ["watchlist_enhanced"]
Watchlist Peps Only "report_names": ["watchlist_peps_only"]
Watchlist Sanctions Only "report_names": ["watchlist_sanctions_only"]

The report_names field takes an array of strings.

Watchlist Enhanced

An example Watchlist Enhanced report object

HTTP/1.1 201 Created
Content-Type: application/json

{
  "created_at": "2019-10-03T15:37:03Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "watchlist_enhanced",
  "properties": {
    "records": []
  },
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "politically_exposed_person": {
      "result": "clear"
    },
    "sanction": {
      "result": "clear"
    },
    "adverse_media": {
      "result": "clear"
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

A watchlist_enhanced 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 below), 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_enhanced reports, first_name and last_name must be provided.

dob

address[]postcode (ZIP code in US)

address[]country

address[]state (required for US addresses)

The applicant address object is nested inside the applicant object. If you create an applicant object with an address, you must provide postcode and country, and state for US addresses.

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 politically_exposed_person and adverse_media breakdown matches except Money Laundering and Terrorist related matches. This will not filter sanction breakdown matches.

If a match is found with either Sanctions, Money Laundering or Terrorist related events, all the other events of that match will be returned, even if the other events are not related to the country specified in the address.

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.

Breakdown

adverse_media
politically_exposed_person
sanction

Watchlist Standard

An example Watchlist Standard report object

HTTP/1.1 201 Created
Content-Type: application/json

{
  "created_at": "2019-10-03T15:42:36Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "watchlist_standard",
  "properties": {
    "records": []
  },
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "breakdown": {
    "sanction": {
      "result": "clear"
    },
    "politically_exposed_person": {
      "result": "clear"
    },
    "legal_and_regulatory_warnings": {
      "result": "clear"
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

A watchlist_standard check provides a granular breakdown of any records found when searching global watchlists. The watchlists include: government sanctions lists, politically exposed persons (PEPs) lists, and more generally: warnings lists such as anti-terrorism watchlists, anti-money-laundering (AML) watchlists and most wanted watchlists.

You can use a watchlist_peps_only check to search only PEPs lists, or a watchlist_sanctions_only check to search only sanctions and warnings lists. A watchlist_standard check will search all types.

Required applicant data

For watchlist_standard checks, first_name and last_name must be provided.

dob

Watchlist Peps Only

A watchlist_peps_only check is a subset of the watchlist_standard check. It provides a granular breakdown of any records found when searching global politically exposed persons (PEPs) lists specifically.

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.

Required applicant data

For watchlist_peps_only checks, first_name and last_name must be provided but can be dummy values if you don’t know an applicant’s name.

dob

Watchlist Sanctions Only

A watchlist_sanctions_only check is a subset of the watchlist_standard check. It provides a granular breakdown of any records found when searching global sanctions and warning lists specifically.

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.

Required applicant data

For watchlist_sanctions_only checks, first_name and last_name must be provided but can be dummy values if you don’t know an applicant’s name.

dob

Proof of Address report

To request a Proof of Address report as part of a check in the API, use the report_names field (which takes an array of strings):

"report_names": ["proof_of_address"]

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.

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 3-letter ISO code e.g. “GBR”)

The applicant address object is nested inside the applicant object. If you create an applicant object with an address, you must provide postcode and country, and state for US addresses.

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

A PoA report upon completion is composed of 3 breakdowns: image integrity, document classification and data comparison.

Breakdowns

image_integrity object
Asserts whether the quality of the uploaded document was sufficient to verify the address
document_classification object
Asserts whether the document is of a valid type as PoA
data_comparison object
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 overall report result will be null if any of the following is true:

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:

Right to Work report

An example Right to Work report object

HTTP/1.1 201 Created
Content-Type: application/json

{
  "created_at": "2019-10-03T15:48:02Z",
  "href": "/v3/reports/<REPORT_ID>",
  "id": "<REPORT_ID>",
  "name": "right_to_work",
  "properties": {
    "nationality": "",
    "last_name": "Names",
    "issuing_country": "GBR",
    "gender": "",
    "first_name": "Report",
    "document_type": "passport",
    "document_numbers": [
      {
        "value": "123456789",
        "type": "document_number"
      }
    ],
    "date_of_expiry": "2030-01-01",
    "date_of_birth": "1990-01-01"
  },
  "result": "clear",
  "status": "complete",
  "sub_result": null,
  "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"
    }
  },
  "check_id": "<CHECK_ID>",
  "documents": []
}

To request a Right to Work report as part of a check in the API, use the report_names field (which takes an array of strings):

"report_names": ["right_to_work"]

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:

Tier 4 (General) student

Tier 2 and Tier 5 Permit visas

Proof of National Insurance number

One of the following:

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


About webhooks

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.

You can create and configure webhooks to receive status changes from live, sandbox 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:

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.

You can quickly inspect webhook requests with temporary endpoint URLs. You can create these using free hosted services such as https://webhook.site.

Webhook object

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": "/v3/webhooks/<WEBHOOK_ID>",
      "token": "<WEBHOOK_TOKEN>",
      "environments": [
        "sandbox"
      ],
      "events": [
        "check.started"
      ]
    }
  ]
}
Attribute Description
id string
The unique identifier for the webhook
url string
The url to listen to notifications (must be HTTPS)
enabled boolean
Determines if the webhook should be active. If omitted, will be set to true by default
events array
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
token string
The webhook token (read more about this in the section on verifying webhook signatures
href string
The URI of this resource

IP addresses

All webhook requests will come from the following IPs:

Europe:

United States:

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 applicant_provides_data is true, 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-10-28T15:00:39Z",
      "href": "https://api.onfido.com/v3/reports/<REPORT_ID>"
    }
  }
}

Attributes

Attribute Description
payload object
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 object
The object affected by this event. This will contain an id and an href to retrieve that resource

Verifying webhook signatures

X-SHA2-Signature: <HMAC_VALUE>
const { WebhookEventVerifier } = require("onfido-node");

const webhookToken = process.env.ONFIDO_WEBHOOK_SECRET_TOKEN;
const verifier = new WebhookEventVerifier(webhookToken);

const readWebhookEvent = (rawEventBody, signature) => {
  try {
    return verifier.readPayload(rawEventBody, signature);
  } catch (error) {
    // Handle invalid webhooks.
    // The error will be an instance of OnfidoError.
  }
};

You should verify request signatures on your server to prevent attackers from imitating valid webhook events.

Each webhook you register will return a single secret token in the token field of the API response body, which is used to generate an HMAC using SHA-256. You only need to register a webhook once. The token for each webhook is also displayed on the Onfido Dashboard ‘Webhook Management’ page.

If possible, we recommend that you verify request signatures with our supported client libraries in your integration.

The following Onfido client libraries have support built in:

Using Onfido client libraries

You must initialise the verifier instance with your webhook’s secret token. For each webhook event, the verifier instance needs:

Code examples showing these steps for supported libraries are in this section of the documentation.

Manually

We provide a detailed guide in our Developer Hub for manually verifying webhook signatures.

Register webhook

Register a webhook

POST /v3/webhooks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
Content-Type: application/json

{
  "url": "https://<URL>",
  "enabled": true,
  "events": [
    "report.completed",
    "check.completed"
  ]
}
curl https://api.onfido.com/v3/webhooks/ \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -F 'url=https://<URL>' \
  -F 'events[]=report.completed' \
  -F 'events[]=check.completed'
url = 'https://<URL>'

onfido.webhook.create(url: url, events: ['report.completed', 'check.completed'])
const webhook = await onfido.webhook.create({
  url: "https://<URL>",
  events: ["report.completed", "check.completed"]
});
webhook = onfido.Webhook(url='https://<URL>', events=['report.completed', 'check.completed'])

api_instance.create_webhook(webhook)
$webhook = new \Onfido\Model\Webhook();
$webhook->setUrl('https://<URL>');
$webhook->setEvents(['report.completed', 'check.completed']);

$onfido->createWebhook($webhook);
import com.onfido.models.Webhook;

Webhook.Request webhookRequest = Webhook.request()
        .url("https://<URL>")
        .events("report.completed", "check.completed");

Webhook webhook = onfido.webhook.create(webhookRequest);

Example response (register webhook)

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "<WEBHOOK_ID>",
  "url": "<URL>",
  "token": "<WEBHOOK_TOKEN>",
  "enabled": true,
  "href": "/v3/webhooks/<WEBHOOK_ID>",
  "environments": [
    "sandbox"
  ],
  "events": [
    "report.completed",
    "check.completed"
  ]
}

POST https://api.onfido.com/v3/webhooks/

Registers a webhook. Returns a webhook object.

You can read 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” or “live” but sandbox tokens cannot be used for the “live” environment.
If omitted (with a live token), 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 /v3/webhooks/ HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
curl https://api.onfido.com/v3/webhooks/ \
  -H 'Authorization: Token token=test_vrkuXHTuZL6g_I1fy9K5I4UQoSq1ObaR' \
onfido.webhook.all
const webhooks = await onfido.webhook.list();
api_instance.list_webhooks()
$onfido->listWebhooks();
import com.onfido.models.Webhook;

List<Webhook> webhooks = onfido.webhook.list();

GET https://api.onfido.com/v3/webhooks/

Lists all webhooks you’ve created.

Returns data in the form: {"webhooks": [<LIST_OF_WEBHOOK_OBJECTS>]}.

Retrieve webhook

Retrieve a single webhook

GET /v3/webhooks/<WEBHOOK_ID> HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
curl https://api.onfido.com/v3/webhooks/<WEBHOOK_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
onfido.webhook.find('<WEBHOOK_ID>')
const webhook = await onfido.webhook.find("<WEBHOOK_ID>");
api_instance.find_webhook('<WEBHOOK_ID>')
$onfido->findWebhook('<WEBHOOK_ID>');
import com.onfido.models.Webhook;

String webhookId = "<WEBHOOK_ID>";
Webhook webhook = onfido.webhook.find(webhookId); 

GET https://api.onfido.com/v3/webhooks/{webhook_id}

Retrieves a single webhook. Returns a webhook object.

Edit webhook

Edit a webhook (change the URL)

PUT /v3/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/v3/webhooks/<WEBHOOK_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "url": "https://<NEW_URL>"
}' \
  -X PUT
const newWebhookDetails = {url: "https://<NEW_URL>"};

const editedWebhook = await onfido.webhook.update("<WEBHOOK_ID>", {
  url: "https://<NEW_URL>"
});
update_webhook = onfido.Webhook(url='https://<NEW_URL>')
webhook_id = '<WEBHOOK_ID>'
api_instance.edit_webhook(webhook_id, update_webhook)
$update_webhook = new \Onfido\Model\Webhook();
$update_webhook->setUrl('https://<NEW_URL>');
$onfido->editWebhook('<WEBHOOK_ID>', $update_webhook);
import com.onfido.models.Webhook;

Webhook.Request webhook = Webhook.request()
        .url("https://<NEW_URL>");

String webhookId = "<WEBHOOK_ID>";
Webhook webhook = onfido.webhook.update(webhookId, webhook);

PUT https://api.onfido.com/v3/webhooks/{webhook_id}

Edits a webhook. Returns the updated webhook object.

Delete webhook

Delete a webhook

DELETE /v3/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/v3/webhooks/<WEBHOOK_ID> \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>' \
  -X DELETE
await onfido.webhook.delete("<WEBHOOK_ID>");
webhook_id = '<WEBHOOK_ID>'
onfido.delete_webhook(webhook_id)
$webhookId = '<WEBHOOK_ID>';
$onfido->deleteWebhook($webhookId);
import com.onfido.models.Webhook;

String webhookId = "<WEBHOOK_ID>";

onfido.webhook.delete(webhookId);

DELETE https://api.onfido.com/v3/webhooks/{webhook_id}

Deletes a webhook. If successful, returns a 204 No Content response.

Address picker

Search for an address using a postcode

GET /v3/addresses/pick?postcode=SW46EH HTTP/1.1
Host: api.onfido.com
Authorization: Token token=<YOUR_API_TOKEN>
$ curl https://api.onfido.com/v3/addresses/pick?postcode=SW46EH \
  -H 'Authorization: Token token=<YOUR_API_TOKEN>'
onfido.address.all('SW4 6EH')
const addresses = await onfido.address.pick('SW4 6EH');
onfido.find_addresses('SW4 6EH')
$postcode = 'SW4 6EH';
$onfido->findAddresses($postcode);
import com.onfido.models.Address;

String postcode = "SW4 6EH"; 

List<Address> addresses = onfido.address.pick(postcode);

GET https://api.onfido.com/v3/addresses/pick?postcode={postcode}

Performs a search for addresses by postcode (UK only).

Returns data in the form: {"addresses": [<LIST_OF_ADDRESS_OBJECTS>]}.

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 /v3/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/v3/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
applicant_id = '<APPLICANT_ID>'
referrer = 'https://*.example.com/example_page/**'

onfido.sdk_token.create(applicant_id: applicant_id, referrer: referrer)
const generateSdkToken = await onfido.sdkToken.generate({
  applicantId: "<APPLICANT_ID>",
  referrer: "https://*.example.com/example_page/**"
});
applicant_id = '<APPLICANT_ID>'
sdk_token_request = onfido.SdkToken(
    applicant_id=applicant_id,
    referrer='https://*.example.com/example_page/**'
)
$applicantId = '<APPLICANT_ID>';

$sdkTokenRequest = new Onfido\Model\SdkToken();

$sdkTokenRequest->setApplicantId('<APPLICANT_ID>');
$sdkTokenRequest->setReferrer('https://*.example.com/example_page/*');

$onfido->generateSdkToken($sdkTokenRequest);
import com.onfido.models.SdkToken;

SdkToken.Request sdkTokenRequest = SdkToken.request()
    .applicantId("<APPLICANT_ID>")
    .referrer("https://*.example.com/example_page/*");

String sdkToken = onfido.sdkToken.generate(sdkTokenRequest);

POST https://api.onfido.com/v3/sdk_token

Generates an SDK token. Returns a token object containing the 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/v3/extractions

Autofill is currently a BETA product. Please contact client-support@onfido.com if you would like to find out more.

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 /v3/extractions 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": "1990-07-21",
    "date_of_expiry": "2025-07-07",
    "document_number": "200407512345",
    "first_name": "AMANDINE CHANTAL",
    "gender": "Female",
    "last_name": "MAVARINE",
    "mrz_line1": "IDFRAMAVARINE<<<<<<<<<<<<<<<<<075123",
    "mrz_line2": "2004075123457AMANDINE<CHANT9007219F5",
    "nationality": "FRA"
  }
}

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 3-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 3-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.