Every time an end user elects to supply an ID document on the relying party app/website/custom product, you will need to create a session with Yoti to perform the ID checks.
Before you start
You will need the Yoti App on your phone and to have registered your business with Yoti.
API Link
Jump straight to our API references with code snippets if you prefer.
Generate the request using our SDK
Please use our Yoti SDKs to automatically build the relevant request.
The Yoti SDKs are available via popular dependency management systems.
// Get the Yoti PHP SDK library via a Composer package
composer require yoti/yoti-php-sdk
// If you are using Maven, add the following dependency:
<dependency>
<groupId>com.yoti</groupId>
<artifactId>yoti-sdk-impl</artifactId>
<version>2.6.0</version>
</dependency>
// If you are using Gradle, add the following dependency:
compile group: 'com.yoti', name: 'yoti-sdk-impl', version: '2.6.0'
// As of version 2.4.0, modules are used. This means it's not necessary to get a copy or fetch all dependencies
// as instructed below, as the Go toolchain will fetch them as necessary.
// You can simply add a `require github.com/getyoti/yoti-go-sdk/v2` to go.mod.
// To download and install the Yoti SDK and its dependencies, run the following command from your terminal:
go get "github.com/getyoti/yoti-go-sdk/v2"
// To install the Yoti NuGet package you will need to install NuGet.
// To import the latest Yoti SDK into your project, enter the following
// command from NuGet Package Manager Console in Visual Studio:
Install-Package Yoti
// For other installation methods, see https://www.nuget.org/packages/Yoti
gem install yoti
# The gem provides a configuration generator for Ruby on Rails:
rails generate yoti:install
Once you have added the Yoti SDK dependency to your project, you can use it to build and send your request. See the code snippets below for examples of how to construct the promise.
const { RequestBuilder, Payload } = require("yoti");
const request = new RequestBuilder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemFilePath("<YOTI_KEY_FILE_PATH>") // file path to PEM file
.withEndpoint("/sessions")
.withPayload(new Payload(SESSION_OBJ))
.withMethod("POST")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();
//get Yoti response
const response = await request.execute();
<?php
use Yoti\Http\RequestBuilder;
use Yoti\Http\Payload;
$request = (new RequestBuilder())
->withBaseUrl('https://api.yoti.com/idverify/v1')
->withPemFilePath('<YOTI_KEY_FILE_PATH>')
->withEndpoint('/sessions')
->withPayload(Payload::fromString(SESSION_JSON_STRING)) // * Version ^2: new Payload(SESSION_OBJ)
->withMethod('POST')
->withQueryParam('sdkId', '<YOTI_CLIENT_SDK_ID>')
->build()
//get Yoti Response
->execute();
// * For JSON data in Version >3 please use Payload::fromJsonData(SESSION_OBJ)
from yoti_python_sdk.http import SignedRequest, RequestHandler
import json
import requests
def execute(request):
response = requests.request(
url=request.url, data=request.data, headers=request.headers, method=request.method)
return response.content
def generate_session():
payload = {} # payload
payload_string = json.dumps(payload).encode()
signed_request = (
SignedRequest
.builder()
.with_pem_file("<YOTI_KEY_FILE_PATH>")
.with_base_url("https://api.yoti.com/idverify/v1")
.with_endpoint("/sessions")
.with_http_method("POST")
.with_param("sdkId", "<YOTI_CLIENT_SDK_ID>")
.with_payload(payload_string)
.build()
)
# get Yoti response
response = signed_request.execute()
response_payload = json.loads(response.text)
byte[] SESSION_OBJ = ...
try {
SignedRequest signedRequest = SignedRequestBuilder.newInstance()
.withKeyPair(<YOTI_KEY_FILE_PATH>)
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withEndpoint("/sessions")
.withPayload(SESSION_OBJ)
.withHttpMethod("POST")
.withQueryParameter("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();
YourPojo yourPojo = signedRequest.execute(YourPojo.class);
} catch (GeneralSecurityException | URISyntaxException | IOException | ResourceException ex) {
ex.printStackTrace();
}
import (
"io/ioutil"
"net/http"
"github.com/getyoti/yoti-go-sdk/v2/requests"
)
key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>")
// Create session
request, _ := requests.SignedRequest{
HTTPMethod: http.MethodPost,
BaseURL: "https://api.yoti.com/idverify/v1",
Endpoint: "/sessions",
Params: map[string]string{
"sdkId": "<YOTI_CLIENT_SDK_ID>"
},
Headers: map[string][]string{
"Content-Type": {"application/json"},
"Accept": {"application/json"}
},
Body: func(data []byte, _ error) []byte {
return data
}(json.Marshal(jsonobj{ data },
})),
}.WithPemFile(key).Request()
//get Yoti response
response, _ := http.DefaultClient.Do(request)
Creating the session object
Below is the full payload example of the request for creating the session.
You will need to specify the following:
System preferences
Checks
ID Document Authenticity
Liveness
ID Document Face Match
Tasks
Client preferences
Name | Acts on | Type | Comment |
|---|
ID_AUTHENTICITY_CHECK | 1x Document Resource | Asynchronous | Must wait for the TextDataCheck, if there is one. |
TEXT_DATA_CHECK | 1x Document Resource | Asynchronous | Used to recover a failed TextExtractionTask |
LIVENESS_CHECK | 1x Liveness Resource | Synchronous | Runs as soon as the FaceMap is uploaded. Can be repeated until it succeeds, but only one successful Check is allowed in each Session. |
FACEMATCH_CHECK | 1x Doc Resource & 1x Liveness Resource | Asynchronous | Must wait for the TextDataCheck, if there is one |
Good to know
The request payload should be in the following format (full details of request parameters are provided in the 'explained' section, below).
This JSON string will be the SESSION_OBJ parameter in the withPayload above code snippet.
{
"client_session_token_ttl": 600,
"resources_ttl": 604800,
"user_tracking_id": "<YOUR_USER_ID>",
"notifications": {
"endpoint": "https://yourdomain.example/idverify/updates",
"topics": [
"resource_update",
"task_completion",
"check_completion",
"session_completion"
],
"auth_token": "username:password"
},
"requested_checks": [
{
"type": "ID_DOCUMENT_AUTHENTICITY",
"config": {
}
},
{
"type": "LIVENESS",
"config": {
"liveness_type": "ZOOM",
"max_retries": 3
}
},
{
"type": "ID_DOCUMENT_FACE_MATCH",
"config": {
"manual_check": "FALLBACK"
}
}
],
"requested_tasks": [
{
"type": "ID_DOCUMENT_TEXT_DATA_EXTRACTION",
"config": {
"manual_check": "FALLBACK"
}
}
],
"sdk_config": {
"allowed_capture_methods": "CAMERA_AND_UPLOAD",
"primary_colour": "#2d9fff",
"preset_issuing_country": "USA",
"success_url": "https://yourdomain.example/success",
"error_url": "https://yourdomain.example/error"
}
}
Example response
If the request is successful and a session is generated the API will send a response in the form:
{
"client_session_token_ttl": 599,
"client_session_token": "<uuid>",
"session_id": "<uuid>"
}
Response | Description |
|---|
client_session_token_ttl | Time in seconds until the client session expires |
client_session_token | Used to authenticate the session |
session_id | ID of the session |
Creating Sessions explained
1. System preferences
The table below explains the optional parameters for the session and data retention configuration.
"client_session_token_ttl": 600,
"resources_ttl": 604800,
"user_tracking_id": "<uuid>",
"notifications": {
"endpoint": "https://yourdomain.com/idverify/updates",
"topics": [
"resource_update",
"task_completion",
"check_completion",
"session_completion"
],
"auth_token": "XXX"
}
Parameters | Description | Required |
|---|
client_session_token_ttl | This is how long the full Yoti Doc Scan session is open for in seconds. This must be longer than 5 minutes. | optional |
resources_ttl | Retention period for uploaded documents/images in number of seconds. Default is one week (60*60*24*7=604800). This can be a minimum of 24 hours and must be at least 24 hours longer than the client_session_token_ttl. This starts once the client_session_token_ttl is completed. | optional |
user_tracking_id | Allows the relying business backend to track the same user across multiple sessions. Note: Should not contain any personal identifiable information. | optional |
notifications { } | If provided, Yoti Doc Scan posts (POST endpoint required) an update notification every time the session state changes, based on the selected subscription topics "endpoint" : "https://yourdomain.com/idverify/updates". Only HTTPS endpoints with TLS are supported. If there is no 'topics' array then only session completion notifications are sent. | optional |
auth_token | Allows the relying business backend to define an authorisation token, if they have secured API endpoints, allowing Yoti to call endpoints. | optional |
Knowledge base
Please head over to our knowledge base for more information on notifications or selecting multiple documents / countries.
2. Checks Configuration
1) ID Document authenticity
A request to assess the characteristics of a document, to determine the validity of the ID document.
"requested_checks": [
{
"type": "ID_DOCUMENT_AUTHENTICITY",
"config": {}
},
]
This requires there to be image media attached to the resource (images of the front and back of the document - the back of the document is not always required).
Jump to..
On successful completion, the check outputs a report in the form of a structured JSON object, which can be found in
the ‘retrieve results’ section. Updates are sent to the updates URL (if subscribed to notifications).
2) Liveness
A requested check to assess whether the document scan is being performed by a real person and not someone wearing a mask or an automated system.
"requested_checks": [
{
"type": "LIVENESS",
"config": {
"liveness_type": "ZOOM", // Required
"max_retries": 3 // Required, must be greater than 0
}
}
]
You must provide the max number of retries your users can have before the liveness is failed. This must be greater than 1.
An "attempt" is a completed liveness check that is either rejected or approved. If the user does not complete the liveness check this does not count as an attempt and the user will be prompted to try again.
Liveness check
Jump to
This will produce a liveness_capture resource in the session as well as a report in the form of a structured JSON object for each attempted liveness check.
3) ID Document face match
A request to assess whether the user's face matches the face on the ID document. The user's facial image is obtained from the liveness check, which must be performed first.
"requested_checks": [
{
"type": "ID_DOCUMENT_FACE_MATCH",
"config": {
"manual_check": "FALLBACK" // | "NEVER" | "ALWAYS"
}
}
]
This is performed as an automated check, however you can configure whether the check is passed on to our security centre for a manual check by qualified Yoti staff. This can be set to always, fallback or never.
Manual Check | Explanation |
|---|
ALWAYS | The requested check will always go to the security centre regardless of the success of the automated check. |
NEVER | The requested check will never go to the security centre. |
FALLBACK | The requested check will only go to the security centre if the machine check fails. |
Jump to...
On successful completion, the check outputs a report in the form of a structured JSON object, which can be found in the ‘checks retrieval’ section of the session retrieval
3. Tasks Configuration
Yoti can complete the following optional task(s), if requested:
ID Document text data extraction
A request to obtain the data printed visually on a document, in structured form.
If machine data extraction is not successful, there is an option (selected at session creation) to fallback to manual data extraction. This generates a ‘text data check’ automatically, and the document is reviewed by one of our document processing experts.
"requested_tasks": [
{
"type": "ID_DOCUMENT_TEXT_DATA_EXTRACTION",
"config": {
"manual_check": "FALLBACK"
}
}
]
Manual Data Extraction | Explanation |
|---|
FALLBACK | This will initiate manual data extraction only if the automatic extraction fails. We strongly recommend this option. |
NEVER | If the ID fails on automatic extraction, Yoti will not attempt manual extraction and will return a failure in the report. |
ALWAYS | The document is always referred for manual review at Yoti's security centre, regardless of whether machine data extraction has succeeded or failed. |
Jump to
On successful completion, see the task results section
Knowledge base
For more information on ID Document Text Data Extraction please head to our knowledge base.
4. Client Preferences
The method sdk_config is explained below. If not defined then they will be set to default (indicated)
"sdk_config": {
"allowed_capture_methods": "CAMERA_AND_UPLOAD"
"primary_colour": "#2d9fff",
"preset_issuing_country": "USA",
"success_url": "https://yourdomain.com/success",
"error_url": "https://yourdomain.com/error",
"locale": "en-GB"
}
Document captureType | Parameters (examples) | Description | Required |
|---|
allowed_capture_methods | CAMERA_AND_UPLOAD, CAMERA(default) | The user must use a camera to take a photo of their ID document, or the user can take a photo or has the option to upload an image of the document from file. | optional |
primary_colour | #2d9fff(default), #ff0000 | Colours of the button provided in the frontend client as a hexadecimal value. | optional |
preset_issuing_country | USA, GBR | The user must select the issuing country of the document they are uploading. This setting determines which issuing country is selected by default. NOTE: Must be a 3 letter ISO code. | optional |
success_url | https://yourdomain.com/success | If the upload/photo is successfully captured redirect your users here. Yoti will then begin to carry out the requested checks and tasks. If undefined, the page will not redirect and you can listen to Yoti's post messages on the same page. | optional |
error_url | https://yourdomain.com/error | If the upload/photo is unsuccessfully captured redirect your users here. If undefined, the user view will display an error screen, with the error code as a query parameter and won't redirect. (Details on the error codes can be found here.) | optional |
locale | en-GB(default) | Force language locale for the frontend client. Full list shown below. | optional |
Supported Documents Endpoint
To see all documents that are supported for Yoti Doc Scan you can send a GET request to our supported-documents endpoint. The request is built in a similar fashion to other Yoti requests, see the example promises below.
const { RequestBuilder } = require("yoti");
const request = new RequestBuilder()
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withPemFilePath("<YOTI_KEY_FILE_PATH>")
.withEndpoint("/supported-documents")
.withMethod("GET")
.withQueryParam("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();
//get Yoti response
const response = await request.execute();
<?php
use Yoti\Http\RequestBuilder;
$request = (new RequestBuilder())
->withBaseUrl('https://api.yoti.com/idverify/v1')
->withPemFilePath('<YOTI_KEY_FILE_PATH>')
->withEndpoint('/supported-documents')
->withMethod('GET')
->withQueryParam('sdkId', '<YOTI_CLIENT_SDK_ID>')
->build()
//get Yoti Response
->execute();
from yoti_python_sdk.http import SignedRequest, RequestHandler
import json
import requests
def execute(request):
response = requests.request(
url=request.url, data=request.data, headers=request.headers, method=request.method)
return response.content
def generate_session():
signed_request = (
SignedRequest
.builder()
.with_pem_file("<YOTI_KEY_FILE_PATH>")
.with_base_url("https://api.yoti.com/idverify/v1")
.with_endpoint("/supported-documents")
.with_http_method("GET")
.with_param("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build()
)
# get Yoti response
response = signed_request.execute()
response_payload = json.loads(response.text)
byte[] payload = ...
try {
SignedRequest signedRequest = SignedRequestBuilder.newInstance()
.withKeyPair(<YOTI_KEY_FILE_PATH>)
.withBaseUrl("https://api.yoti.com/idverify/v1")
.withEndpoint("/supported-documents")
.withHttpMethod("GET")
.withQueryParameter("sdkId", "<YOTI_CLIENT_SDK_ID>")
.build();
YourPojo yourPojo = signedRequest.execute(YourPojo.class);
} catch (GeneralSecurityException | URISyntaxException | IOException | ResourceException ex) {
ex.printStackTrace();
}
import (
"io/ioutil"
"net/http"
"github.com/getyoti/yoti-go-sdk/v2/requests"
)
key, _ := ioutil.ReadFile("<YOTI_KEY_FILE_PATH>")
// GET supported documents
request, _ := requests.SignedRequest{
HTTPMethod: http.MethodGet,
BaseURL: "https://api.yoti.com/idverify/v1",
Endpoint: "/supported-documents",
Params: map[string]string{
"sdkId": "<YOTI_CLIENT_SDK_ID>"
},
Headers: map[string][]string{
"Content-Type": {"application/json"},
"Accept": {"application/json"}
},
}.WithPemFile(key).Request()
//get Yoti response
response, _ := http.DefaultClient.Do(request)
Yoti will return a JSON object with countries listed by ISO country code. Each country will list an array of supported documents from that country. See the example below:
{
"supported_countries": [
{
"code": "AGO",
"supported_documents": [
{
"type": "DRIVING_LICENCE"
},
{
"type": "NATIONAL_ID"
},
{
"type": "PASSPORT"
}
]
},
{
"code": "AIA",
"supported_documents": [
{
"type": "PASSPORT"
}
]
}, ...