Introduction
Welcome to Veriff's developers documentation!
If you have any questions, use the Intercom button at the bottom of the screen or write to support@veriff.com to get in contact with us.
Getting Started With Veriff
Signing up
Fill in the form at veriff.com [↗] and a confirmation email with further instructions is sent to you.
Logging in
To log in to the Veriff environment, please use the link sent in the confirmation email and follow the instructions.
New user accounts
Once you have logged in and wish to create new user accounts for other members of your team, navigate to the Team page. You must have the Administrator rights to do it. Check out this article [↗] in the Knowledge Base for more info (requires a login to the Veriff environment).
Creating an integration
Integration is a collection of settings and is distinguished by the API keys. In short, it means that an integration is a way to exchange data with Veriff.
Integrations are created in the Veriff environment. In case it has not already been created for you, or you would like to create another one, follow these steps.
- Log in via the link sent to you in your signup email
- Navigate to Integrations tab on the top-bar menu
- Click on the Add integration button
- Choose a suitable name and environment for the integration (either Test or Live)
Test integrations
These are used for development. Verification sessions done in the test integrations do not count towards paid usage. Stress testing without prior agreement with Veriff is not allowed.
Veriff does not provide decisions for sessions created in the test integration, you need to trigger the decisions yourself.
One option is to do it in the Veriff environment. See the article here [↗] about how to do that (requires a login to the Veriff environment).
The other is to generate a session using the POST /sessions call and pass "Approve", "Decline" or "Resubmit"
in the firstName
field. You can read more about it in this article
[↗] in the Knowledge Base (requires a login to the Veriff environment).
Live integrations
These are used for production. Sessions created will count towards paid usage and Veriff provides a decisions for those.
To find more information about Integrations, please see the articles [↗] in the Knowledge Base (requires a login to the Veriff environment).
Quick guide of IDV using the SDKs
This section is a quick intro into doing identity verification (IDV) when using the Software Development Kits (SDKs).
You may want to opt for the SDKs when you prefer using Veriff's front-end solution and built-in verification flow, and have no plans to independently collect end-user media.
Quick overview of the steps
- Add the relevant Veriff SDK to your project
- Create an integration (guide above)
- Configure webhooks (guide below)
- Create a verification session to get the session URL (guide below)
- Pass the session URL to the SDK
- Direct the end-user to the verification flow, where they submit their data and media
- End-user's data and media passed to Veriff
- Veriff verifies the end-user
- Veriff returns the decision via webhook
Using the API to generate a session for the SDK
First refer to the Prerequisites to create API requests and the Backwards compatible changes sections to make sure you have all you need to start sending API requests.
- Make a POST /sessions call:
- Send the object to
https://<BaseURL>/v1/sessions
- Include the Content-Type
application/json
header - Include the X-AUTH-CLIENT header containing your integration's API key
- Include the callback URL in
verification.callback
for Redirect end-users - Include the
vendorData
parameter (optional, but strongly recommended)
- Send the object to
- From the response you need to take:
- The unique session ID in
verification.id
, important for webhooks and for identifying the session later on - The unique session URL in
verification.url
, required to bring the end-user into the flow - Also, we recommend storing the unique
vendorData
parameter, which is important for improved fraud detection, webhooks, and for identifying the session later on
- The unique session ID in
Request example
{
"verification": {
"callback": "https://veriff.com",
"vendorData": "2bf528f7-4b9c-44f0-b928-fdc7afc5ca1b"
}
}
Response example
{
"status": "success",
"verification": {
"id": "b27afb60-1455-4927-afb6-fc27a60e1455",
"url": "https://....",
"vendorData": "2bf528f7-4b9c-44f0-b928-fdc7afc5ca1b",
"host": "https://....veriff.com",
"status": "created",
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....."
}
}
What happens after the end-user leaves the verification flow?
When the end-user leaves the verification flow, the following scenarios apply.
Android, iOS, Flutter and React Native
When a session is canceled or finished, the Veriff SDK is closed. The end-user is taken back to your application.
Also, the end-user flow completion status is returned to the host application via callback or delegate method, depending on the SDK type. Note that this status shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
Refer to each SDK for more info about the callback or delegate methods:
- Android: the
onActivityResult()
callback, see here - iOS: the
func sessionDidEndWithResult(_ result: Veriff.Result)
delegate method, see here - Flutter: the
start
method, see here - React Native: the
launchVeriff
method, see here
InContext JS (Iframe and Embedded)
When a session is canceled or finished, the InContext SDK emits the CANCELED
or FINISHED
events. It is up to you
to decide what happens (close, redirect) in the SDK when the events are triggered.
See here for more info about the onEvent
callback that will return the
end-user flow completion status.
Redirect
When a session is canceled or finished, we try to redirect the end-user to the callback URL, or close the browser if the callback URL is not present.
SDK sessions lifecycle diagram
Quick guide of the IDV using the API
This section is a quick intro into doing identity verification (IDV) when using the Application Programming Interface (API) calls.
In case of using the API, you are collecting the end-user's data and/or media yourself via your own solution, and then use Veriff's API endpoints to pass us relevant data for verification.
The most important prerequisite to send end-user's data to Veriff is the session ID aka the value in the
POST /sessions response verification.id
field. This is used in all the calls made for the specific session
(refer to the Endpoints), and it is used to get the webhook responses for the session.
Quick overview of the steps
- Create an integration (guide above)
- Configure webhooks (guide below)
- Create a verification session to get the session ID (guide below)
- Using the session ID, pass end-user's media via POST sessions/{sessionId}/media
- Patch the session to
submitted
using PATCH sessions/{sessionId} - Veriff verifies the end-user
- Veriff returns the decision via webhook
Note that collecting end-user's data beforehand or during the flow is optional, as Veriff can extract this data from the media sent to us.
Using the API to generate a session for API
First refer to the Prerequisites to create API requests and the Backwards compatible changes sections to make sure you have all you need to start sending API requests.
- Make a POST /sessions call:
- Send the object to
https://<BaseURL>/v1/sessions
(required) - Include the Content-Type
application/json
header (required) - Include the X-AUTH-CLIENT header containing your integration's API key (required)
- Include the end-user's data/media you have collected (refer to the Request properties explained in POST /sessions) (optional)
- Include the
vendorData
parameter (optional, but strongly recommended)
- Send the object to
- In the response, you will receive a JSON with:
- The unique session ID in
verification.id
, important for webhooks and for identifying the session later on
- The unique session ID in
Request example
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "12-03-1989"
},
"document": {
"number": "B01234567",
"type": "PASSPORT",
"country": "EE"
},
"address": {
"fullAddress": "Lorem Ipsum 30, 12345 Tallinn, Estonia"
},
"vendorData": "2bf528f7-4b9c-44f0-b928-fdc7afc5ca1b"
}
}
Response example
{
"status": "success",
"verification": {
"id": "b27afb60-1455-4927-b155-0260ffe0947a",
"url": "https://....",
"vendorData": "2bf528f7-4b9c-44f0-b928-fdc7afc5ca1b",
"host": "https://....veriff.com",
"status": "created",
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....."
}
}
API sessions lifecycle diagram
Generating session manually
It is possible to manually generate a verification session in the Veriff environment. This option can be used to test or debug sessions, or as a manual fallback option.
Using this option, you can generate a link and a QR code, and share them with the end-user.
- Go to the Veriff environment
- Click on the Verifications on the top menu
- Click on the Add Verification button
- Find and open the relevant integration
- Fill in the first name, last name
- Click Generate Verification
- Click on Share to copy the URL or QR image onto a clipboard
Setting up webhooks
In order to receive responses from Veriff services, you need to configure webhooks. Refer to the Webhooks section for a thorough overview.
To configure the webhook endpoint:
- Go to the Veriff environment
- Click on the Integrations on the top menu
- Find and open the relevant integration
- Navigate to the Settings tab on the integration's page
- Fill in the webhook URL input field with the URL where your endpoint is accepting payloads from Veriff
There are several types of webhooks. Veriff will post payloads to respective webhook URLs.
Note that the image below does not contain all the possible webhook URLs. The list available depends on your integration.
Verification session statuses
Once the end-user has gone through the flow, we return the session status and the status code.
Session statuses explained
Identity verification session status is one of:
approved
resubmission_requested
declined
expired
abandoned
review
For the aforementioned verification statuses, the status code is one of 9001, 9102, 9103, 9104, 9121. All codes and explanations can be found in the Verification session decision codes table.
Responses 9001, 9102, 9121 and 9104 are conclusive responses. The session is closed and the URL is not available for the end-user.
Response 9103 is an inconclusive response. The session remains open until you receive one of the above conclusive responses. The session is re-opened for the end-user, accepting a new attempt.
Fetching the session statuses
The session status is available in the verification.status
parameter in:
- Decision webhook payload
- POST /sessions response
- GET /sessions/{sessionId}/attempts response
- GET /sessions/{sessionId}/decision response
Verification decisions
Once the end-user has gone through the verification flow and the verification process is complete, the session receives a decision. The end user is approved, declined, or asked to resubmit.
Decisions explained
We share with you the reasons why the end-user was declined or asked to resubmit:
- Common decision reason codes table can be found here
- More granular decision reason codes table can be found here
Triggering decisions manually for testing
There are two ways to trigger decisions for test integration sessions.
In the Veriff environment. Refer to this article [↗] in the Knowledge Base (requires a login to the Veriff environment).
Generate a session using the POST /sessions call and pass "Approve", "Decline" or "Resubmit" in the
firstName
field. Refer to this article [↗] in the Knowledge Base (requires a login to the Veriff environment).
Fetching the decision
There are several options to fetch the decision(s) of a verification session:
- Manually: the Verifications page in the Veriff environment displays sessions' details, including the decisions made
- Use the decision webhook, for which you need to specify the Webhook URL in the Veriff environment and implement a listener
- Query the GET /sessions/{sessionId}/decision endpoint
Full Auto solution with insights and extractions
Use the Full Auto webhook, but note that in this case, the "decision" is the system's suggestion about what to do with the session.
Also, querying GET /sessions/{sessionId}/decision endpoint will not return data about the session, the payload will be empty. Contact your Solutions Engineer for more info.
Verification session events
Event statuses and codes are sent to notify you about the progress of the data gathering process during the verification session. For more info, see the Event webhook section.
Backwards compatible changes
All the changes listed below are considered to be backwards compatible by Veriff. Make sure to set up your systems in such flexible manner that it is able to handle these changes.
- Adding new properties (e.g., strings, objects, arrays) to existing API responses
- Changing the order* of properties in existing API responses, i.e., the order of strings, objects, arrays
- Adding new API resources, e.g., adding new API endpoints
- Adding new optional request parameters to existing API endpoints
- Changing the length or format of opaque** strings, such as error messages, object IDs, etc.
- Adding new event types to webhooks
- Adding new properties (e.g., strings, objects, arrays) to webhook payloads
- Webhook listener should gracefully handle unfamiliar event types
*As a general note on the order of properties in the responses, keep in mind that the order is not static. This means that the order you see in your API call responses may differ from the order you see in Veriff documentation.
**This means data that your system should be able to just transmit or store, not interpret.
Try our demos
Web
To try out the end-user facing verification flow, navigate to Veriff Demo [↗]. Opening the link will start the verification flow in your browser.
Mobile SDKs
Our mobile SDKs can be tested by downloading the demo versions: iOS / Android [↗]
Review Verifications
To review the submitted verification and its results, visit the Veriff environment and open the individual verification session to see the details.
Browser support for verification flow
Supported browsers
Desktop
- Google Chrome
- Mozilla Firefox
- Safari
- Microsoft Edge (Chromium based)
- Opera
- Yandex Browser
In addition to the listed browsers other Chromium based browsers may work.
iOS
- Safari
- On iOS 14.3 and newer iOS versions all browsers are supported.
Android
- Google Chrome
- Mozilla Firefox
- Samsung Browser
- Opera
In addition to the listed browsers other Chromium based browsers may work.
Not supported browsers
A list of browsers which are not supported currently and that we can not support unless there are browser side changes implemented by the browser provider:
Android
- Xiaomi browser
- UC Browser
- Facebook webview
iOS
- All Non-Safari iOS browsers on iOS versions prior to 14.3.
Allowlisted URLs and IP addresses
To ensure uninterrupted access to our services, it is important that your network firewall configurations permit communication with our servers. This involves allowing specific IP addresses and URLs to establish a secure and reliable connection.
Allowlisted URLs
To facilitate smooth service operations, we request allowing all traffic coming from the following domains:
*.veriff.me
*.veriff.com
Allowlisted IP addresses
IPs for US zone
100.20.120.34
52.25.243.218
54.148.105.103
54.218.205.80
IPs for EU zone
34.254.42.181
34.242.213.89
52.19.226.239
Floating IPs range
3.251.215.160/27
That means the range to be allowed is: 3.251.215.160
to 3.251.215.191
Test the API Collection in Postman
It is possible to test the Veriff API v1.0 Collection in Postman. Click on the button below to get started.
Integrations Test Guide
You will have one Test integration pre-created for you in the Veriff environment. You can create more test integrations if needed. The test integration will be used by you to test the communication between Veriff's and your system and to see how the responses are handled.
To check the quality of Veriff's responses, and you are already set up with Veriff, please talk to you Solutions Engineer. If not, please select plan and subscribe to a free trial on Plans [↗] page. After you activate the free trial and log in to the Veriff environment you are allowed to create Live integrations.
Testing verification sessions checklist
- New session link is generated
- Session data is saved with your record
- Sessions with odd names can be started
- Sessions with
vendorData
- do you get them back and do you perform actions on them - Sessions with
endUserId
- do you get them back and do you perform actions on them - End-user is granted access to your platform after receiving an
Approved
decision - End-user is notified about verification failure after receiving
Resubmission
orDeclined
decision - End-user is prompted to try again after receiving
Resubmission
decision. Note that the end-user has 9 resubmission attempts, the 10th attempt is an automatic decline. See the note here for more info. - In case of resubmitted session, end-user is directed to same
sessionURL
- In case of disrupted session (browser close, end-user logout, etc.,), the end-user should be directed back to earlier session
- In case generated session is over 7 days old (and thus in
Expired
orAbandonded
status), a new session is generated - At end of verification,
callbackURL
redirects back to the correct place in your platform
Also see our support article for getting the desired test verification result [↗]
Testing security
- A webhook with wrong API key should not be accepted
- A webhook with mismatched X-HMAC-SIGNATURE should not be accepted
- A webhook with invalid JSON should not break or crash your server
Testing responses
Each type of response should be accepted:
- Approved (Decision endpoint)
- Declined (Decision endpoint)
- Resubmission (Decision endpoint)
- Review (Decision endpoint)
- Expired (Decision endpoint)
- Abandoned (Decision endpoint)
Explanations and availability of these have been listed in the session status and decision codes tables > decision codes 9001 to 9121.
Testing process in your app
You should test the handling of best cases as well as edge cases:
- Approved end-users handled or notified as appropriate
- Declined end-users handled as appropriate, your back office notified if necessary
- In case of resubmission request, end-user is invited back to try KYC again using the same
sessionURL
- In case of
Expired
orAbandoned
session (after 7 days), end-user is not offered to continue from same session, newsessionURL
is created
Mobile testing
Test our demo app by downloading it in the app store. iOS / Android [↗]
API Upload testing
Required tools
- Veriff's integration demo: js-integration-demo-master.zip (clicking the link will start the download)
- Node.js (download from Node.js org [↗])
- Notepad/TextEdit (default in Windows/Mac) or Notepad++ (download from Notepad++ [↗])
Step by step
- Download and install Node.js
- Download and extract js-integration-demo-master.zip
- Open Command (Windows) or Terminal (Mac) on your local computer.
- Navigate to js-integration-demo-master folder
cd C:\Users\User\Desktop\Veriff API).
- Run command >npm install
- Open app.js with your text editing app (Notepad/TextEdit) and update 'API-Public-Key' and 'API-Private-Key' to the values in your Backoffice account (Management -> Vendor). Tokens must be in single quotes. Save the file.
const API_TOKEN = process.env.API_TOKEN || 'API-Public-Key';
const API_SECRET = process.env.API_SECRET || 'API-Private-Key';
const API_URL = process.env.API_URL || 'https://api.staging.vrff.io/v1';
const WEBHOOK_PORT = process.env.WEBHOOK_PORT || 3002;
const IMAGE_DIR = process.env.IMAGE_DIR || 'documents'
Run the app.js
node app.js
Now the verification session is created and it is being processed. Check your Backoffice dashboard to review the data extracted and decision made by Veriff.
Batch testing
Batch upload tests are sometimes agreed with our onboarding team and are very use case specific. Therefore, below might be not applicable for the majority of customers. For batch tests, customers will need to prepare dataset that will be used for testing. If you have been asked for dataset, please see batch test data preparation guide [↗].
End-User In The Flow
Session Status Diagram
SDK Guide
Why use the SDK?
Veriff Software Development Kits (SDKs) can be opted for if you prefer leveraging Veriff's front-end solution, wish to maximize the benefits of our built-in verification flow, and have no plans to independently collect end-user media.
SDKs are quite straightforward to integrate with, as they have pre-built components and libraries. Veriff handles SDKs' updates and maintenance, to ensure improvements and bug fixes.
SDKs allow gathering lots of different data, thus supporting enhanced fraud detection abilities. Examples here are video recording and liveness checks.
Once integrated into your project, the SDK allows you to customize the solution's appearance by adding your unique branding elements and colors.
Veriff supports the following SDKs
Native
Web
SDK customization guides
It is possible to change the look of the end-user flow in both native SDKs and the web flow to be more aligned with your brand.
See the Veriff Native SDKs customization guide [↗] document to see the options, and read the customization guide in each SDKs section for further info.
See the Veriff Web SDKs customization guide [↗] document to see the options.
Prerequisites to use the SDKs
Before you can launch the verification flow for your end-users, make sure you have:
- Added the SDK to your project (see below for detailed descriptions of each SDK integration)
- Created the integration in the Veriff environment (guide above)
- Configured the webhooks (guide below)
- Created a verification session to get the unique session URL (see the SDKs getting started section for instructions)
- Made sure that you are able to handle the backwards compatible changes
- Familiarized yourself with and adhere to the requirements to declare data collection purposes [↗] in your applications
Android SDK
Android SDK Requirements
The Veriff Android SDK has the following constraints and requirements:
minSdkVersion
is 26.- Kotlin
1.7.21
or above. - Supports
android-gradle-plugin
version7.2.0
and above. - The SDK is using AndroidX support libraries.
List of all direct transitive dependencies:
androidx.annotation:annotation-experimental:1.1.0
androidx.annotation:annotation:1.7.1
androidx.appcompat:appcompat:1.6.1
androidx.concurrent:concurrent-futures:1.1.0
androidx.constraintlayout:constraintlayout:2.1.4
androidx.core:core-ktx:1.9.0
androidx.core:core:1.9.0
androidx.databinding:viewbinding:8.6.1
androidx.exifinterface:exifinterface:1.3.7
androidx.fragment:fragment-ktx:1.5.7
androidx.lifecycle:lifecycle-common:2.5.1
androidx.lifecycle:lifecycle-livedata:2.5.1
androidx.lifecycle:lifecycle-runtime-ktx:2.5.1
androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1
androidx.vectordrawable:vectordrawable-seekable:1.0.0-beta01
com.google.android.gms:play-services-mlkit-face-detection:17.1.0
com.google.android.material:material:1.4.0
com.google.auto.value:auto-value-annotations:1.7
com.google.dagger:dagger:2.45
com.google.guava:listenablefuture:1.0
com.squareup.okhttp3:logging-interceptor:4.10.0
com.squareup.okhttp3:okhttp:4.10.0
com.squareup.okio:okio-jvm:3.2.0
com.squareup.okio:okio:3.2.0
org.bouncycastle:bcprov-jdk18on:1.76
org.bouncycastle:bcutil-jdk18on:1.76
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.21
org.jetbrains.kotlin:kotlin-stdlib:1.7.21
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
Adding the Android SDK
Open the root build.gradle
file and add a new maven destination to the repositories in the allprojects section:
allprojects {
repositories {
maven { url "https://cdn.veriff.me/android/" }
google()
mavenCentral()
}
}
Alternatively, when using Gradle 7+, add the Maven repository to your settings.gradle
file:
dependencyResolutionManagement {
repositories {
maven { url "https://cdn.veriff.me/android/" }
google()
mavenCentral()
}
}
Add the Veriff SDK dependency to the application build.gradle
file:
implementation 'com.veriff:veriff-library:6.+'
Permissions
The SDK will request all the permissions it needs, please make sure that the CAMERA, RECORD_AUDIO permissions are not explicitly removed using tools:node="remove"
in your app`s manifest file. Ignore this if you are not explicitly removing any permissions.
Declare foreground service sync for Google Play
The SDK declares and uses the FOREGROUND_SERVICE_DATA_SYNC
. If you distribute your application on Google Play,
then you must declare the foreground service information in Play Console [↗].
The information required by Play Console is (as listed on the Google Play link above):
- Provide a description of the app functionality that is using each foreground service type.
- The Veriff SDK uses the foreground service to upload end-user data to Veriff's servers for verification purposes.
- Describe the user impact if the task is deferred by the system (does not start immediately), and/or the task is interrupted by the system (paused and/or restarted).
- If the task is deferred or interrupted by the system, the end-user verification will be delayed.
- Include a link to a video demonstrating each foreground service feature. The video should demonstrate the steps the user needs to take in your app in order to trigger the feature.
- Please record a video of your app's Veriff SDK integration.
- Choose your specific use case for each foreground service type.
- "Network transfer: Upload or download / Other"
See also Veriff's note on data collection purposes in your app [↗]
Starting the verification flow
The verification flow must be launched from the vendor Activity class with a unique session. A session is valid for 7 days and expires automatically after that.
import com.veriff.Sdk;
Intent intent = Sdk.createLaunchIntent(activity, sessionUrl);
startActivityForResult(intent, REQUEST_CODE);
Parameters are defined as below;
Parameters | Description |
---|---|
sessionUrl |
Required parameter. sessionUrl can be received from your backend implementation. sessionUrl should be unique for each call. Check /sessions endpoint in the API documentation here to learn how to generate one. |
REQUEST_CODE |
Define an integer constant REQUEST_CODE in your activity which can be used to compare in onActivityResult |
Customizing the SDK
Setting a theme (Optional)
You can customize the look and feel of the SDK flow by passing a Branding
object via Configuration
to createLaunchIntent
as shown in the example below.
Branding branding = new Branding.Builder()
.logo(R.drawable.logo)
// Screen and dialog background color
.background(getResources().getColor(R.color.background_color))
// Non-surface content (such as text, icons) displayed on `background`.
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `background`
.onBackground(getResources().getColor(R.color.on_background_color))
// Secondary non-surface content (such as text) displayed on `background`.
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `background`
.onBackgroundSecondary(getResources().getColor(R.color.on_background_secondary_color))
// Tertiary non-surface content (such as text) displayed on `background`.
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `background`
.onBackgroundTertiary(getResources().getColor(R.color.on_background_tertiary_color))
// Primary surfaces (such as buttons) displayed on `background`.
// Accessibility: Must have a contrast ratio of at least 3:1 vs `background`
.primary(getResources().getColor(R.color.primary_color))
// Non-surface content (such as text) displayed on `primary` surfaces.
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `primary`
.onPrimary(getResources().getColor(R.color.on_primary_color))
// Secondary surfaces (such as bullet points and illustrations) displayed on `background`.
// Accessibility: Must have a contrast ratio of at least 3:1 vs `background`
.secondary(getResources().getColor(R.color.secondary_color))
// Non-surface content (such as text) displayed on `secondary` surfaces.
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `secondary`
.onSecondary(getResources().getColor(R.color.on_secondary_color))
// Backgroung color of the overlay area on all the screens with camera
.cameraOverlay(getResources().getColor(R.color.camera_overlay_color))
// All UI elements on all the screens with camera on top of camera overlay
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `cameraOverlay`
.onCameraOverlay(getResources().getColor(R.color.on_camera_overlay_color))
// Color used for various outlines and boundaries of UI elements
.outline(getResources().getColor(R.color.outline_color))
// Error indicators (such as text, borders, icons) displayed on `background`
// Accessibility: Must have a contrast ratio of at least 4.5:1 vs `background`
.success(getResources().getColor(R.color.success_color))
// Success indicators (such as borders, icons) displayed on `background`
// Accessibility: Must have a contrast ratio of at least 3:1 vs `background`
.error(getResources().getColor(R.color.error_color))
// Button corner radius, in `dp`
.buttonRadius(48f)
.build();
Configuration configuration = new Configuration.Builder()
.branding(branding)
.build();
Intent intent = Sdk.createLaunchIntent(activity, sessionUrl, configuration);
startActivityForResult(intent, REQUEST_CODE);
All custom values for branding are optional. If a value is not provided for them the default Veriff color or icon will be used.
More customization options
Customizing the font
You can customize the fonts used in the SDK by passing the resource IDs of the fonts you want to use. Make sure that you have added the font files to the font
resource folder in your app.
A custom font can be set by passing a com.veriff.Font
object to the font
method of Branding
builder. The com.veriff.Font
builder accepts 3 types of fonts via the setRegular
setMedium
and setBold
methods.
brandingBuilder.font(
new com.veriff.Font.Builder()
.setRegular(R.font.comic_neue_regular)
.setMedium(R.font.comic_neue_medium)
.setBold(R.font.comic_neue_bold)
.build()
);
Custom intro screen
Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers. First, please ask about this possibility from your solutions engineer. In case we can offer it for you then removal process is following:
- You agree your own introduction screen visuals and copy with our solutions engineer and get relevant legal documents signed in case they are needed.
- After that Veriff will enable custom introduction screen from backend for your integrations.
- After you have implemented your own introduction screen you can change the configuration option specified below.
Configuration configuration = new Configuration.Builder()
.customIntroScreen(true)
.build();
Note: Adding the configuration alone in your app is not enough to enable the custom intro screen. Make sure to contact your solutions engineer so they can enable the feature for your integration.
Setting a locale for the SDK (Optional)
You can set a locale(java.util.Locale
) for the SDK from the app itself.
Locale appLocale = Locale.ENGLISH;
Configuration configuration = new Configuration.Builder()
.locale(appLocale)
.build();
Intent intent = Sdk.createLaunchIntent(activity, sessionUrl, configuration);
startActivityForResult(intent, REQUEST_CODE);
Adding vendor data
Veriff supports the option to override vendor data. Please check with your Solutions Engineer to confirm if this feature can be enabled for your integration. If it is possible, follow these steps:
- Veriff will enable vendor data overriding from the backend for your integrations.
- Modify the configuration option as specified below.
Configuration configuration = new Configuration.Builder()
.vendorData("Vendor Data")
.build();
Note: Enabling this feature alone will not be sufficient to override the vendor data. Ensure that you contact your Solutions Engineer to have the feature enabled for your integration.
Getting the verification status
Veriff SDK sends callbacks to your mobile application. To capture the result override the onActivityResult
method in your activity that started the verification flow.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
Result result = Result.fromResultIntent(data);
if (result != null) {
handleResult(result); //see below for handling the result
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void handleResult(Result result) {
switch (result.getStatus()) {
case DONE:
// Session is completed from the end-user's perspective
break;
case CANCELED:
// End-user cancelled the session
break;
case ERROR:
// An error occurred during the flow, Veriff has already shown UI, no need to display
// a separate error message here
Log.w(TAG, "Verification error occurred: " + result.getError());
break;
}
}
Adding error logging
To turn on logging, simply add your logging implementation instance (instance of com.veriff.Logger
class) to the SDK before launching the SDK as shown.
Sdk.setLogger(myLoggerImplementation);
Intent intent = Sdk.createLaunchIntent(activity, sessionUrl);
startActivityForResult(intent, REQUEST_CODE);
Excluding ML Kit support
Veriff Android SDK uses ML Kit [↗] for things like automatic selfie capture and
accessibility feedback to improve the end-user experience. It uses on-device models that are
pre-downloaded by Play services. If your app cannot use Play services at all then you can exclude the
transitive mlkit
dependency - this will remove any dependencies on ML Kit and disable the use of these ML modules
at runtime:
implementation('com.veriff:veriff-library:7.+') {
exclude group: 'com.veriff', module: 'mlkit'
}
Android SDK Changelog
Please refer to release notes [↗].
Migrating Veriff Android SDK from 5.x.x to 6.0.0
SDK integration
The following APIs were removed:
Branding.Builder.themeColor(color)
- this was split into two different attributes:Branding.Builder.primary(color)
&Branding.Builder.secondary(color)
Branding.Builder.logomark(drawable)
Branding.Builder.primaryButtonBackgroundColor(color)
- the button background will be set based on the newBranding.Builder.onPrimary(color)
attributeBranding.Builder.bulletPoint(color)
- bullet point color can be controlled by the newBranding.Builder.secondary(color)
&Branding.Builder.onSecondary(color)
attributesBranding.Builder.notificationIcon(color)
The following APIs were renamed:
Branding.Builder.toolbarIcon(drawable)
- renamed toBranding.Builder.logo(drawable)
Branding.Builder.backgroundColor(color)
- renamed toBranding.Builder.background(color)
Branding.Builder.primaryTextColor(color)
- renamed toBranding.Builder.onBackground(color)
Branding.Builder.secondaryTextColor(color)
- renamed toBranding.Builder.onBackgroundSecondary(color)
Branding.Builder.buttonCornerRadius(cornerRadius)
- renamed toBranding.Builder.buttonRadius(cornerRadius)
The following APIs were added:
Branding.Builder.onBackgroundTertiary(color)
Branding.Builder.primary(color)
Branding.Builder.onPrimary(color)
Branding.Builder.secondary(color)
Branding.Builder.onSecondary(color)
Branding.Builder.outline(color)
Branding.Builder.error(color)
Branding.Builder.success(color)
Migrating Veriff Android SDK from 4.x.x to 5.0.0
SDK integration
The following APIs were removed:
Branding.Builder.buttonHeight(height)
- buttons are now always with a60dp
heightBranding.Builder.statusBarColor(color)
- the status bar is now using thebackgroundColor
attribute insteadBranding.Builder.externalResources(externalResources)
- resources can be customized viatoolbarIconProvider()
,toolbarIcon()
and the newlogomark()
method.Font.Builder.setNormalAndBold(normal, bold)
- this was split into separate setters for font weights
The following APIs were added:
Branding.Builder.logomark(drawable)
- Sets a drawable to use in UI elements where a square logo is needed. (Defaults to the Veriff logomark when this attribute is not set)Font.Builder.setRegular(regularFont)
- Sets regular weight fontFont.Builder.setMedium(mediumFont)
- Sets medium weight fontFont.Builder.setBold(boldFont)
- Sets bold weight font
Migrating Veriff Android SDK from 3.x.x to 4.0.0
Follow these steps to migrate from SDK 3.x.x
to 4.0.0
Android Gradle Plugin
Open the root build.gradle
file and change the classpath
dependency in the buldscript
section if that needed.
groovy
buildscript {
repositories {
...
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1' // and above
...
}
}
Kotlin
Open the root build.gradle
file and change the classpath
dependency in the buldscript
section if that needed.
buildscript {
ext.kotlinVersion = '1.4.0' // and above
repositories {
...
}
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
...
}
}
Proguard
Open the root build.gradle
file and add the force update
to the buildscript
section if that needed.
groovy
buildscript {
...
configurations.all {
resolutionStrategy {
force 'net.sf.proguard:proguard-gradle:6.2.2'
}
}
}
SDK integration
Nothing changed in SDK except the public API types, please update the imports to
java
import com.veriff.Branding;
import com.veriff.Configuration;
import com.veriff.Font;
import com.veriff.Result;
import com.veriff.Sdk;
and change types from
VeriffBranding
to Branding
VeriffConfiguration
to Configuration
VeriffFont
to Font
VeriffResult
to Result
Migrating Veriff Android SDK from 2.x.x to 3.0.0
Follow these steps to migrate from SDK 2.x.x to 3.0.0
Switch to AndroidX
Veriff SDK 3.0.0 requires AndroidX 1.0.0 or later. If you haven't switched to AndroidX in your app yet then follow this guide [↗].
Enable Java 8
Veriff SDK 3.0.0 requires Java 8 language features to be enabled in your project. If you don't have this enabled already then add this to your app/build.gradle
file under the android {}
section:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
See more here [↗].
Switch from baseUrl
and sessionToken
to sessionUrl
The new 3.0.0 SDK requires a single sessionUrl
parameter instead of baseUrl
and sessionToken
. See the documentation here. As a backwards compatibility measure, if a sessionToken
value is passed into the sessionUrl
parameter then it will still work with an assumed baseUrl
of magic.veriff.com
.
Use com.veriff.*
classes instead of mobi.lab.veriff.data.*
ones
The name and location of the main SDK entry class has changed from mobi.lab.veriff.data.Veriff
to com.veriff.VeriffSdk
. The API is largely similar - instead of Veriff.Builder
there's a VeriffSdk.createLaunchIntent
method that returns an Intent
which you can then use to launch veriff. See example here.
If you are using Branding
to customize the look and feel of the SDK then it has a new name - VeriffBranding
. The builder interface has been streamlined by removing the set*
prefixes from all the methods. Read more about customization here.
Use com.veriff.VeriffResult
instead of reading return Intent
directly
Starting with 3.0.0 there's a new way to handle the result of the verification flow. Instead of reading INTENT_EXTRA_STATUS
directly from the returned data
intent, use VeriffResult.fromResultIntent(data)
to get a result object with a status
field and an optional error
field. We've reduced status
to just three - CANCELED, ERROR, DONE
. In case of ERROR
the error
field contains more information. See the example here.
Remove usage of deprecated types
While the old SDK entrypoints are still present for backwards compatibility they will be removed in the future. Please remove usage of any SDK type marked with @Deprecated
- the easiest way to discover these is to look at your Gradle build log with Java/Kotlin compilation warnings turned on.
Here's a list of old deprecated classes due to be removed in a future release:
mobi.lab.veriff.data.Veriff
mobi.lab.veriff.data.Veriff.Builder
mobi.lab.veriff.data.VeriffConstants
mobi.lab.veriff.data.Branding
mobi.lab.veriff.data.Branding.Builder
mobi.lab.veriff.data.DrawableProvider
mobi.lab.veriff.util.LogAccess
mobi.lab.veriff.util.LogAccess.LogLevel
mobi.lab.veriff.util.LogcatLogAccess
mobi.lab.veriff.service.VeriffStatusUpdatesService
iOS SDK
iOS SDK Requirements
Integration Veriff iOS SDK requires at least iOS version 13.0
Adding the SDK to the project
VeriffSDK requires the latest stable version of Xcode available at the time the release is made. If you would like to use versions that are independent of Swift versions, please integrate .xcframework
.
Using Swift Package Manager
To integrate Veriff SDK with Swift Package Manager, open File > Swift Packages > Add Package Dependency and add the Veriff iOS SDK Swift Package repository url as stated below;
https://github.com/Veriff/veriff-ios-spm/
Using Cocoapods
To integrate Veriff SDK with Cocoapods, please add the line below to your Podfile and run pod install
.
New to Cocoapods? Learn more here [↗].
pod 'VeriffSDK'
After installation is done, use the newly created .xcworkspace
file of your project.
Using Carthage
To integrate VeriffSDK into your Xcode project using Carthage, specify the required libraries below in your Cartfile
.
binary "https://cdn.veriff.me/ios/carthage/VeriffSDK.json"
Run carthage update --use-xcframeworks
and then drag and drop Veriff.xcframework from Carthage/Build
folder to the Frameworks, Libraries,
and Embedded Content section on your app target's General settings tab.
Using XCFramework
To integrate Veriff SDK into your project manually, please download VeriffSDK [↗].
After the download finishes, drag and drop the unzipped Veriff.xcframework to the Frameworks, Libraries, and Embedded Content section on your app target's General settings tab.
Adding permissions
Add usage descriptions to application Info.plist
Not adding these usage descriptions causes system to kill application when it requests the permissions when needed.
Veriff iOS SDK requires camera, microphone, photo library and optionally NFC reader permissions for capturing photos,
video and scanning passport during identification. Your application is responsible to describe the reason why camera,
microphone, photo library and NFC reader is used. You must add 3 descriptions listed below to Info.plist
of your
application with the explanation of the usage.
NSCameraUsageDescription
NSMicrophoneUsageDescription
NSPhotoLibraryUsageDescription
Add required steps for NFC scanning
- Add
NFCReaderUsageDescription
description toInfo.plist
. - The application needs to define the list of application IDs or AIDs it can connect to, in the Info.plist file.
The AID is a way of uniquely identifying an application on a ISO 7816 tag, which is usually defined by a standard.
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>A0000002471001</string> <string>A0000002472001</string> <string>00000000000000</string> </array>
Introduce a new entitlement for NFC scanning. Xcode automatically adds this entitlement when you activate the Near Field Communication Tag Reading feature in the target Signing & Capabilities. Following the activation of this feature, the *.entitlements file should include the TAG format.
<key>com.apple.developer.nfc.readersession.formats</key> <array> <string>TAG</string> </array>
Note: due to Apple's policies, you may be required to record and share a proof video of using the NFC. You can download and use this pre-recorded video [↓]. If this does not solve the issue, please contact our support team.
Declare the purposes of data collection in your app
See Veriff's note on data collection purposes [↗]
Starting verification flow
Import Veriff in your code
// Swift
import Veriff
// Objective-C
@import Veriff;
In order to use Veriff SDK, please import it to your class that will use the SDK.
Start the verification flow
In order to start the verification flow please call the method below with the defined parameters.
// SwiftUI
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl)
// Swift
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl, presentingFrom: yourViewController)
// Objective-C
VeriffSdk *veriff = [VeriffSdk shared];
[veriff startAuthenticationWithSessionUrl:sessionUrl presentingFrom:yourViewController];
Parameters are defined as below;
Parameters | Description |
---|---|
sessionUrl |
Required parameter. sessionUrl can be received from your backend implementation. sessionUrl should be unique for each call. Check /sessions endpoint in the API documentation here to learn how to generate one. |
configuration |
Optional VeriffConfiguration object. Refer to Customize user interface (Optional) for how to use it. |
presentingFrom |
Your app's view controller from which our UI will be presented modally. It's optional and shouldn't be used in SwiftUI projects. |
Customize user interface (Optional)
Setting theme color, font and logo
You can customize the Veriff user interface through your own application, by letting the SDK know of your brand's main color, font and logo. The Branding
class allows customization of the navigation bar title image, button corner radius, font and following colors:
background
- screen and dialog backgroundonBackground
- non-surface content (such as text, icons) displayed on thebackground
coloronBackgroundSecondary
- secondary non-surface content (such as text) displayed on thebackground
coloronBackgroundTertiary
- tertiary non-surface content (such as text) displayed on thebackground
colorprimary
- primary surfaces (such as buttons) displayed on thebackground
coloronPrimary
- non-surface content (such as text) displayed onprimary
surfacessecondary
- secondary surfaces (such as bullet points and illustrations) displayed on thebackground
coloronSecondary
- non-surface content (such as text) displayed onsecondary
surfacescameraOverlay
- overlay surface color on top of the camera preview screenonCameraOverlay
- non-surface content (such as text, icons) displayed oncameraOverlay
outline
- outlines and boundaries of UI elements (such as text inputs)error
- error indicators (such as text, borders, icons) displayed onbackground
colorsuccess
- success indicators (such as borders, icons) displayed onbackground
color
In order to use customization set the branding
property of VeriffConfiguration
before you start the verification.
See the Veriff SDK customization guide [↗] document to see what it looks like.
// Swift
let branding = VeriffSdk.Branding()
branding.logo = UIImage(named: "logo.png")
branding.background = UIColor.background
branding.onBackground = UIColor.onBackground
branding.onBackgroundSecondary = UIColor.onBackgroundSecondary
branding.onBackgroundTertiary = UIColor.onBackgroundTertiary
branding.primary = UIColor.primary
branding.onPrimary = UIColor.onPrimary
branding.secondary = UIColor.secondary
branding.onSecondary = UIColor.onSecondary
branding.cameraOverlay = UIColor.cameraOverlay
branding.onCameraOverlay = UIColor.onCameraOverlay
branding.outline = UIColor.outline
branding.error = UIColor.error
branding.success = UIColor.success
branding.buttonRadius = CGFloat.cornerRadius
branding.font = VeriffSdk.Branding.Font(regular: "Font", medium: "Font-Medium", bold: "Font-Bold")
// Objective-C
VeriffBranding *branding = [[VeriffBranding alloc] init];
branding.logo = [UIImage imageNamed:@"logo.png"];
branding.background = [UIColor background];
branding.onBackground = [UIColor onBackground];
branding.onBackgroundSecondary = [UIColor onBackgroundSecondary];
branding.onBackgroundTertiary = [UIColor onBackgroundTertiary];
branding.primary = [UIColor primary];
branding.onPrimary = [UIColor onPrimary];
branding.secondary = [UIColor secondary];
branding.onSecondary = [UIColor onSecondary];
branding.cameraOverlay = [UIColor cameraOverlay];
branding.onCameraOverlay = [UIColor onCameraOverlay];
branding.outline = [UIColor outline];
branding.error = [UIColor error];
branding.success = [UIColor success];
branding.buttonRadius = 5;
branding.font = [[VeriffBrandingFont alloc] initWithRegular: @"Font" medium: @"Font-Medium" bold: @"Font-Bold"];
For optimal results, we recommend that the height of your custom logo image be kept under 40 points, and the width under 90 points. If your logo exceeds these dimensions, it will be compressed while preserving its original aspect ratio.
Setting the user interface language
The Veriff iOS SDK allows setting the language of the SDK. In order to use this language, please set the languageLocale
property of VeriffSdk.Configuration
before you start the verification.
// Swift
let locale = Locale(identifier: "et")
// Objective-C
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"et"];
Create the configuration object
// Swift
let configuration = VeriffSdk.Configuration(branding: branding, languageLocale: locale)
// Objective-C
VeriffConfiguration *configuration = [[VeriffConfiguration alloc] initWithBranding:branding languageLocale:locale];
Custom intro screen
Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers. First, please ask about this possibility from your Solutions Engineer. In case we can offer it for you then removal process is following:
- You agree your own introduction screen visuals and copy with our Solutions Engineer and get relevant legal documents signed in case their needed.
- After that Veriff will enable custom introduction screen from backend for your integrations.
- After you have implemented your own introduction screen you can change the configuration option specified below.
configuration.customIntroScreen = true
Note: This step alone is not enough to enable the custom intro screen. Make sure to contact your Solutions Engineer so they can enable the feature for your integration.
Vendor data
Veriff supports the option to override vendor data. Please check with your Solutions Engineer to confirm if this feature can be enabled for your integration. If it is possible, follow these steps:
- Veriff will enable vendor data overriding from the backend for your integrations.
- Modify the configuration option as specified below.
configuration.vendorData = "Vendor Data"
Note: Enabling this feature alone will not be sufficient to override the vendor data. Ensure that you contact your Solutions Engineer to have the feature enabled for your integration.
Start the verification flow by using the configuration
// Swift
let veriff = VeriffSdk.shared
veriff.startAuthentication(sessionUrl: sessionUrl, configuration: configuration, presentingFrom: yourViewController)
// Objective-C
VeriffSdk *veriff = [VeriffSdk shared];
[veriff startAuthenticationWithSessionUrl:sessionUrl configuration:configuration presentingFrom:yourViewController];
Handling result codes from SDK
To receive session results, you must implement the VeriffSdkDelegate
protocol and assign a delegate
to the VeriffSdk
instance.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
veriff.delegate = self
The Veriff SDK returns a number of result codes that your application can handle.
// Swift
extension VerificationService: VeriffSdkDelegate {
func sessionDidEndWithResult(_ result: Veriff.Result) {
switch result.status {
case .done:
// The end-user successfully submitted the session
break
case .canceled:
// The end-user canceled the verification process.
break
case .error(let error):
switch error {
// ...
}
}
}
}
// Objective-C
- (void)sessionDidEndWithResult:(VeriffResult *)result {
switch (result.status) {
case VeriffStatusDone:
// The end-user successfully submitted the session
break;
case VeriffStatusCanceled:
// The end-user canceled the verification process.
break;
case VeriffStatusError:
if (result.error == nil) { break; }
switch (result.error.code) {
// ...
}
}
}
You can find the description of status codes below:
done
The session status is finished from clients perspectivecanceled
The end-user canceled the verification processerror
An error occurred. To see the error reason:- In Swift: check the associated value (
Veriff.Error
) passed by error status. - In Objective-C: check
result.error.code
(VeriffErrorCode
).
- In Swift: check the associated value (
Notes
- The Veriff SDK always shows an error screen itself. The errors returned by the session are to inform your application.
Migrating to Veriff iOS 3.0.0
Switch from baseUrl
and sessionToken
to sessionUrl
The Veriff
object in the SDK 3.0.0 takes a required sessionUrl
and an optional VeriffConfiguration
instance as parameters into initialisation. The sessionUrl
is received from your backend implementation (see the documentation here), it is composed of the baseUrl
and sessionToken
sent to the VeriffConfiguration
object in earlier versions.
Updated VeriffConfiguration
object
The VeriffConfiguration
struct now takes in branding
and languageLocale
as initialisation parameters.
The new VeriffDelegate
method
You can now receive session results via func sessionDidEndWithResult(_ result: Veriff.Result)
instead of the obsolete func onSession(result: VeriffResult, sessionToken: String)
. The sessionToken
is included in the Veriff.Result
as an instance variable.
Use Veriff.Result
instead of VeriffResult
The new Veriff.Result
struct comprises status: Status
and sessionToken: String?
instance variables. The Status
enum can be of three types: done
, canceled
, error
. The description
variable on the Veriff.Result
returns additional information as a string.
Migrating to Veriff iOS 4.0.0
Rename Veriff
instances to VeriffSdk
The name Veriff
was used both for our module and public class name. However this blocked us from supporting Swift Package Manager due to Swift compiler bug [↗]. We renamed our public class name to VeriffSdk
.
VeriffConfiguration
is now VeriffSdk.Configuration
VeriffConfiguration struct is moved under VeriffSdk
. Please replace the occurrences of VeriffConfiguration
with VeriffSdk.Configuration
.
Branding
is now VeriffSdk.Branding
Branding struct is moved under VeriffSdk
. Please replace the occurrences of Branding
with VeriffSdk.Branding
.
Rename VeriffDelegate
to VeriffSdkDelegate
Please replace the occurrences of VeriffDelegate
with VeriffSdkDelegate
.
VeriffSdk.Result.description
made non-optional
If you were dealing with unwrapping it, feel free to remove it.
VeriffSdk.Result.sessionToken
removed and VeriffSdk.Result.sessionUrl
added instead
Please remove the occurrences of sessionToken
. You can now use sessionUrl
to get the full sessionUrl
including token.
Migrating to Veriff iOS 5.0.0
Increased min iOS supported version
Now min version is iOS 11.0.
Updated VeriffSdk.Branding
object
Following configurations are removed:
buttonHeight
statusBarColor
secondaryTextColor
isTextUppercase
Fonts API changes:
lightFontName
is removedregularFontName
,semiBoldFontName
andboldFontName
are renamed toregular
,medium
andbold
.
logomark
customization is added.
Migrating to Veriff iOS 6.0.0
Updated VeriffSdk.Branding
object
Following configurations are added:
background
onBackground
onBackgroundSecondary
onBackgroundTertiary
primary
onPrimary
secondary
onSecondary
outline
error
success
Following configurations are removed:
themeColor
backgroundColor
primaryTextColor
primaryButtonBackgroundColor
bulletPoint
Following configurations are deprecated:
logomark
not used anymore
Following configurations are renamed:
buttonCornerRadius
->buttonRadius
Migrating to Veriff iOS 7.0.0
Set deployment target to iOS 13
iOS SDK Changelog
Please refer to release notes [↗].
Flutter Plugin
Requirements
Integration with Veriff Flutter Plugin requires the project to target at least iOS version 13.0 and Android version 8.0 (API 26) or higher.
Install the plugin to your project
Follow instructions here [↗] to install the plugin.
Declare foreground service sync for Google Play
The SDK declares and uses the FOREGROUND_SERVICE_DATA_SYNC
. If you distribute your application on Google Play,
then you must declare the foreground service information in Play Console [↗].
The information required by Play Console is (as listed on the Google Play link above):
- Provide a description of the app functionality that is using each foreground service type.
- The Veriff SDK uses the foreground service to upload end-user data to Veriff's servers for verification purposes.
- Describe the user impact if the task is deferred by the system (does not start immediately), and/or the task is interrupted by the system (paused and/or restarted).
- If the task is deferred or interrupted by the system, the end-user verification will be delayed.
- Include a link to a video demonstrating each foreground service feature. The video should demonstrate the steps the user needs to take in your app in order to trigger the feature.
- Please record a video of your app's Veriff SDK integration.
- Choose your specific use case for each foreground service type.
- "Network transfer: Upload or download / Other"
See also Veriff's note on data collection purposes in your app [↗]
iOS specific configuration
Add usage descriptions to application Info.plist
Not adding these usage descriptions causes system to kill application when it requests the permissions when needed.
Veriff requires camera, microphone, photo library and optionally NFC reader permissions for capturing photos, video and scanning passport during identification. Your application is responsible to describe the reason why camera, microphone, photo library and NFC reader is used. You must add 3 descriptions listed below to Info.plist
of your application with the explanation of the usage.
NSCameraUsageDescription
NSMicrophoneUsageDescription
NSPhotoLibraryUsageDescription
Add required steps for NFC scanning
- Add
NFCReaderUsageDescription
description toInfo.plist
. The application needs to define the list of application IDs or AIDs it can connect to, in the Info.plist file. The AID is a way of uniquely identifying an application on a ISO 7816 tag, which is usually defined by a standard.
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>A0000002471001</string> <string>A0000002472001</string> <string>00000000000000</string> </array>
Introduce a new entitlement for NFC scanning, a feature made available from iOS 13 onwards. Xcode automatically adds this entitlement when you activate the Near Field Communication Tag Reading feature in the target Signing & Capabilities. Following the activation of this feature, the *.entitlements file should include the TAG format.
<key>com.apple.developer.nfc.readersession.formats</key> <array> <string>TAG</string> </array>
Set the iOS target in Xcode
Make sure that the 'iOS Deployment Target' in Xcode (under Project > target > Info > Deployment Target) is set to iOS 13.0
or later.
Launching the verification flow
Import plugin in your code
In order to use Veriff plugin, please import it to your class that will use it.
import 'package:veriff_flutter/veriff_flutter.dart'
Start verification flow
In order to start the verification flow please create a configuration with defined parameters below.
Parameters are defined as below;
Parameters | Description |
---|---|
sessionUrl |
Required parameter. sessionUrl can be received from your backend implementation. sessionUrl should be unique for each call. Check /sessions endpoint in the API documentation here to learn how to generate one. |
Configuration config = Configuration(sessionUrl);
Then pass the configuration to Veriff object and start the verification flow;
Veriff veriff = Veriff();
try {
Result result = await veriff.start(config);
print(result.status);
print(result.error);
} on PlatformException {
// handle exception
}
Customize user interface (Optional)
You can customize Veriff SDK user interface in your application by defining your brand's colors, font and logo.
See the Veriff SDK customization guide [↗] document to see what it looks like.
Veriff Flutter plugin allows the customization of your brand's colors, font and logo in the SDK flow by passing the optional parameters when launching Veriff:
String regularFontPath = "fonts/Regular.otf";
String mediumFontPath = "fonts/Medium.otf";
String boldFontPath = "fonts/Bold.otf";
Fonts fonts = Fonts(
regularFontPath: regularFontPath,
mediumFontPath: mediumFontPath,
boldFontPath: boldFontPath
);
Branding branding = Branding(
logo: AssetImage(path_of_image),
background: "#f2ff00",
onBackground: "#ff00ff",
onBackgroundSecondary: "#52b35c",
onBackgroundTertiary: "#3a593d",
primary: "#123abc",
onPrimary: "#ff00ff",
secondary: "#f2ff00",
onSecondary: "#ff7700",
cameraOverlay: "#59496a",
onCameraOverlay: "#e27e23",
outline: "#ff00ff",
error: "#ff0000",
success: "#00ff00",
buttonRadius: 5,
fonts: fonts
);
And pass the branding object with configuration for starting the verification flow:
Configuration config = Configuration(sessionUrl, branding: branding);
When a color isn't defined, the default Veriff theme color is used.
Setting the user interface language
Veriff Flutter plugin supports setting the language of the UI. In order to use this feature, please pass the locale identifier as in example below;
Configuration config = Configuration(sessionUrl, branding: branding, languageLocale: "et");
Custom intro screen
Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers. First, please ask about this possibility from your solutions engineer. In case we can offer it for you then removal process is following:
- You agree your own introduction screen visuals and copy with our solutions engineer and get relevant legal documents signed in case their needed.
- After that Veriff will enable custom introduction screen from backend for your integrations.
- After you have implemented your own introduction screen you can change the configuration option specified below.
config.useCustomIntroScreen = true;
Vendor data
Veriff supports the option to override vendor data. Please check with your Solutions Engineer to confirm if this feature can be enabled for your integration. If it is possible, follow these steps:
- Veriff will enable vendor data overriding from the backend for your integrations.
- Modify the configuration option as specified below.
config.vendorData = "Vendor Data";
Handling the results from plugin
The Result returned by start method will have a status that is one of Status.done
, Status.canceled
and Status.error
.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
In case Status.error is received, you will also have an error description that is one of the list below:
- Error.cameraUnavailable
- Error.microphoneUnavailable
- Error.networkError
- Error.sessionError
- Error.deprecatedSDKVersion
- Error.unknown
- Error.nfcError
- Error.setupError
- Error.none
You can check the statuses and errors using switch-case as in example below;
switch (result.status) {
case Status.done:
print("Session is completed.");
break;
case Status.canceled:
print("Session is canceled by the end-user.");
break;
case Status.error:
switch (result.error) {
case Error.cameraUnavailable:
print("User did not give permission for the camera");
break;
case Error.microphoneUnavailable:
print("User did not give permission for the microphone.");
break;
case Error.networkError:
print("Network error occurred.");
break;
case Error.sessionError:
print("A local error happened before submitting the session.");
break;
case Error.deprecatedSDKVersion:
print(
"Version of Veriff SDK used in plugin has been deprecated. Please update to the latest version.");
break;
case Error.unknown:
print("Uknown error occurred.");
break;
case Error.nfcError:
print("Error with NFC");
break;
case Error.setupError:
print("Error with setup");
break;
case Error.none:
print("No error.");
break;
default:
break;
}
break;
default:
break;
}
React Native SDK
React Native SDK requirements
Integration with Veriff React Native SDK requires the project to target at least iOS version 13.4 and Android version 8.0 (API 26) or higher.
Note: If you have created your react native app using expo, you will have to eject out of expo at this point(if you have not ejected out already) since expo does not support native modules Check the Caveats section here [↗] for more info on that.
Add the SDK to a project
Add the Veriff React Native SDK to your package.json
file:
npx yarn add @veriff/react-native-sdk
Or if using npm
:
npm install @veriff/react-native-sdk --save
Update Android build.gradle
file
Open the root build.gradle
file in the android
folder and add a new maven destination to the repositories in the allprojects
section. The best place is right after the local node_modules
repositories and before the google()
repository.
allprojects {
repositories {
// ... local react native repos
maven { url "https://cdn.veriff.me/android/" } //veriff
google()
jcenter()
}
}
Declare foreground service sync for Google Play
The SDK declares and uses the FOREGROUND_SERVICE_DATA_SYNC
. If you distribute your application on Google Play,
then you must declare the foreground service information in Play Console [↗].
The information required by Play Console is (as listed on the Google Play link above):
- Provide a description of the app functionality that is using each foreground service type.
- The Veriff SDK uses the foreground service to upload end-user data to Veriff's servers for verification purposes.
- Describe the user impact if the task is deferred by the system (does not start immediately), and/or the task is interrupted by the system (paused and/or restarted).
- If the task is deferred or interrupted by the system, the end-user verification will be delayed.
- Include a link to a video demonstrating each foreground service feature. The video should demonstrate the steps the user needs to take in your app in order to trigger the feature.
- Please record a video of your app's Veriff SDK integration.
- Choose your specific use case for each foreground service type.
- "Network transfer: Upload or download / Other"
See also Veriff's note on data collection purposes in your app [↗]
iOS Specific setup
Add Swift to the ios module
Veriff SDK requires your ios module to have some Swift code. If you don't have any Swift code yet then add a new empty.swift
file in Xcode. If Xcode offers to add a bridging header then add it.
Update iOS Podfile
Open Podfile
in the ios
folder and make sure that platform
is 13.4 or higher:
platform :ios, '13.4'
Also make sure your main target in the Podfile
contains use_native_modules!
directive:
target 'MyApp' do
# pod 'foo'...
config = use_native_modules!
end
Add usage descriptions to application Info.plist
Not adding these usage descriptions causes system to kill application when it requests the permissions when needed.
Veriff requires camera, microphone, photo library and optionally NFC reader permissions for capturing photos, video and scanning passport during identification. Your application is responsible to describe the reason why camera, microphone, photo library and NFC reader is used. You must add 3 descriptions listed below to Info.plist
of your application with the explanation of the usage.
NSCameraUsageDescription
NSMicrophoneUsageDescription
NSPhotoLibraryUsageDescription
Add required steps for NFC scanning
- Add
NFCReaderUsageDescription
description toInfo.plist
. The application needs to define the list of application IDs or AIDs it can connect to, in the Info.plist file. The AID is a way of uniquely identifying an application on a ISO 7816 tag, which is usually defined by a standard.
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>A0000002471001</string> <string>A0000002472001</string> <string>00000000000000</string> </array>
Introduce a new entitlement for NFC scanning, a feature made available from iOS 13 onwards. Xcode automatically adds this entitlement when you activate the Near Field Communication Tag Reading feature in the target Signing & Capabilities. Following the activation of this feature, the *.entitlements file should include the TAG format.
<key>com.apple.developer.nfc.readersession.formats</key> <array> <string>TAG</string> </array>
Set the iOS target in Xcode
Make sure that the 'iOS Deployment Target' in Xcode (under Project > target > Info > Deployment Target) is set to iOS 13.4 or later.
Using the Veriff React Native SDK
Starting the verification flow
In order to use Veriff SDK, please import it to the file that will use the SDK.
import VeriffSdk from '@veriff/react-native-sdk';
Parameters are defined as below;
Parameters | Description |
---|---|
sessionUrl |
Required parameter. sessionUrl can be received from your backend implementation. sessionUrl should be unique for each call. Check /sessions endpoint in the API documentation here to learn how to generate one. |
Once you have the sessionUrl
you can launch Veriff using VeriffSdk
imported earlier:
var result = await VeriffSdk.launchVeriff({ sessionUrl: SESSION_URL });
User Interface customization
You can customize Veriff SDK user interface in your application by defining your brand's colors, font and logo.
See Veriff SDK customization guide [↗] document on how it looks.
Veriff React Native SDK allows the customization of your brand's colors, font and logo in the SDK flow by passing in these optional properties when launching Veriff:
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
branding: {
logo: 'parrot', // see alternative options for logo below
background: '#ff00ff',
onBackground: '#ffffff',
onBackgroundSecondary: '#ff00ff',
onBackgroundTertiary: '#000000',
primary: '#333333',
onPrimary: '#444444',
secondary: '#333333',
onSecondary: '#444444',
outline: '#444444',
cameraOverlay: '#59496a',
onCameraOverlay: '#e27e23',
error: '#333333',
success: '#444444',
buttonRadius: 28,
iOSFont: {
regular: 'Font-Regular',
medium: 'Font-Medium',
bold: 'Font-Bold',
},
androidFont: {
regular: 'font_regular',
medium: 'font-medium',
bold: 'font_bold',
}
},
});
When a color or a font isn't defined the default Veriff color or font is used. Same applies to the logo - when it isn't defined the default is used. The image assets need to be added into Xcode assets in the iOS project and into drawable folders in the Android project. In the example above you would need to add an image asset named 'parrot' into Xcode assets and 'parrot.png' to Android drawable folders in android/src/main/res
.
Alternative ways to provide the logo
Instead of using platform-specific image assets you can provide a URI to an image which will then be used:
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
branding: {
logo: { uri: 'http://example.com/logo/parrot.jpg' },
},
});
React Native assets are also supported through resolveAssetSource
:
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
const parrot = require('./img/parrot.png');
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
branding: {
logo: resolveAssetSource(parrot),
},
});
Setting the user interface language
The Veriff RN SDK allows setting the language of the SDK. In order to use this language, please pass the locale as in example below;
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
locale: 'et'
});
Custom intro screen
Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers. Please request this from your solutions engineer. The removal process is following:
- Agree your own introduction screen visuals and copy with our solutions engineer and get relevant legal documents signed;
- Veriff will enable custom introduction screen for your integrations;
- After you have implemented your own introduction screen you can change the configuration option as specified below;
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
locale: 'et',
customIntroScreen: true
});
Vendor data
Veriff supports the option to override vendor data. Please check with your Solutions Engineer to confirm if this feature can be enabled for your integration. If it is possible, follow these steps:
- Veriff will enable vendor data overriding from the backend for your integrations.
- Modify the configuration option as specified below.
var result = await VeriffSdk.launchVeriff({
sessionUrl: SESSION_URL,
locale: 'et',
vendorData: "Vendor Data"
});
Handling the result from the SDK
The result
returned by launchVeriff
will have a status
field that is one of either VeriffSdk.statusDone
,
VeriffSdk.statusCanceled
or VeriffSdk.statusError
.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
In case of statusError
there will be a error code (not human-readable) in the error
field.
var result = await VeriffSdk.launchVeriff({ sessionUrl: SESSION_URL });
switch (result.status) {
case VeriffSdk.statusDone:
// end-user submitted the images and completed the flow
// note that this does not mean a final decision yet
break;
case VeriffSdk.statusCanceled:
// end-user canceled the flow before completing
break;
case VeriffSdk.statusError:
// the flow could not be completed due to an error
console.log("Veriff verification failed with error=" + result.error);
break;
}
Migrating to React Native SDK 3.0.0
Follow these steps to migrate to React Native SDK 3.0.0 API
Updated Branding API
Following configurations are added:
- background
- onBackground
- onBackgroundSecondary
- onBackgroundTertiary
- primary
- onPrimary
- secondary
- onSecondary
- outline
- error
- success
Following configurations are removed:
- themeColor
- backgroundColor
- primaryTextColor
- primaryButtonBackgroundColor
- bulletPoint
Following configurations are renamed:
buttonCornerRadius -> buttonRadius
Migrating to React Native SDK 2.0.0
Follow these steps to migrate to React Native SDK 2.0.0 API
Use new parameter sessionUrl
New API uses sessionUrl
instead of a sessionToken
. sessionUrl
is a combination of base URL and session token.
Rename parameter navigationBarImage
to logo
We renamed the navigationBarImage
parameter in configuration to logo
.
React Native SDK Changelog
Below is a summary of changes introduced with each version of the React Native SDK. Expand the list by clicking on "Versions" and then on each release version to see the summary.
Cordova Plugin
Cordova requirements
Integration with Cordova plugin requires the project to target at least iOS version 11.0 and Android version 5.0 (API level 21) or higher.
Add the plugin to a project
Add the Veriff Cordova plugin to your project:
cordova plugin add @veriff/cordova-plugin-veriff
Adding this plugin will make the window.cordova.plugins.Veriff
global object available once the deviceready
event propagates.
Declare foreground service sync for Google Play
The SDK declares and uses the FOREGROUND_SERVICE_DATA_SYNC
. If you distribute your application on Google Play,
then you must declare the foreground service information in Play Console [↗].
The information required by Play Console is (as listed on the Google Play link above):
- Provide a description of the app functionality that is using each foreground service type.
- The Veriff SDK uses the foreground service to upload end-user data to Veriff's servers for verification purposes.
- Describe the user impact if the task is deferred by the system (does not start immediately), and/or the task is interrupted by the system (paused and/or restarted).
- If the task is deferred or interrupted by the system, the end-user verification will be delayed.
- Include a link to a video demonstrating each foreground service feature. The video should demonstrate the steps the user needs to take in your app in order to trigger the feature.
- Please record a video of your app's Veriff SDK integration.
- Choose your specific use case for each foreground service type.
- "Network transfer: Upload or download / Other"
See also Veriff's note on data collection purposes in your app [↗]
iOS Specific setup
Add usage descriptions to application Info.plist
Not adding these usage descriptions causes system to kill application when it requests the permissions when needed.
Veriff requires camera, microphone, photo library and optionally NFC reader permissions for capturing photos, video and scanning passport during identification. Your application is responsible to describe the reason why camera, microphone, photo library and NFC reader is used. You must add 3 descriptions listed below to ios platform in config.xml
of your application with the explanation of the usage.
NSCameraUsageDescription
NSMicrophoneUsageDescription
NSPhotoLibraryUsageDescription
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
<string>Access to camera is needed for user identification purposes</string>
</config-file>
<config-file target="*-Info.plist" parent="NSMicrophoneUsageDescription">
<string>Access to microphone is needed for video identification</string>
</config-file>
<config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
<string>Access to photo library is needed uploading proof of address documents</string>
</config-file>
Add required steps for NFC scanning
- Add
NFCReaderUsageDescription
description to ios platform insideconfig.xml
.
<config-file target="*-Info.plist" parent="NFCReaderUsageDescription">
<string>Access to NFC is needed for user identification purposes</string>
</config-file>
The application needs to define the list of application IDs or AIDs it can connect to, in the Info.plist file. The AID is a way of uniquely identifying an application on a ISO 7816 tag, which is usually defined by a standard.
<config-file target="*-Info.plist" parent="com.apple.developer.nfc.readersession.iso7816.select-identifiers"> <array> <string>A0000002471001</string> <string>A0000002472001</string> <string>00000000000000</string> </array> </config-file>
Introduce a new entitlement for NFC scanning, a feature made available from iOS 13 onwards. Xcode automatically adds this entitlement when you activate the Near Field Communication Tag Reading feature in the target Signing & Capabilities. Following the activation of this feature, the *.entitlements file should include the TAG format. If your application is intended to support iOS versions prior to iOS 13, the NDEF format is mandatory. However, for applications targeting iOS 13 and later, there is no need to add the NDEF format to the entitlements.
<config-file target="**/Entitlements.plist" parent="com.apple.developer.nfc.readersession.formats"> <array> <string>TAG</string> <string>NDEF</string> </array> </config-file>
Set the iOS target in Xcode
Make sure that the 'iOS Deployment Target' in Xcode (under Project > target > Info > Deployment Target) is set to iOS 12.4 or later.
Using the Veriff Cordova plugin
Starting the verification flow
The Veriff Plugin has a single function to start a verification attempt: start(callback, sessionUrl, configuration)
callback
(required) - a callback that will be invoked with the verification attempt result. The callback includes the result object which will have astatus
field that is one of eitherVeriff.STATUS_DONE
,Veriff.STATUS_CANCELED
orVeriff.STATUS_ERROR
.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
In case thestatus
isVeriff.STATUS_ERROR
there will be a error code (not human-readable) in theerror
field.sessionUrl
(required) -sessionUrl
can be received from your backend implementation.sessionUrl
should be unique for each call. Check/sessions
endpoint in the API documentation here to learn how to generate one.configuration
(optional) - an object that allows the customization of the Veriff Plugin, including your brand's colors, font and logo. The supported properties are:branding
(optional) - customize various branding options.locale
(optional) - override the user interface language (default: device language).customIntroScreen
(optional) - Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers.vendorData
(optional) - Veriff supports the option to override vendor data.
User Interface customization
You can customize Veriff SDK user interface in your application by defining your brand's colors, font and logo.
See Veriff SDK customization guide [↗] document on how it looks.
Veriff Cordova plugin allows the customization of your brand's colors, font and logo in the SDK flow by passing in these optional properties when launching Veriff:
window.cordova.plugins.Veriff.start(
function (result) {
console.log("Veriff SDK result: status: " + result.status + ", error: " + result.error);
},
sessionUrl,
{
branding: {
logo: 'parrot',
background: '#ff00ff',
onBackground: '#ffffff',
onBackgroundSecondary: '#ff00ff',
onBackgroundTertiary: '#000000',
primary: '#333333',
onPrimary: '#444444',
secondary: '#333333',
onSecondary: '#444444',
outline: '#444444',
cameraOverlay: '#59496a',
onCameraOverlay: '#e27e23',
error: '#333333',
success: '#444444',
buttonRadius: 28,
iOSFont: {
regular: 'Font-Regular',
medium: 'Font-Medium',
bold: 'Font-Bold',
},
androidFont: {
regular: 'font_regular.ttf',
medium: 'font-medium.ttf',
bold: 'font_bold.ttf',
}
}
},
);
When a color or a font isn't defined the default Veriff color or font is used. Same applies to the logo - when it isn't defined the default is used. The image assets need to be added into Xcode assets in the iOS project and into drawable folders in the Android project. In the example above you would need to add an image asset named 'parrot' into Xcode assets and 'parrot.png' to Android drawable folders in android/src/main/res
.
Setting the user interface language
The Veriff Cordova plugin allows setting the language of the SDK. In order to use this language, please pass the locale as in example below;
window.cordova.plugins.Veriff.start(
function (result) {
console.log("Veriff SDK result: status: " + result.status + ", error: " + result.error);
},
sessionUrl,
{
locale: 'et'
}
);
Custom intro screen
Veriff supports replacing introduction screen with a custom client developed introduction screen for eligible customers. Please request this from your solutions engineer. The removal process is following:
- Agree your own introduction screen visuals and copy with our solutions engineer and get relevant legal documents signed;
- Veriff will enable custom introduction screen for your integrations;
- After you have implemented your own introduction screen you can change the configuration option as specified below;
window.cordova.plugins.Veriff.start(
function (result) {
console.log("Veriff SDK result: status: " + result.status + ", error: " + result.error);
},
sessionUrl,
{
customIntroScreen: true
}
);
Vendor data
Veriff supports the option to override vendor data. Please check with your Solutions Engineer to confirm if this feature can be enabled for your integration. If it is possible, follow these steps:
- Veriff will enable vendor data overriding from the backend for your integrations.
- Modify the configuration option as specified below.
window.cordova.plugins.Veriff.start(
function (result) {
console.log("Veriff SDK result: status: " + result.status + ", error: " + result.error);
},
sessionUrl,
{
vendorData: 'Vendor Data',
}
);
Handling the result from the SDK
The result
returned by Veriff.start
will have a status
field that is one of either Veriff.STATUS_DONE
, Veriff.STATUS_CANCELED
or Veriff.STATUS_ERROR
.
Note that this is the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It is not the verification session status.
In case of Veriff.STATUS_ERROR
there will be a error code (not human-readable) in the error
field.
window.cordova.plugins.Veriff.start(
function (result) {
console.log("Veriff SDK result: status: " + result.status + ", error: " + result.error);
switch (result.status) {
case STATUS_DONE:
// end-user submitted the images and completed the flow
// note that this does not mean a final decision yet
break;
case STATUS_CANCELED:
// end-user canceled the flow before completing
break;
case STATUS_ERROR:
// the flow could not be completed due to an error
console.log("Veriff verification failed with error=" + result.error);
switch (result.error) {
case UNABLE_TO_ACCESS_CAMERA:
// unable to access camera, likely due to no permission
break;
case UNABLE_TO_ACCESS_MICROPHONE:
// unable to access camera, likely due to no permission
break;
case NETWORK_ERROR:
break;
case SESSION_ERROR:
break;
case UNKNOWN_ERROR:
break;
case UNSUPPORTED_SDK_VERSION:
break;
}
break;
}
},
sessionUrl
);
Javascript SDK
Veriff JS SDK is a simple and customizable library, making it a convenient way to include Veriff's web flow to your solution.
The purpose of the JS SDK is to create the session URL for your end-user's verification session.
Once you have the URL, you have two options to direct the user to the verification flow:
- Use the redirect solution
- Trigger the InContext SDK solution
Install JS SDK
Include as a script tag:
<script src='https://cdn.veriff.me/sdk/js/1.5/veriff.min.js'></script>
or install it via a package manager
$ npm install --save @veriff/js-sdk
// CommonJS
const Veriff = require('@veriff/js-sdk');
// ES6 style import
import { Veriff } from '@veriff/js-sdk';
Adding JS SDK
Veriff JS SDK requires one parent element in HTML:
<div id='veriff-root'></div>
It is possible to set the width of js-sdk form through style attribute:
<div id='veriff-root' style="width:400px"></div>
In order to initialize the library, API Key, parentId and onSession callback function is required. Parameters are defined as below:
Parameters | Description |
---|---|
apiKey |
Required parameter. See how to find your API keys here to learn how to generate one. |
parentId |
Required parameter. 'veriff-root' |
onSession |
Required parameter. The end-user can be redirected either to the verification url or incontext SDK can be triggered |
const veriff = Veriff({
apiKey: 'API_KEY',
parentId: 'veriff-root',
onSession: function(err, response) {
// received the response, verification can be started / triggered now
// redirect
window.location.href = response.verification.url;
// incontext sdk
createVeriffFrame({url: response.verification.url});
}
});
veriff.mount();
Read more about incontext sdk method or redirection.
By default, the following form will be rendered:
onSession function is executed after the response is received from the API, response body contains a verification object with following schema:
{
"status": "success",
"verification": {
"id": "UUID V4 Identifying the verification",
"url": "full url to which a person should be redirected in order to proceed with verification flow",
"host": "hostname",
"status": "status of the verification",
"sessionToken": "JWT encoded verification token"
}
}
vendorData
: string - customer-specific data string, max 1000 characters long, will be sent back unmodified using webhooks.
We require only non-semantic data to be submitted (UUID-s etc., that can not be resolved or used outside the customer's domain).
In case the Given name / Last name / Vendor Data or all of them are known, they can be passed to the SDK, therefore text input fields will not be rendered.
const veriff = Veriff({
apiKey: 'API_KEY',
parentId: 'veriff-root',
onSession: function(err, response) {
// received the response, verification can be started now
}
});
veriff.setParams({
person: {
givenName: 'Foo',
lastName: 'Bar'
},
vendorData: '7eb19312-79d6-11ec-90d6-0242ac120003'
});
veriff.mount({
submitBtnText: 'Get verified'
});
It is possible to disable fields rendering without passing any data by not including anything in corresponding value:
const veriff = Veriff({
apiKey: 'API_KEY',
parentId: 'veriff-root',
onSession: function(err, response) {
// received the response, verification can be started now
}
});
veriff.setParams({
person: {
givenName: ' ',
lastName: ' '
},
vendorData: ' '
});
veriff.mount({
submitBtnText: 'Get verified'
});
Additionally the input placeholder and button text value can be customised.
const veriff = Veriff({
apiKey: 'API_KEY',
parentId: 'veriff-root',
onSession: function(err, response) {
// received the response, verification can be started now
}
});
veriff.mount({
formLabel: {
givenName: 'First name',
lastName: 'Family name',
vendorData: 'Unique id of an end-user'
},
submitBtnText: 'Get verified',
loadingText: 'Please wait...'
});
Adding viewport meta tag
The viewport meta tag is crucial for proper rendering and layout on mobile devices. If this meta tag is missing, the website may be rendered too small on mobile devices.
Make sure to add the following tag to mitigate such issues:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
InContext Javascript SDK
Use this if you would like to use incontext UI.
Install InContext JS SDK
npm install @veriff/incontext-sdk
Adding InContext JS SDK
You need to have a Veriff session URL generated before initializing the SDK. Please see our documentation to learn how to generate one, or use our JavaScript SDK to create it.
// ES6
import { createVeriffFrame } from '@veriff/incontext-sdk';
// CommonJS
const { createVeriffFrame } = require('@veriff/incontext-sdk');
const veriffFrame = createVeriffFrame({ url: VERIFF_SESSION_URL })
This will render a modal with adapted Veriff application in iframe.
createVeriffFrame()
returns an object that controls the modal.
Listening for events
Pass onEvent
callback function when initializing SDK
import { createVeriffFrame, MESSAGES } from '@veriff/incontext-sdk';
createVeriffFrame({
url,
onEvent: function(msg) {
switch(msg) {
case MESSAGES.CANCELED:
//
break;
}
}
})
msg
:STARTED
- session status changed to 'started'CANCELED
- end-user closed the modalFINISHED
- end-user finished verification flow
Note that this sends you the end-user flow completion status, meaning that it shows whether the end-user was able to complete all the steps in the verification flow or not. It does not send the verification session status.
Using with inline script
Include a script tag:
<script src='https://cdn.veriff.me/incontext/js/v1/veriff.js'></script>
window.veriffSDK.createVeriffFrame({ url: VERIFF_SESSION_URL });
Options
createVeriffFrame([options])
[options]
- Configuration object:url
- Veriff session URLlang
- Override user interface languageonEvent
- Event callback functiononReload
- Reload request callback - handle reloading the webpage and reopening the SDK
Close Veriff modal
Normally modal will be closed due to end-user input, but if you want to control it(e.g. timeout), please use this function.
veriffFrame.close();
onReload
This callback can be called on some browsers when the end-user has denied camera access and to re-request access the host page has to be reloaded.
For best UX we recommend reloading the webpage & reopening Veriff InContext SDK automatically.
Example:
const url = sessionStorage.getItem('@veriff-session-url') || getSessionUrl()
veriffSDK.createVeriffFrame({
url,
onReload: () => {
// Logic to re-open Veriff SDK after page reload
// e.g. sessionStorage.setItem('@veriff-session-url', url);
window.location.reload();
},
});
Adding Content Security Policy to InContext SDK
In order to improve the security, add the following CSP directives headers to index.html file, under the <meta>
tag:
Content-Security-Policy default-src 'self' *.veriff.me *.veriff.com;
script-src 'self' *.veriff.me *.veriff.com *.hotjar.com *.probity.io;
img-src blob: 'self' *.probity.io;
frame-src 'self' *.hotjar.com;
connect-src 'self' *.veriff.com *.veriff.me *.probity.io;
style-src 'self' *.veriff.com *.veriff.me;
For example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-security-policy"
content="default-src 'self' *.veriff.me *.veriff.com;
script-src 'self' *.veriff.me *.veriff.com *.hotjar.com *.probity.io *sentry.io;
img-src blob: 'self' *.probity.io;
frame-src 'self' *.hotjar.com;
connect-src 'self' *.veriff.com *.veriff.me *.probity.io;
style-src 'self' *.veriff.com *.veriff.me;">
</head>
Allow camera requests in your Permissions Policy
To avoid any issues, make sure that you allow Veriff to request camera access. If your Permissions Policy denies camera requests by default, you may encounter issues when using the InContext SDK. For more information, please read the W3C Permissions Policy Explainer [↗].
The html document where the InContext Iframe is embedded is explicitly blocking the use of camera and microphone if the following header is present:
Permissions-Policy Header: camera=(), microphone=()
According to MDN Web Docs - Permissions Policy > Allowlists[↗]:
()
means an empty allowlist, so the feature is disabled in top-level and nested browsing contexts. The equivalent for<iframe>
allow
attribute is'none'
.
Integrate by Redirection
In case you would like to opt out of modal based approach by using our incontext sdk you can instead redirect end-users to the verification flow.
Using redirection
You need to have a Veriff session URL generated before redirecting the end-user to the flow. See our documentation to learn how to generate one, or use our JavaScript SDK to create it.
// After receiving the url you could redirect end-users there by using following
window.location.href = url;
Query parameters
Available parameters that can be changed;
Parameters | Description |
---|---|
lang |
Optional parameter. lang can be used to override the end-user interface's language. |
SDK Support Policy
Support Policy for Veriff SDKs
Identity verification software, practices, and regulations move fast. To keep our software user-friendly, and maintain high conversion rates for our customers, our development team needs to be faster. To deliver an increasingly smarter, better and safer product, it's important to drop backward compatibility layers and update SDKs at least once every three months. Our SDKs are updated every two weeks, and downloading new releases will keep your verification process smooth and error-free. All releases are fully tested by our team and before being deployed, and come with the support from our team in the form of:
SDK support for 6 months after release, including:
- Fixing all reported bugs in the upcoming SDK release
- Fixing critical bugs in any final version before a major release for three months
- In case an SDK release requires major implementation efforts, then the old version will be supported for one year
Notifications before major changes to SDK support such as:
- Dropping support for an SDK version, where we will inform you via email one month in advance
- The end of the one-month grace period, after which Veriff will block future use of a specified SDK version
- When end-users engage with outdated SDKs, they will receive a prompt to upgrade the host application
SDK release versioning To help you keep track of SDK releases, Veriff uses three numbers to represent the scale of the updates. Each release is assigned either X, Y, or Z according to the following descriptions:
- Major Release (X) - These releases may require addtional development efforts, and often come with large-scale improvements to the SDK
- Minor Release (Y) - These do not come with any mandatory development efforts on your end, but may include new functionalities that require development efforts to be activated
- Bug-fix Release (Z) - These resolve issues from the previous release and do not introduce any new features or improvements
Supported languages
Supported languages are as below;
Language Code | Name |
---|---|
ar |
العربية |
bg |
Български |
bn |
বাংলা |
ca |
Català |
cs |
Čeština |
da |
Dansk |
de |
Deutsch |
el |
Ελληνικά |
et |
Eesti |
en |
English |
es |
Español (España) |
es-latam |
Español (Latinoamérica) |
es-mx |
Español (México) |
fi |
Suomi |
fil |
Filipino |
fr |
Français |
hi |
हिंदी |
hr |
Hrvatski |
hu |
Magyar |
id |
Bahasa Indonesia |
it |
Italiano |
ja |
日本語 |
ka |
ქართული |
ko |
한국어 |
lv |
Latviešu |
lt |
Lietuvių |
mk |
Македонски |
ms |
Bahasa Melayu |
nb |
Norsk (Bokmål) |
nl |
Nederlands |
pl |
Polski |
pt |
Português (Brasil) |
pt-pt |
Português (Portugal) |
ro |
Română |
ru |
Русский |
si |
සිංහල |
sk |
Slovenčina |
sl |
Slovenski |
so |
Af-soomaali |
sr |
Srpski |
sv |
Svenska |
tr |
Türkçe |
th |
ไทย |
uk |
Українська |
vi |
Tiếng Việt |
zh |
简体中文 |
zh-hant |
繁體中文 |
hy |
հայերեն |
Sessions lifecycle diagram (SDK)
API Guide
Why use the API?
There are a few scenarios where you may not wish to use Veriff's native or web SDKs to verify your end-users. For example:
- You wish to completely implement your own front-end
- You plan to collect end-users' media yourself
- You wish to do an offline bulk audit of previously verified end-users
In those cases, you can do the whole process using our API and you will not show any Veriff front-end to your end-users.
Customer's API flow in a nutshell
Create a verification session
The goal here is to create a new object (a verification session) that contains one verification, nested inside the session object in the response. Also, you will receive the session ID, which you need for the next step. (Guide: Using the API to generate a session for API)
Send end-user's media
Using the session ID, pass the end-user's media (face, document front, document back, etc.) by uploading all images (and video if applicable) one by one using the POST request to sessions/{sessionId}/media endpoint. The goal here is to upload the required photos and associate them with the verification created in step 1.
Take advantage of the additional collected data
In order to further improve the IDV process, we strongly recommend you collect some additional end-user data and send it to us via POST /sessions/{sessionId}/collected-data. This step is not mandatory, but it is highly recommended.
Submit session for review
Once all the media and additional data has been uploaded, you then submit the verification session by sending the PATCH request to
PATCH /sessions/{sessionId} and marking the verification to submitted
status.
Make sure that all the media has been submitted prior to triggering the PATCH request.
Wait for Veriff to verify the end-user
After these three steps, you have done your part, and the verification will then be taken care of by us.
Wait for webhook response
Veriff sends different types of webhooks for different event types using the POST method. For IDV, we send:
- The event webhook to notify you about the progress of the verification flow (events)
- The decision webhook with the verification session decision. It contains more data, including the verified identity information.
Prerequisites to use the API
In order to start sending media over the API, make sure that you:
- Created the integration in the Veriff environment (guide above)
- Configured the webhooks (guide below)
- Have all the necessary API keys, API URL and Headers at hand (guides below here and here)
- You have made sure that you are able to handle the backwards compatible changes
Prerequisites to create API requests
API keys
Log in to Veriff's environment via the link in your sign-up email. Navigate to Integrations page via the top menu and open the Integration you need. From there you need to take:
- the API key, to use it as the X-AUTH-CLIENT value in the Header
- the shared secret key, to create the X-HMAC-SIGNATURE value for the Header
- the BaseURL, to create the API URL for the request
Shared secret key rotation
It is possible to manage your shared secret keys in the Veriff environment. You can add and delete keys, and set the master signature key.
You can have up to 5 shared secret keys.
To manage the keys:
- Log in to the Veriff environment
- Click on the Integrations on the top menu
- Find and open the relevant integration
- All the keys are displayed on the main page, under the shared secret keys field
- You can add a key using the + Add key button
- Use the kebab menu button next to the key to promote it to the master signature key, or to delete it
API URL and Headers
To create the API URL, add v1
to the Base URL value:
https://<Base-URL>/v1/
The list below shows basic Headers. These are often needed to send requests, or are returned in responses:
X-AUTH-CLIENT: string (required) - API key
CONTENT-TYPE: string (required) - Media type of the resource (application/json)
X-HMAC-SIGNATURE: string (required) - HMAC-SHA256 hex encoded keyed hash using your shared secret key
Backwards compatible changes
All the changes listed below are considered to be backwards compatible by Veriff. Make sure to set up your systems in such flexible manner that it is able to handle these changes.
- Adding new properties (e.g., strings, objects, arrays) to existing API responses
- Changing the order* of properties in existing API responses, i.e., the order of strings, objects, arrays
- Adding new API resources, e.g., adding new API endpoints
- Adding new optional request parameters to existing API endpoints
- Changing the length or format of opaque** strings, such as error messages, object IDs, etc.
- Adding new event types to webhooks
- Adding new properties (e.g., strings, objects, arrays) to webhook payloads
- Webhook listener should gracefully handle unfamiliar event types
*As a general note on the order of properties in the responses, keep in mind that the order is not static. This means that the order you see in your API call responses may differ from the order you see in Veriff documentation.
**This means data that your system should be able to just transmit or store, not interpret.
API Reference
Endpoints
Available endpoints and methods:
- POST /sessions
- POST /sessions/{sessionId}/media
- POST /sessions/{sessionId}/collected data
- PATCH /sessions/{sessionId}
- GET /sessions/{sessionId}/attempts
- GET /sessions/{sessionId}/decision
- GET /sessions/{sessionId}/person
- GET /sessions/{sessionId}/media
- GET /sessions/{sessionId}/watchlist-screening
- DELETE /sessions/{sessionId}
- GET /attempts/{attemptId}/media
- GET /media/{mediaId}
- GET /address/{addressId}/media
- GET /address-media/{mediaId}
- POST /validate-registry
- POST /validate-registry-sync-api-v1
- POST /sessions/{sessionId}/consents
- GET /sessions/{sessionId}/decision/ine-registry
- GET /sessions/{sessionId}/decision/curp-registry
- GET /sessions/{sessionId}/decision/combined-ine-curp-registr
POST /sessions
Creates a session with the data specified in the request body.
The customer sends end-user's data to Veriff, and in return receives a unique sessionId
and a unique sessionToken
that are related to the verification session initiated for the specific end-user.
The response also returns the session URL value (required in the SDK integrations). You can find this in the
verification.url
parameter.
You can find the sample implementation for Javascript at https://github.com/Veriff/js-integration-demo
Request
Request method: POST
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
Content-Type: application/json
Request properties explained
verification
:object
Verification objectcallback
:string
ThecallbackUrl
to where the end-user is redirected after the verification session is completed. Default is visible in the Veriff environment > Settings. Changing the value in this request body will overwrite the defaultcallbackUrl
, but it will not change thecallbackUrl
that is visible in the Veriff environment.person
:object
Person to be verifiedfirstName
:string
First namelastName
:string
Last nameidNumber
:string
National identification numbergender
:string
GenderdateOfBirth
:string
(YYYY-MM-DD) Date of birth
document
:object
Document of a person to be verifiednumber
:string
Document number, [a-zA-Z0-9] characters onlycountry
:ISO-2
String Issuing country of the documenttype
:string
(PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS_LICENSE, VISA) Document type. See the document types
address
:object
Address of a person to be verified.fullAddress
:string
Full address (mandatory only for UK DIATF Medium profile flow)
vendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not provided. We require only non-semantic data to be submitted (UUID-s etc.,) that can be user or resolved only inside your environments). Although it can have several use-cases, this is a recommended field to improve fraud mitigation.endUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provided. Recommended field for Biometric Authentication, and a great alternative tovendorData
, especially if using the UUID format to create unique end-user identifiers.consents
:array
Array of objects listing the type of consent given. Optional, should be only included for features that require consent (currently, only the INE Biometric Database Verification)type
:string
Indicates the feature for which the consent is givenapproved
:boolean
Iftrue
, indicates that the consent has been given.true
is mandatory to start the INE Biometric Database Verification. Iffalse
or missing, the session is not created.
Sample Request
curl
curl -X POST \
--url '/v1/sessions/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"callback": "https://veriff.com",
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789"
},
"document": {
"number": "B01234567",
"type": "PASSPORT",
"country": "EE"
},
"address": {
"fullAddress": "Lorem Ipsum 30, 13612 Tallinn, Estonia"
},
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"consents": [
{
"type": "ine",
"approved": true
}
]
}
}'
Node.js
var request = require('request');
var options = { method: 'POST',
url: '/v1/sessions/',
headers:
{ 'Content-Type': 'application/json',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' },
body:
{ verification:
{ callback: 'https://veriff.com',
person:
{ firstName: 'John',
lastName: 'Smith',
idNumber: '123456789' },
document: { number: 'B01234567', type: 'PASSPORT', country: 'EE' },
vendorData: '11111111',
endUserId: 'fa820aba-019f-455a-ae81-cfca8075bc3f',
consents: [
{
type: 'ine',
approved: true
}
]
}
},
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3
import requests
import pprint
import json
url = '/v1/sessions/'
payload = json.dumps({
'verification': {
'callback': 'https://veriff.com',
'person': {
'firstName': 'John',
'lastName': 'Smith',
'idNumber': '123456789'
},
'document': {
'number': 'B01234567',
'type': 'PASSPORT',
'country': 'EE'
},
'vendorData': '11111111',
'endUserId': 'fa820aba-019f-455a-ae81-cfca8075bc3f',
'features': [
'selfid'
],
'consents': [
{
'type': 'ine',
'approved': true
}
]
}
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, data=payload, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Request statusverification
:object
Verification objectid
:UUID
-v4 String UUID v4 which identifies the verification sessionurl
:string
URL of the verification to which the person is redirected (Combination of thebaseUrl
andsessionToken
)vendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedhost
:string
The base url the sessionToken can be used forstatus
:string
Verification session statussessionToken
:string
Session-specific token of the verification
Sample response
{ "status": "success",
"verification":{
"id":"f04bdb47-d3be-4b28-b028-a652feb060b5",
"url": "https://alchemy.veriff.com/v/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoX3Rva2VuIjoiOThiYzdjMjEtZTQ0Yy00MTZiLTkxOTMtMTU5ZGZkMzBmMDg4Iiwic2Vzc2lvbl9pZCI6Ijc2ODhmMzYzLTAyZjctNDE1My1iMzM1LWE0ODQ3OTRkMzZmNyIsImlhdCI6MTUwMTIyODI1MSwiZXhwIjoxNTAxODMzMDUxfQ.bMEF37E6-zT2Aa6Q8UXK3B_ZL51w6D_lxnGgQvhj214",
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"host": "https://alchemy.veriff.com",
"status": "created",
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoX3Rva2VuIjoiOThiYzdjMjEtZTQ0Yy00MTZiLTkxOTMtMTU5ZGZkMzBmMDg4Iiwic2Vzc2lvbl9pZCI6Ijc2ODhmMzYzLTAyZjctNDE1My1iMzM1LWE0ODQ3OTRkMzZmNyIsImlhdCI6MTUwMTIyODI1MSwiZXhwIjoxNTAxODMzMDUxfQ.bMEF37E6-zT2Aa6Q8UXK3B_ZL51w6D_lxnGgQvhj214"
}
}
POST /sessions/{sessionId}/media
Uploads an image (and specifies the type of the image that's being uploaded) for a specific sessionId
.
- Only one image file can be uploaded with one request
- Veriff supports .jpg, .jpeg, .png, .heif, .heic, .webp and .pdf file formats in uploads
- The image file is defined as base64 encoded image string inside a JSON body object
- To avoid issues with upload, keep the image smaller than:
- Image files: 24MB in base64 encoding (approx 17MB in image files format)
- PDFs: 20 MB in pdf format
Information about PDF support
Veriff supports PDF file uploads for Identity Verification (IDV) documents and Proof of Address (PoA) documents.
Identity Verification Feature
In IDV, document images can be uploaded in following configurations:
- Two PDF files, where one file contains document front image and the other file contains document back image
- Single PDF file, which has both document sides on different pages
- Single PDF file, which has both document sides on single page
Veriff processes first 5 pages of uploaded PDF file. System removes empty pages from the PDF.
Proof of Address Feature
The file that is uploaded for Proof of Address flow must contain only one PoA document. If you need to send several PoA documents, upload them one-by-one in separate PDF files.
For PoA, documents can be uploaded in following configurations:
- Single PDF file, where the document data is on one page
- Single PDF file, where the document data spans over several pages
Veriff processes first 5 pages of uploaded PDF file. System removes empty pages from the PDF.
Request
Request method: POST
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
image
:object
(required)context
:string
(required) Context type of the document (one offace
,document-front
,document-back
)content
:string
(required) base64 encoded image (.jpg, .jpeg, .png, .heif, .heic, .webp and .pdf formats are supported)- Example
data:image/png;base64,R0lGODlhAQABAAAAACw=
- Example
Sample request
curl
curl -X POST \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53' \
-d '{
"image": {
"context": "document-front",
"content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII="
}
}'
Node.js
var request = require('request');
var options = { method: 'POST',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' },
body:
{ image:
{ context: 'document-front',
content: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII=' } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url='/v1/sessions/{sessionId}/media'
payload = json.dumps({
'image': {
'context': 'document-front',
'content': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII='
}
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, data=payload, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Request statusimage
:object
Image objectcontext
:string
Context type of the imageid
:UUID-v4
String UUID v4 which identifies the imagename
:string
File name that identifies the imagetimestamp
:object
(Deprecated) Timestamp object, will return null/Nonesize
:integer
Size for the imagemimetype
:string
Format of the media file. See Mimetypes table for more infourl
:string
URL for the image
Sample response
{ "status": "success",
"image":{
"context": "document-back",
"id": "39388f8d-c6d6-4e9b-92c6-6978b2e8d664",
"name": "document-back",
"timestamp": (Deprecated) null,
"size": 52268,
"mimetype": "image/png",
"url": "/v1/media/39388f8d-c6d6-4e9b-92c6-6978b2e8d664"
}
}
POST /sessions/{sessionId}/collected-data
Uploads information that has been collected for improved IDV process. The session must be either in
created
or started
status.
Request
Request method: POST
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
providerName
:string
Name of the fingerprinting service provider, max 255 charactersperson
:object
Information about the person. Optional fieldemail
:string
Person's e-mail address entered during the validation. Optional fieldphoneNumber
:string
Person's phone number, can include numbers, whitespaces and the "+" sign in front. Optional field
network
:object
Network related datamobileCarrier
:string
Name of the service provider. Optional fieldssid
:string
Service Set Identifier (SSID) value. Optional fieldhostname
:string
Service host name. Optional fieldlocation
:object
Location data. Optional fieldcountryCode
:string
ISO 3166-1 Alpha-2 country code. Optional fieldcontinentCode
:string
(EU, NA, AS, SA, AF, OC) Two-letter code of the continent. Optional fieldcity
:string
City name, in English. Optional fieldregion
:string
Region code or name, in English. Optional fieldtimezone
:string
Timezone abbreviation as listed in the Timezones Database. Optional field
ip
:object
IP info. At least one is mandatory!addressV4
:string
IPv4 info. Optional if IPv6 info is includedaddressV6
:string
IPv6 info. Optional if IPv4 info is included
asn
:object
ASN info. Optional fieldnumber
:string
Autonomous System Number (ASN). Optional fieldorganisation
:string
Name of the organization owning the ASN. Optional field
device
:object
End-user's device related datafingerprint
:string
Device fingerprint, max 255 charactersandroidId
:string
The Android unique device ID is a combination of 8 digits and letters, followed by a dash and three sets of 4 digits and letters, all letters are lowercase. Optional fieldidfv
:string
The Identifier for Vendors (IDFV) code, example F325G3GB-12FC-352F-C6C3-DZ52F0F690D8. Optional fieldmodel
:string
Device model. Optional fieldvendor
:string
Device supplier. Optional fieldtype
:string
(desktop, mobile, tablet, other) Device type. Optional fieldbrowser
:object
Browser data. Optional fieldlanguages
:array
IETF language tag, for example: "es-419", "en-gb", "pl". Optional fielduserAgent
:string
Browser user agent, max 255 characters. Optional fieldtimezoneOffsetMinutes
:number
An integer number for the time offset from the UTC, in minutes (range from -1440 to +1440 minutes) Optional fieldisIncognito
:boolean
Data about whether the incognito mode is on. Optional field
audio
:object
Device audio info. Optional fielddevices
: [{name
:string
}] Array of objects. Optional field
screen
:object
Data about device screen. Optional fieldheightPixels
:number
An integer number in range of 1–100000. Optional fieldwidthPixels
:number
An integer number in range of 1–100000. Optional fielddpi
:number
An integer number in range of 1–100000. Optional field
battery
:object
Device battery related info. Optional fieldlevel
:number
A float in range of 0.0–1.0. Optional fieldcharging
:boolean
Data about whether the device is charging. Optional field
os
:object
Device operating system (OS) data. Optional fieldfamily
:string
OS family. Optional fieldname
:string
OS name. Optional fieldplatform
:string
OS platform type, for example "x64", "ARM", "OS/390". Optional fieldversion
:string
OS version. Optional field
Sample Request
curl
curl -X POST \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/collected-data' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API key' \
-H 'X-HMAC-SIGNATURE: 034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53' \
-d '{
"providerName": "SampleName",
"person": {
"email": "firstname.lastname@domain.com",
"phoneNumber": "+11 222 333 44"
},
"network": {
"mobileCarrier": "RandomTeleCom Inc",
"ssid": "12345",
"hostname": "examplehostname.amazonaws.com",
"location": {
"countryCode": "US",
"continentCode": "NA",
"city": "New York",
"region": "New York",
"timezone": "EDT"
},
"ip": {
"addressV4": "192.168.XXX.XXX"
},
"asn": {
"number": "AS12345",
"organisation": "AWS"
}
},
"device": {
"fingerprint": "123456asdfg7890hijkl123456asdfg7890hijkl123456asdfg7890hijkl",
"androidId": "ab1357cd-a1b2-c3d4-f5g6",
"idfv": "F325G3GB-12FC-352F-C6C3-DZ52F0F690D8",
"model": "Samsung Galaxy S23 Ultra",
"vendor": "Samsung",
"type": "mobile",
"browser": {
"languages": ["en-gb"],
"timezoneOffsetMinutes": -240,
"isIncognito": false
},
"screen": {
"heightPixels": 3088,
"widthPixels": 1440,
"dpi": 500
},
"battery": {
"level": 0.43,
"charging": true
},
"os": {
"family": "Android",
"name": "Android",
"version": "13"
}
}
}'
Node.js
var request = require('request');
var options = {
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/collected-data',
method: 'POST',
headers: {
'Content-Type': 'application/json'
'X-AUTH-CLIENT': 'API key' \
'X-HMAC-SIGNATURE': '034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53'
},
body: {
"providerName": "SampleName",
"person": {
"email": "firstname.lastname@domain.com",
"phoneNumber": "+11 222 333 44"
},
"network": {
"mobileCarrier": "RandomTeleCom Inc",
"ssid": "12345",
"hostname": "examplehostname.amazonaws.com",
"location": {
"countryCode": "US",
"continentCode": "NA",
"city": "New York",
"region": "New York",
"timezone": "EDT"
},
"ip": {
"addressV4": "192.168.XXX.XXX"
},
"asn": {
"number": "AS12345",
"organisation": "AWS"
}
},
"device": {
"fingerprint": "123456asdfg7890hijkl123456asdfg7890hijkl123456asdfg7890hijkl",
"androidId": "ab1357cd-a1b2-c3d4-f5g6",
"idfv": "F325G3GB-12FC-352F-C6C3-DZ52F0F690D8",
"model": "Samsung Galaxy S23 Ultra",
"vendor": "Samsung",
"type": "mobile",
"browser": {
"languages": ["en-gb"],
"timezoneOffsetMinutes": -240,
"isIncognito": false
},
"screen": {
"heightPixels": 3088,
"widthPixels": 1440,
"dpi": 500
},
"battery": {
"level": 0.43,
"charging": true
},
"os": {
"family": "Android",
"name": "Android",
"version": "13"
}
}
}
},
json: true };
request(options, function (error, response, body) {
if (error) {
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestsessionId
:string
UUID v4 which identifies the verification sessionattemptId
:string
UUID v4 which identifies the attempt
Sample response
{
"status": "success",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"attemptId": "f5c68aea-7f4d-478d-80ab-ca9356074f69"
}
PATCH /sessions/{sessionId}
Changes the status of the verification to "submitted".
Request
Request method: PATCH
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
verification
:object
(required)status
:string
(required) Status of a verification ("submitted")
Sample request
curl
curl -X PATCH \
--url '/v1/sessions/fd5c1563-1d23-4b1a-ae46-7ba429927ed8' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0' \
-d '{
"verification": {
"status": "submitted"
}
}'
Node.js
var request = require('request');
var options = { method: 'PATCH',
url: '/v1/sessions/fd5c1563-1d23-4b1a-ae46-7ba429927ed8',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': 'dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' },
body:
{ verification:
{ status: 'submitted' } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/{sessionId}'
payload = json.dumps({
'verification': {
'status': 'submitted'
}
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': 'dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0',
'Content-Type': 'application/json'
}
response = requests.request('PATCH', url, data=payload, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Request statusverification
:object
Verification objectid
:UUID-v4
String UUID v4 which identifies the verification sessionurl
:string
URL for the timestampvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedhost
:string
Host URIstatus
:string
Status of the verificationsessionToken
:string
Session specific token of the verification
Sample response
{
"status": "success",
"verification": {
"id": "fd5c1563-1d23-4b1a-ae46-7ba429927ed8",
"url": "https://alchemy.veriff.com/v/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoiZmQ1YzE1NjMtMWQyMy00YjFhLWFlNDYtN2JhNDI5OTI3ZWQ4IiwiaWF0IjoxNTcyMzM4MDIwfQ.3HbNq0YWKAfFrH-P658_WXMwcUMubyC1aXAMo-umfCU",
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"host": "https://alchemy.veriff.com",
"status": "submitted",
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoiZmQ1YzE1NjMtMWQyMy00YjFhLWFlNDYtN2JhNDI5OTI3ZWQ4IiwiaWF0IjoxNTcyMzM4MDIwfQ.3HbNq0YWKAfFrH-P658_WXMwcUMubyC1aXAMo-umfCU"
}
}
GET /sessions/{sessionId}/attempts
Returns the list of attempt objects with sessionId = {sessionId}
Returns the user-defined statuses data if those have been set in the Veriff environment.
Request
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/attempts' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/attempts',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/attempts'
headers = {Response
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestverifications
:array
Array of JSON objects identifying the attemptsid
:UUID
-v4 of the attemptstatus
:string
Status of the attempt. It can be one ofcreated
,started
,abandoned
,expired
,submitted
,approved
,resubmission_requested
,declined
,inflow_completed
,review
.userDefinedData
:array
Array of objects describing the custom statuses defined by the user. Instructions how to add statuses can be found here [↗] (requires a login to the Veriff environment).status
:string
Name of the custom status as set in the Veriff environmentstatusCode
:string
Autogenerated code for the custom statusreason
:string
Name of the custom reason as set in the Veriff environment. If the user has selected the "Custom" reason for the status and typed an explanation to the text box, then the explanation is sent in this field.reasonCode
:string | null
Autogenerated code for the reason. It isnull
when the user has selected the "Custom" reason for the status and typed an explanation to the text box. This explanation is sent in thereason
parameter.createdAt
:string
Timestamp of when the custom status was added. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone Offset
createdTime
:string
Timestamp of when the attempt was created. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone Offset
Sample Response (simple)
{
"status": "success",
"verifications": [
{
"id": "f5c68aea-7f4d-478d-80ab-ca9356074f69",
"status": "approved"
},
{
"id": "f2270684-8c51-4d03-88eb-dafd43e8b486",
"status": "resubmission_requested"
}
]
}
Sample Response (user-defined statuses added)
In the sample below the user has added a status for the attempt in the Veriff environment, but has not enabled the "Custom" option for the status.
{
"status": "success",
"verifications": [
{
"id": "a1c68aea-7f4d-478d-80ab-ca9356074f69",
"status": "approved",
"userDefinedData":[
{
"status":"Custom status for suspicious attempt",
"statusCode":"custom_status_for_suspicious_attempt",
"reason":"Looks like velocity abuse",
"reasonCode":"looks_like_velocity_abuse",
"createdAt":"2023-09-18T08:41:41.606636Z"
}
],
"createdTime":"2023-09-18T08:33:30.047935Z"
},
{
"id": "f2270684-8c51-4d03-88eb-dafd43e8b486",
"status": "resubmission_requested"
}
]
}
In the sample below the user has added a status for the attempt in the Veriff environment, has enabled the "Custom" option for the status and added an explanation to the text box.
{
"status": "success",
"verifications": [
{
"id": "a1c68aea-7f4d-478d-80ab-ca9356074f69",
"status": "approved",
"userDefinedData":[
{
"status":"Custom status for suspicious attempt",
"statusCode":"custom_status_for_suspicious_attempt",
"reason":"The document used in this attempt is clearly a cut-out",
"reasonCode": null,
"createdAt":"2023-09-18T08:41:41.606636Z"
}
],
"createdTime":"2023-09-18T08:33:30.047935Z"
},
{
"id": "f2270684-8c51-4d03-88eb-dafd43e8b486",
"status": "resubmission_requested"
}
]
}
GET /sessions/{sessionId}/decision
Returns the session decision with sessionId = {sessionId}
In order to receive the decision payload from us:
- the Integration needs to have the Webhook decisions URL configured
- the session related to the
sessionId
needs to have one of 9000-code statuses, otherwise you will seeDecision not available
in the response payload
Test integrations
For test integrations, the Webhook decision URL is added automatically.
But you need to manually set the session's status in the Veriff Environment:
- Open the verification session on Verifications page
- Press the Update status button
- Select a status
Live integrations
For live integrations, you need to define the Webhook decisions URL:
- Go to the Integrations page
- Open the relevant integration
- Navigate to Integration Settings
- Add your URL to the Webhook decisions URL field
In live integrations, the session statuses are set automatically.
Request
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: 'https://<Base-URL>/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = 'https://<Base-URL>/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a/decision'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Response body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the responseverification
:object
Verification request decision object. Null if decision is not available yetid
:string
UUID v4 which identifies the verification sessioncode
:integer
(one of 9001, 9102, 9103, 9104, 9121) Verification response code. More information about decision codesperson
:object
Verified persongender
:string | null
(M, F or Null) GenderidNumber
:string | null
National identification numberlastName
:string | null
Last namefirstName
:string | null
First namecitizenship
:(Deprecated)
null
dateOfBirth
:string
(YYYY-MM-DD) Date of birthnationality
:string | null
NationalityyearOfBirth
:string | null
(YYYY) Year of birthplaceOfBirth
:string | null
Place of birthpepSanctionMatch
:string | null
PEP check result. Optional, depending on integration.occupation
:string | null
Occupation data from the document. Optional, depending on integration.employer
:string | null
Employer's name from the document. Optional, depending on integration.foreginerStatus
:string | null
) Foreigner status field from the document. Optional, depending on integration.extraNames
:string
Additional name from the document. Optional, depending on integration.addresses
:array
Address data from the document. Optional, depending on integration.fullAddress
:string
Address as single string.parsedAddress
:object
Object with parsedfullAddress
. It is optional, depending on integration.city
:string | null
Any human settlement, including cities, towns, villages, hamlets, localities, etc.unit
:string | null
An apartment, unit, office, lot, or other secondary unit designatorstate
:string | null
A first-level administrative division. For example, Scotland, Northern Ireland, Wales, and England in the UK are mapped to "state" as well (convention used in OSM, GeoPlanet, etc.)street
:string | null
Name of the streetcountry
:string | null
Sovereign nations and their dependent territories, anything with an ISO-3166 codepostcode
:string | null
Postal codes used for mail sortinghouseNumber
:string | null
External (street-facing) building number
reason
:string | null
Reason of failed Verificationstatus
:approved
(one of approved, resubmission_requested, review, declined, expired, abandoned) Verification statuscomments
:array
(Deprecated)document
:object
Verified documenttype
:string
(PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS_LICENSE, VISA, OTHER) Document type. See the document typesnumber
:string | null
Document number, [a-zA-Z0-9] characters onlycountry
:string | null
Document issuing country, as ISO 3166 alpha-2 coderemarks
:string
Data extracted from the document's remarks fieldstate
:string | null
Document issuing state, as ISO 3166 alpha-2 or alpha-3 code.null
when the state data is not present on the documentvalidFrom
:string | null
Document is valid from datevalidUntil
:string | null
Document is valid until dateplaceOfIssue
:string | null
Place where document was issued. Optional field, depending on integration.firstIssue
:string | null
Date of document first issue in YYYY-MM-DD format. Optional field, depending on integration.issueNumber
:string | null
Document issue number. Optional field, depending on integration.issuedBy
:string | null
Document issuing authority. Optional field, depending on integration.nfcValidated
:boolean
Biometric document data has been successfully decoded. Optional field, depending on integration.residencePermitType
:string
Type of the residence permit type from the document. Optional, depending on integration.portraitIsVisible
:boolean
Indicates that the portrait image is visible in the session and its quality is sufficient to perform verification. Optional, depending on the integrationsignatureIsVisible
:boolean
Indicates that the signature is present on the document and readable to perform the verification. Optional, depending on the integration
reasonCode
:integer | null
Reason code of failed Verification See Response and error codesvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provideddecisionTime
:string
Timestamp of the decision. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsetacceptanceTime
:string
Timestamp of the session generation. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsethighRisk
:boolean
(Deprecated) If session is considered high risk or not. Optional, depending on integration.additionalVerifiedData
:object
Data which has been optionally verified for session.driversLicenseCategory
:object
Optional, depending on integration.B
:boolean | null
driversLicenseCategoryFrom
:object
Date when the driving license category was obtained. Optional, depending on integration.B
:string | null
Category is valid from date in YYYY-MM-DD format
driversLicenseCategoryUntil
:object
Driving license category expiry date. Optional, depending on integration.B
:string | null
Category is valid until date in YYYY-MM-DD format
estimatedAge
:number
An integer number representing the estimated age. Optional, depending on integration.estimatedGender
:number
A float representing the estimated gender. Optional, depending on integration. Values closer to 0.0 indicate 'male', values closer to 1.0 indicate 'female'.processNumber
:string
Process number (e.g., "Trámite №") from the document. Optional, depending on integration.driversLicenseNumber
:string
Number of the driver's license. Optional, depending on integration.cpfValidation
:object | null
Brazilian individual taxpayer registry (CPF) validation check object. Optional, depending on integrationstatus
:string | null
Status of the entry in the registry (one of CPF is validated, CPF is suspended, CPF holder is deceased, CPF is pending regularization, CPF is cancelled (was a duplicate), Cancelled craft (meaning that it was cancelled due to reasons other than being a duplicate))cpfNumber
:string | null
Brazilian individual taxpayer registry (CPF) number of the personname
:string | null
Person's name in the CPFdateOfBirth
:string | null
Person's date of birth in the CPF as YYYY-MM-DDyearOfDeath
:string | null
Person's year of death in the CPF as YYYY
ineBiometricRegistryValidation
:object
INE Biometric Database Verification check object. Optional, available only when the INE Biometric Validation check has been enabled for the integrationfaceMatch
:boolean | null
Indicates if the person's selfie image is a match with their image in the registry. This decision is made based on the value returned infaceMatchPercentage
(see below).null
if the check could not be completedfaceMatchPercentage
:integer | null
Indicates the level of similarity the system thinks the matched images have, in the range of 0-100. Values ≥85 indicate a match; values <85 indicate that images do not match.null
if the check could not be completedresponseStatus
:string | null
Indicates the response received from the service provider. One ofsuccess
orfailure
; ornull
if the check could not be completed
riskScore
:object
Data about the risk scorescore
:number
A float in the range of 0.0–1.0. Numerical value representing the overall risk associated with the session. Lower score indicates more confidence in that the session is genuine. Note: in the Veriff environment, the range is shown as 1–100.
riskLabels
:array
Optional array of risk labels related to the session. The presence of this property depends on risk labels being enabled for the integration. Full list of risk labels (requires login to Veriff's environment) [↗]label
:string
Name of the risk labelcategory
:string
(one of client_data_mismatch, cross-links, device, document, images, network, session, person)sessionIds
:array of strings
Array of verification IDs that are referenced to the particular risk label
biometricAuthentication
:object
Object containing data about the biometric authentication. Optional, available only when using the Biometric Authentication solutionmatchedSessionId
:string | null
Refers to the verification session ID which the face matchedmatchedSessionEndUserId
:string | null
Refers to the verification sessionendUserId
which the face matchedmatchedSessionVendorData
:string | null
Refers to the verification sessionvendorData
which the face matcheddetails
:object
Lists the results of different checks that were made to verify the end-user. Log in to the Veriff environment to see the detailed request explanation and a sample request[↗].
technicalData
:object
Technical data objectip
:string | null
IP of the device from which the verification was made
Sample Response
{
"status": "success",
"verification": {
"id": "12df6045-3846-3e45-946a-14fa6136d78b",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"lastName": "MORGAN",
"addresses": [
{
"fullAddress": "1234 Snowy Ridge Road, Indiana, 56789 USA",
"parsedAddress": {
"city": null,
"unit": null,
"state": "Indiana",
"street": "1234 Snowy Ridge Road",
"country": "USA",
"postcode": "56789",
"houseNumber": "null"
}
}
],
"firstName": "SARAH",
"citizenship": null,
"dateOfBirth": "1967-03-30",
"nationality": null,
"yearOfBirth": "1967",
"placeOfBirth": "MADRID",
"occupation": "Sales Representative",
"employer": "Any Company LLC",
"foreignerStatus": "EXTRANJERO",
"extraNames": "NOM D'USAGE",
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": "DRIVERS_LICENSE",
"number": "MORGA753116SM9IJ",
"country": "US",
"remarks": "WORK PERMITTED",
"state": "NY",
"placeOfIssue": "NEW YORK",
"validFrom": null,
"validUntil": "2022-04-20",
"firstIssue": "2015-03-21",
"issueNumber": "01",
"issuedBy": "ISSUER",
"nfcValidated": "true",
"residencePermitType": "C",
"portraitIsVisible": "true",
"signatureIsVisible": "true"
},
"reasonCode": null,
"vendorData": "12345678",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"decisionTime": "2019-11-06T07:18:36.916Z",
"acceptanceTime": "2019-11-06T07:15:27.000Z",
"additionalVerifiedData": {
"driversLicenseCategory": {
"B": true
},
"driversLicenseCategoryFrom": {
"B": "2019-10-06"
},
"driversLicenseCategoryUntil": {
"B": "2025-10-05"
},
"estimatedAge": 32,
"estimatedGender": 0.613,
"processNumber": "12345678912 1234",
"driversLicenseNumber": "1234569",
"cpfValidated": {
"status": "CPF is validated"
"cpfNumber": "123456789",
"name": "SARAH MORGAN",
"dateOfBirth": "1967-03-30",
"yearOfDeath": null
},
"ineBiometricRegistryValidation": {
"faceMatch": true,
"faceMatchPercentage": 89,
"responseStatus": "success"
}
},
"riskScore": {
"score": 0.12
},
"riskLabels": [
{
"label": "document_integration_level_crosslinked_with_fraud",
"category": "document",
"sessionIds": ["5a2358e7-fd31-4fcb-a23f-4d76651ba68a"]
},
{
"label": "document_integration_level_crosslinked_with_multiple_declines",
"category": "document",
"sessionIds": ["fd5c1563-1d23-4b1a-ae46-7ba429927ed8"]
}],
"biometricAuthentication": {
"matchedSessionId": "d40edb60-6ae6-4475-be72-84b81669cce6",
"matchedSessionEndUserId": "a1b2c35d-eš8f7-6d5e-3cd2-a1b2c35db3d4",
"matchedSessionVendorData": "12345678"
"details": {
...
}
}
},
"technicalData": {
"ip": "186.153.67.122"
}
}
GET /sessions/{sessionId}/person
Returns information objects
about a person (hereinafter the Person) associated with
the specific sessionId
.
Request
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/person' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/person',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/person'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestperson
:object
List of objects identifying the Person associated with the search termid
:uuid
Unique identifier of the PersonfirstName
:string | null
Person's first name as written on the document, if presentlastName
:string | null
Person's last name as written on the document, if presentidCode
:string
Person's ID codedateOfBirth
:string
(YYYY-MM-DD) Person's date of birthgender
:string
(M: male, F: female, null: undefined) Person's gendernationality
:string
ISO 3166-1 Alpha-2 country codeplaceOfBirth
:string
Person's place of birthcitizenships
: Deprecated, will return [ ]pepSanctionMatches
:array
Array of objects identifying the PEP and Sanction values. The array is empty if there are no hits in the databaseprovider
:string
Name of the data providernumberOfMatches
:number
Total number of hitsdate
:string
Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2018-04-18T11:02:05.261Z)matches
:array
Array listing info about matches to the search termname
:string
Person's namenationality
:string
Person's nationalitycategory
:string
Defines the category, SIP of PEP
hits
:array
Array of objects listing results that match the search termdoc
:object
List of attributes identifying the info in the document of the Personid
:string
Document number, [a-zA-Z0-9] characters onlylastUpdatedUtc
: Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2018-04-18T11:02:05.261Z)createdUtc
: Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:S.SSS+Timezone Offset|Z, i.e., 2018-04-18T11:02:05.261Z)fields
:array
Array of objects describing the document fieldsname
:string
Name of the document fieldsource
:string
Source of the information in the documentvalue
:string
Value in the document fieldtag
:string
Tag related to the name objectlocale
:string
Language
types
:array
Array of match types names as defined by the data provider (possible match types names: adverse-media, adverse-media-v2-cybercrime, adverse-media-v2-financial-aml-cft, adverse-media-v2-financial-difficulty, adverse-media-v2-fraud-linked, adverse-media-v2-general-aml-cft, adverse-media-v2-narcotics-aml-cft, adverse-media-v2-other-minor, adverse-media-v2-other-serious, adverse-media-v2-property, adverse-media-v2-terrorism, adverse-media-v2-violence-aml-cft, adverse-media-v2-violence-non-aml-cft, pep, pep-class-1, pep-class-2, sanction, warning)name
:string
Person's name on the documententityType
:string
(person) Type of entity. In this GET request, it's always "person"aka
:array
Array of objects listing the alternative names of the Personname
:string
Person's alternative name
associates
:array
Array of objects identifying Associates of the Personassociation
:string
Type of association (relationship)name
:string
Associate's name
sources
:array
Info about the information sourceskeywords
:array
Will return []media
:array
Array of objects containing media about the Persondate
:string
Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2022-04-18T11:02:05.261Z)snippet
:string
Text about the Persontitle
:string
Title of the text about the Personurl
:string
Web address to the text about the Person
assets
:array
Array listing the info about media sourcespublicURL
:string
Web addresssource
:string
Name of the sourcetype
:string
File format
sourceNotes
:object
List of attributes identifying the information sourceamlTypes
:array
List of types as defined by the data providercountry_codes
:array
List of country ISO 1366-1 Alpha-2 codeslistingStartedUtc
:string
Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2022-04-18T11:02:05.261Z)name
:string
Name of the info sourceurl
:string
Web address of the info source
matchTypes
:array
Info about which data was matched. Returns the first value that is true from the following values: name_exact, aka_exact, name_fuzzy, aka_fuzzy, phonetic_name, phonetic_aka, equivalent_name, equivalent_aka, unknown. If appropriate, the secondary match type is returned: year_of_birth, removed_personal_title, removed_personal_suffix, removed_organisation_prefix, removed_organisation_suffix, removed_clerical_mark. Please see the data provider's documentation [↗] for more detailed info.matchTypesDetails
:object
List of more detailed breakdown of why a match happenedmatchTypes
:string
(matching_name, sources, aml_types, name_matches, secondary_matches) More detailed info about why a hit occurred. Please see the data provider's documentation [↗] for more detailed info.type
:string
Displays the type of the match_type that was matched
matchStatus
:string
(no_match, false_positive, potential_match, true_positive, unknown, true_positive_approve, true_positive_reject) Status of the matchisWhitelisted
:boolean
Indicates whether an entity has been whitelisted. Availability depends on the configurationscore
:decimal
Optional field. The request results match and ranking is computed via a score that is included as part of the metadata. It is not an absolute ranking of the document, only giving some relative indication of relevance. This value comes from the data provider.
Sample response from the data provider
{
"status": "success",
"person": {
"id": "b00a203e-2524-4ded-867b-b4e281a2c96b",
"firstName": "MUAMMAR GADDAFI",
"lastName": null,
"idCode": "062.449.269-94",
"dateOfBirth": "1942-09-22",
"gender": null,
"nationality": null,
"placeOfBirth": null,
"citizenships": [],
"pepSanctionMatches": [
{
"provider": "Comply Advantage",
"numberOfMatches": 1,
"date": "2022-07-12T12:42:30.573Z",
"matches": [],
"hits": [
{
"doc": {
"id": "4KJL9THDX9ZNV4W",
"lastUpdatedUtc": "2022-07-09T12:50:34Z",
"createdUtc": "2020-03-17T19:32:58Z",
"fields": [
{
"name": "Original Country Text",
"source": "world-bank-star-asset-recovery-watch",
"value": "European Union"
},
{
"name": "Nationality",
"source": "complyadvantage",
"value": "Libya"
},
{
"name": "Original Place of Birth Text",
"source": "hong-kong-special-administrative-region-sanctions-issued-under-the-un-sanctions-ordinance",
"value": "Sirte"
},
{
"name": "Original Country Text",
"source": "complyadvantage",
"value": "East Africa"
}
],
"types": [
"adverse-media",
"adverse-media-v2-cybercrime",
"adverse-media-v2-financial-aml-cft",
"adverse-media-v2-financial-difficulty",
"adverse-media-v2-fraud-linked",
"adverse-media-v2-general-aml-cft",
"adverse-media-v2-narcotics-aml-cft",
"adverse-media-v2-other-minor",
"adverse-media-v2-other-serious",
"adverse-media-v2-property",
"adverse-media-v2-terrorism",
"adverse-media-v2-violence-aml-cft",
"adverse-media-v2-violence-non-aml-cft",
"pep",
"pep-class-1",
"pep-class-2",
"sanction",
"warning"
],
"name": "Mouammar Mohammed Abu Minyar Kadhafi",
"entityType": "person",
"aka": [
{
"name": "Moamarr Qaddafi"
},
{
"name": "Moammar Kaddafi"
},
{
"name": "Muammer al Gaddafi"
},
{
"name": "মোৱাম্মাৰ গাড্ডাফি"
},
{
"name": "Moammar Khadafi"
}
],
"associates": [
{
"association": "spouse",
"name": "Fatiha al-Nuri"
},
{
"association": "spouse",
"name": "Fatiha al-Nuri Gaddafi"
},
{
"association": "child",
"name": "Qadhafi Muammar Mohammed Abu Minyar"
},
{
"association": "spouse",
"name": "Safia el-Brasai"
},
{
"association": "spouse",
"name": "Safia el-Brasai Gaddafi"
}
],
"sources": [
"argentina-ministerio-de-relaciones-exteriores-y-culto-sanciones-de-la-onu",
"belarus-state-security-agency-list-of-organizations-and-individuals-involved-in-terrorist-activities"
],
"keywords": [],
"media": [
{
"date": "2021-11-16T00:00:00Z",
"snippet": "Sang Tan Judges in the High Court in London have ruled that Saleh Ibrahim Mabrouk, a former aide of Libyan leader Colonel Muammar Gaddafi, was partly to blame for the murder of PC Yvonne Fletcher. The gunman",
"title": "'Justice at Last': Former Gaddafi Aide Found Liable for 1984 Police Officer Murder by UK High Court - 16.11.2021, Sputnik International",
"url": "https://sputniknews.com/amp/20211116/justice-at-last-former-gaddafi-aide-found-liable-for-1984-police-officer-murder-by-uk-high-court-1090775876.html"
}
],
"assets": [
{
"publicUrl": "http://complyadvantage-asset.s3.amazonaws.com/76993a49-2d1e-4397-9e35-1e20f2b7dfa8.pdf",
"source": "world-bank-star-asset-recovery-watch",
"type": "pdf"
}
],
"sourceNotes": {
"argentinaMinisterioDeRelacionesExterioresYCultoSancionesDeLaOnu": {
"amlTypes": [
"sanction"
],
"listingStartedUtc": "2019-09-26T00:00:00Z",
"name": "Argentina Ministerio de Relaciones Exteriores y Culto Sanciones de la ONU",
"url": "https://www.cancilleria.gob.ar/es/politica-exterior/seguridad-internacional/comite-de-sanciones"
},
"belarusStateSecurityAgencyListOfOrganizationsAndIndividualsInvolvedInTerroristActivities": {
"amlTypes": [
"sanction"
],
"listingStartedUtc": "2019-08-28T00:00:00Z",
"name": "Belarus State Security Agency List of Organizations and Individuals Involved in Terrorist Activities",
"url": "http://kgb.by/ru/perechen-inf-ru/"
},
"complyadvantageAdverseMedia": {
"amlTypes": [
"adverse-media",
"adverse-media-v2-cybercrime",
"adverse-media-v2-financial-aml-cft",
"adverse-media-v2-financial-difficulty",
"adverse-media-v2-fraud-linked",
"adverse-media-v2-general-aml-cft",
"adverse-media-v2-narcotics-aml-cft",
"adverse-media-v2-other-minor",
"adverse-media-v2-other-serious",
"adverse-media-v2-property",
"adverse-media-v2-terrorism",
"adverse-media-v2-violence-aml-cft",
"adverse-media-v2-violence-non-aml-cft"
],
"countryCodes": [
"AE",
"AM",
"AR"
],
"name": "ComplyAdvantage Adverse Media"
},
"dfatAustraliaList": {
"amlTypes": [
"sanction"
],
"countryCodes": [
"LY",
"OM"
],
"listingStartedUtc": "2011-02-26T00:00:00Z",
"name": "DFAT Australia Consolidated Sanctions List",
"url": "https://www.dfat.gov.au/international-relations/security/sanctions/Pages/consolidated-list.aspx"
}
},
},
"matchTypes": [
"aka_exact",
"year_of_birth"
],
"matchTypesDetails": {
"gaddafiMuammar": {
"matchTypes": {
"gaddafi": [
"name_exact"
],
"muammar": [
"name_exact"
]
},
"type": "aka"
},
"muammarGaddafi": {
"matchTypes": {
"gaddafi": [
"name_exact"
],
"muammar": [
"name_exact"
]
},
"type": "aka"
}
},
"matchStatus": "potential_match",
"isWhitelisted": false,
"score": 24.46217
}
]
}
]
}
}
GET /sessions/{sessionId}/media
Returns a list of media objects
with sessionId = {sessionId}
The list of objects are sorted based on their accuracy (e.g., does an image match the required image type) and their quality. The order is determined by the automation system.
Note that the request will return the media objects of the most recent attempt. If you require the media of a certain
attempt, you can call the list of attemptId
-s with GET sessions/{sessionId}/attempts
and then use the GET attempts/{attemptId}/media to get the media of a specific attempt.
Request
Request method: GET
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14'
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestvideos
:array
Array of JSON objects identifying the videoscontext
:string
Context type of the video. See here for more info about the videocontext
.id
:UUID
-v4 Video Idmimetype
:string
Format of the media file. See Mimetypes table for more infoname
:string
Video namesessionId
:UUID
-v4 Session Idduration
:string
Video duration in secondsurl
:string
Video download urlsize
:string
Video size in bytestimestamp
:object
(Deprecated) Timestamp object, will return null/None
images
:array
Array of JSON objects identifying the imagescontext
:string
Context type of the image. See here for more info about the imagecontext
.id
:UUID
-v4 Image Idname
:string
Image nameurl
:string
Image download urlsessionId
:UUID
-v4 Session Idsize
:string
Image size in bytesmimetype
:string
Format of the media file. See Mimetypes table for more infotimestamp
:object
(Deprecated) Timestamp object, will return null/None
Sample response
{
"status": "success",
"videos": [
{
"context": "{VIDEO_TYPE}",
"duration": "{DURATION_IN_SECONDS}",
"id": "{MEDIA_ID}",
"mimetype": "{MEDIA_MIME_TYPE}",
"name": "{VIDEO_NAME}",
"sessionId": "{SESSIOND_ID}",
"size": "{SIZE_IN_B}",
"timestamp": (Deprecated) null,
"url": "{MEDIA_DOWNLOAD_URL}"
}
],
"images": [
{
"context": "{IMAGE_TYPE}",
"id": "{MEDIA_ID}",
"name": "{IMAGE_NAME}",
"url": "{MEDIA_DOWNLOAD_URL}",
"sessionId": "{SESSIOND_ID}",
"timestamp": (Deprecated) null,
"size": "{SIZE_IN_B}",
"mimetype": "{MEDIA_MIME_TYPE}"
}
]
}
GET /sessions/{sessionId}/watchlist-screening
Returns a list of data objects from PEP and Sanctions services for specific sessionId
.
Only available for customers using the Veriff PEP and Sanctions services.
Request
Request method: GET
Media type: application/json
Type: object.
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= session
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/watchlist-screening' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/watchlist-screening',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/watchlist-screening'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the responsedata
:object
Status of the responseattemptId
:string
UUID v4 which identifies session attemptsessionId
:string
UUID v4 which identifies sessionvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedcheckType
:string
(one of initial_result, updated_result)matchStatus
:string
(one of possible_match, no_match)searchTerm
:object
Data used to perform the checkname
:string
Full name used during the checkyear
:string
Birth year used during the check
totalHits
:integer
Total number of hits returned from the checkcreatedAt
:string
Timestamp indicating when the check response was receivedhits
:array
Check response hits array of matched records. Empty array if no hits were not foundmatchedName
:string
The name that was matched in this hit based on the search termcountries
:array
List of countries that sources listed in relation to this hitdateOfBirth
:string
Birth date of the person in the matched listingsdateOfDeath
:string
Death date of the person in the matched listingsmatchTypes
:array
Array that shows the match type in the listingsaka
:array
Array of names that the matched person is also known asassociates
:array
Array of names that the matched person is associated withlistingsRelatedToMatch
:object
Matched listingswarnings
:array
Array of warning matches. Empty array if no warnings were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
sanctions
:array
Array of sanctions matches. Empty array if no sanctions were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
fitnessProbity
:array
Array of fitness probity matches. Empty array if no fitness probabilities were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
pep
:array
Array of PEP matches. Empty array if no PEP matches were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
adverseMedia
:array
Array of media matches. Empty array if no media were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
Sample response
No match
{
"status": "success",
"data": {
"attemptId": "aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"vendorData": null,
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"checkType": "initial_result",
"matchStatus": "no_match",
"searchTerm": {
"name": "Juan Rico"
},
"totalHits": 0,
"createdAt": "2021-06-15T08:27:33.015Z",
"hits": []
}
}
Possible match
{
"status": "success",
"data": {
"attemptId": "aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"vendorData": null,
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"checkType": "updated_result",
"matchStatus": "possible_match",
"searchTerm": {
"name": "Mirko Kokki",
"year": "1960"
},
"totalHits": 1,
"createdAt": "2021-07-05T13:23:59.851Z",
"hits": [{
"matchedName": "Miro kokkino",
"countries": [
"Australia",
"Brazil"
],
"dateOfBirth": "1963",
"dateOfDeath": null,
"matchTypes": [
"aka_exact",
"year_of_birth"
],
"aka": [
"Mirkoni kokki",
"Mirkor Kokki"
],
"associates": [
"Desmon Lamela",
"Fred Austin"
],
"listingsRelatedToMatch": {
"warnings": [{
"sourceName": "FBI Most Wanted",
"sourceUrl": "http://www.fbi.gov/wanted",
"date": null
}],
"sanctions": [{
"sourceName": "Argentina Ministerio de Relaciones Exteriores y Culto Sanciones de la ONU",
"sourceUrl": "https://www.cancilleria.gob.ar/es/politica-exterior/seguridad-internacional/comite-de-sanciones",
"date": null
}],
"fitnessProbity": [],
"pep": [{
"sourceName": "United Kingdom Insolvency Service Disqualified Directors",
"sourceUrl": "https://www.insolvencydirect.bis.gov.uk/IESdatabase/viewdirectorsummary-new.asp",
"date": null
}],
"adverseMedia": [{
"sourceName": "SNA's Old Salt Award Passed to Adm. Davidson",
"sourceUrl": "https://www.marinelink.com/amp/news/snas-old-salt-award-passed-adm-davidson-443093",
"date": null
}]
}
}]
}
}
Failed response
{
"status": "fail",
"code": "1818",
"message": "Signature \"334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14\" does not match the HMAC-SHA256 of query ID and integration API secret."
}
DELETE /sessions/{sessionId}
Method to request deletion of a session, a session is eligible for deletion on created
, started
, abandoned
,
expired
, approved
, resubmission_requested
, declined
, inflow_completed
, review
statuses. Attempting to
delete the session in other statuses will respond with the Session is not in a completed status.
error message.
The availability of this feature is optional, depending on integration.
If session status is one of the following created
, started
or resubmission_requested
a decision webhook with
expired/abandoned
status will be sent. After successful request, session will immediately become unavailable
in Station and API. Data will be deleted within 12 hours.
Rate-limit is: 10 sessions per 24 hours and 5 sessions per 1 hour.
Request
Request method: DELETE
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X DELETE \
--url '/v1/sessions/fd5c1563-1d23-4b1a-ae46-7ba429927ed8' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0'
Node.js
var request = require('request');
var options = { method: 'DELETE',
url: '/v1/sessions/fd5c1563-1d23-4b1a-ae46-7ba429927ed8',
headers: {
'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': 'dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY'
},
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/sessions/{sessionId}'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': 'dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0',
'Content-Type': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Successful response
Response HTTP status code: 202 Accepted
Response body:
{
"status": "success",
"verification": {
"id": "fd5c1563-1d23-4b1a-ae46-7ba429927ed8"
}
}
Failed responses
Response HTTP status code: 400 Bad Request
Response body:
{
"status": "fail",
"code": "1305",
"message": "Session is not in a completed status."
}
Response HTTP status code: 400 Bad Request
Response body:
{
"status": "fail",
"code": "1306",
"message": "Session in progress."
}
Limited access response
Response HTTP status code: 429 Too Many Requests
Response body:
{
"status": 429,
"code": "1004",
"message": "Too many requests",
}
GET /attempts/{attemptId}/media
Returns a list of media objects with attemptId = {attemptId}
The list of objects are sorted based on their accuracy (e.g., does an image match the required image type) and their quality. The order is determined by the automation system.
Request
Request method: GET
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= attemptId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/attempts/f5c68aea-7f4d-478d-80ab-ca9356074f69/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/attempts/f5c68aea-7f4d-478d-80ab-ca9356074f69/media',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': 'acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/attempts/f5c68aea-7f4d-478d-80ab-ca9356074f69/media'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': 'acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestvideos
:array
Array of JSON objects identifying the videoscontext
:string
Context type of the video. See here for more info about the videocontext
.id
:UUID
-v4 Video Idname
:string
Video nameduration
:string
Video duration in secondsurl
:string
Video download urlsize
:string
Video size in bytestimestamp
:object
(Deprecated) Timestamp object, will return null/Nonemimetype
:string
Format of the media file. See Mimetypes table for more info
images
:array
Array of JSON objects identifying the imagescontext
:string
Context type of the image. See here for more info about the imagecontext
.id
:UUID-v4
Image Idname
:string
Image nameurl
:string
Image download urlsize
:string
Image size in bytestimestamp
:object
(Deprecated) Timestamp object, will return null/Nonemimetype
:string
Format of the media file. See Mimetypes table for more info
Sample response
{
"status": "success",
"videos": [
{
"context": "{VIDEO_TYPE}",
"id": "{MEDIA_ID}",
"name": "{VIDEO_NAME}",
"duration": "{DURATION_IN_SECONDS}",
"url": "{MEDIA_DOWNLOAD_URL}",
"timestamp": (Deprecated) null,
"size": "{SIZE_IN_B}",
"mimetype": "{MEDIA_MIME_TYPE}"
}
],
"images": [
{
"context": "{IMAGE_TYPE}",
"id": "{MEDIA_ID}",
"name": "{IMAGE_NAME}",
"url": "{MEDIA_DOWNLOAD_URL}",
"timestamp": (Deprecated) null,
"size": "{SIZE_IN_B}",
"mimetype": "{MEDIA_MIME_TYPE}"
}
]
}
GET /media/{mediaId}
Returns media file with mediaId = {mediaId}.
To get the mediaId
of a specific media file, request a list of media with GET attempts/{attemptId}/media
or sessions/{sessionId}/media.
Note about the size of images captured with the end-user flow
- All images with one edge larger that 1920px are proportionally reduced, so the longer edge is max 1920px
- There should be no size limits to the images when downloading
- There should be no resolution limits when downloading, except the fact that images >1920px were reduced
Request
Request method: GET
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= mediaId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/media/ebbf6434-3bf1-4020-8ac3-1ef51a25c673' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/media/ebbf6434-3bf1-4020-8ac3-1ef51a25c673',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
url = '/v1/media/ebbf6434-3bf1-4020-8ac3-1ef51a25c673'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
print(response.content)
Response
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Response body signed with the shared secret key
TRANSFER-ENCODING: string (required)
Form of encoding used to safely transfer the payload body
Sample response
Transfer-Encoding: chunked
Sample chunked data handling /media/{mediaId}
Sample how to store response data to file (image or video)
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= mediaId
signed with the shared secret key
mediaId: string (required)
mediaId
To get the mediaId
of a specific media file, request a list of media with GET attempts/{attemptId}/media
or sessions/{sessionId}/media
Node.js
Here is a simple example how to download media with Node.js, it is applicable for both video and image files. Just make sure to use correct file extension which can be found from /media api response
const fs = require('fs');
const request = require('request');
var options = { method: 'GET',
url: '/v1/media/ebbf6434-3bf1-4020-8ac3-1ef51a25c673',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
}).pipe(fs.createWriteStream(__dirname+'/myMedia.jpeg'));
Video files sample
media_url = '/v1/media/05cfc122-15d8-4838-bbf1-7b26a736b2d2'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'Content-Type': 'application/json',
}
response = requests.get(media_url, headers=headers)
with open('media_filename.webm', 'wb') as media_file:
for chunk in response.iter_content():
media_file.write(chunk)
Image files sample
media_url = '/v1/media/2b3b3a9f-d73d-445a-aabe-9b41c1c1a2ac'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'Content-Type': 'application/json',
}
response = requests.get(media_url, headers=headers)
with open('image_file_name.jpg', 'wb') as write_file:
write_file.write(response.content)
GET /address/{addressId}/media
Returns a list of media objects with addressId = {addressId} for Proof of Address sessions.
Request
Request method: GET
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= addressId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/address/f087f21f-5282-41b8-9857-6f85c28b8122/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/address/f087f21f-5282-41b8-9857-6f85c28b8122/media',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': 'acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url = '/v1/address/f087f21f-5282-41b8-9857-6f85c28b8122/media'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': 'acfe1cf21c986edf25cc6bc74fd769954443bbb606500019a4bed46645179b36',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the requestimages
:array
Array of JSON objects identifying the imagescontext
:string
Context type of the image (address-front
)id
:UUID-v4
Image Idname
:string
Image nameurl
:string
Image download urlsize
:string
Image size in bytesmimetype
:string
Format of the media file. See Mimetypes table for more info
Sample response
{
"status": "success",
"images": [
{
"context": "{IMAGE_TYPE}",
"id": "{MEDIA_ID}",
"name": "{IMAGE_NAME}",
"url": "{MEDIA_DOWNLOAD_URL}",
"timestamp": null,
"size": "{SIZE_IN_B}",
"mimetype": "{MEDIA_MIME_TYPE}"
}
]
}
GET /address-media/{mediaId}
Returns the media for Proof of Address with mediaId = {mediaId}
Request
Request method: GET
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= mediaId
signed with the shared secret key
Content-Type: application/json
Sample request
curl
curl -X GET \
--url '/v1/address-media/8d79522f-e3ad-4c1f-8e6a-4248db6935a2' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b' \
Node.js
var request = require('request');
var options = { method: 'GET',
url: '/v1/address-media/8d79522f-e3ad-4c1f-8e6a-4248db6935a2',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
url = '/v1/address-media/8d79522f-e3ad-4c1f-8e6a-4248db6935a2'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'Content-Type': 'application/json'
}
response = requests.request('GET', url, headers=headers)
print(response.content)
Response
Headers:
X-AUTH-CLIENT: string (required)
API key
X-HMAC-SIGNATURE: string (required)
Response body signed with the shared secret key
TRANSFER-ENCODING: string (required)
Form of encoding used to safely transfer the payload body.
Sample response
Transfer-Encoding: chunked
Sample chunked data handling /address-media/{mediaId}
Sample how to store response data to file (image or video)
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= mediaId
signed with the shared secret key
Node.js
Here is a simple example how to download address media with Node.js. Just make sure to use correct file extension, which can be found from /media api response.
const fs = require('fs');
const request = require('request');
var options = {
method: 'GET',
url: '/v1/address-media/8d79522f-e3ad-4c1f-8e6a-4248db6935a2',
headers: {
'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
}).pipe(fs.createWriteStream(__dirname + '/myMedia.jpeg'));
Image files sample
media_url = '/v1/address-media/8d79522f-e3ad-4c1f-8e6a-4248db6935a2'
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '452bfca0e02f8ee0f56d97373cc6971067e43149f1b7e58b681d4e57353a2f6b',
'Content-Type': 'application/json',
}
response = requests.get(media_url, headers=headers)
with open('image_file_name.jpg', 'wb') as write_file:
write_file.write(response.content)
POST /validate-registry
Validates a national ID number (e.g. social security number (SSN)) with the provided data. A verification session will be automatically created and submitted after which the validation result gets sent via Webhook. Note that media upload is not used for registry verification.
You will need a separate integration to do this verification (i.e., the integration you have for IDV will not suffice.)
In order to perform a social security number (SSN) validation the following fields must be provided:
idNumber
fullName
OR (firstName
+lastName
)dateOfBirth
ORaddress
data.- If
address
data is provided, then send EITHERfullAddress
value OR thestreet
+houseNumber
+postcode
values.
- If
Request
Request method: POST
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
verification
:object (required)
Verification objectcallback
:string
Default is defined on settings.callbackUrl
to where the end-user is redirected after the verification session is completedperson
:object (required)
Person whose national ID will be validatedidNumber
:string (required)
SSN unique idfullName
:string
Full name. Required iffirstName
+lastName
is not providedfirstName
:string
First name. Required iffullName
is not providedlastName
:string
Last name. Required iffullName
is not provideddateOfBirth
:string
(YYYY-MM-DD) Date of birth. Required, ifaddress
is not providedphoneNumber
:string
Phone number
address
:object
Address datafullAddress
:string
Full address. Required ifstreet
andhouseNumber
is not providedstreet
:string
Street. Required iffullAddress
is not providedhouseNumber
:string
House number. Required iffullAddress
is not providedpostcode
:string
Postal code. Required iffullAddress
is not providedcity
:string
Citystate
:string
Stateunit
:string
Unit
vendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provided
Sample request
curl
curl -X POST \
--url '/v1/validate-registry/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"callback": "https://veriff.com",
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789",
"dateOfBirth": "1980-03-06"
},
"address": {
"street": "Street 123",
"houseNumber": "456"
},
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f"
}
}'
Node.js
var request = require('request');
var options = { method: 'POST',
url: '/v1/validate-registry/',
headers:
{ 'Content-Type': 'application/json',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' },
body:
{ verification:
{ callback: 'https://veriff.com',
person:{
firstName: 'John',
lastName: 'Smith',
idNumber: '123456789',
dateOfBirth: "1980-03-06"
},
address: {
street: 'Street 123',
houseNumber: '456'
},
vendorData: '11111111'
endUserId: 'fa820aba-019f-455a-ae81-cfca8075bc3f' } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3
import requests
import pprint
import json
url = '/v1/validate-registry/'
payload = json.dumps({
'verification': {
'callback': 'https://veriff.com',
'person': {
'firstName': 'John',
'lastName': 'Smith',
'idNumber': '123456789',
'dateOfBirth': '1980-03-06'
},
'address': {
'street': 'Street 123',
'houseNumber': '456',
},
'vendorData': '11111111',
'endUserId': 'fa820aba-019f-455a-ae81-cfca8075bc3f',
'features': [
'selfid'
]
}
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, data=payload, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Request statusverification
:object
Verification objectid
:UUID
-v4 String UUID v4 which identifies the verification sessionvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedstatus
:string
Verification session statussessionToken
:string
Session specific token of the verification
Sample responses
Success, values in the form match
{
"status": "success",
"verification": {
"id":"f04bdb47-d3be-4b28-b028-a652feb060b5",
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"status": "submitted",
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoX3Rva2VuIjoiOThiYzdjMjEtZTQ0Yy00MTZiLTkxOTMtMTU5ZGZkMzBmMDg4Iiwic2Vzc2lvbl9pZCI6Ijc2ODhmMzYzLTAyZjctNDE1My1iMzM1LWE0ODQ3OTRkMzZmNyIsImlhdCI6MTUwMTIyODI1MSwiZXhwIjoxNTAxODMzMDUxfQ.bMEF37E6-zT2Aa6Q8UXK3B_ZL51w6D_lxnGgQvhj214"
}
}
Status 400 "Bad request", firstName
+ lastName
OR fullName
not provided
{
"status": "fail",
"code": "1309",
"message": "SSN validation requires person firstName + lastName OR fullName to be provided"
}
Status 400 "Bad request", idNumber
not provided
{
"status": "fail",
"code": "1308",
"message": "ID number is missing."
}
Status 400 "Bad request", dateOfBirth
OR address
not provided
{
"status": "fail",
"code": "1310",
"message": "SSN validation requires person.dateOfBirth or address data to be provided."
}
POST sync-api.veriff.me/v1/validate-registry
Validates a national ID number (e.g. social security number (SSN)) with the provided data. A verification session will be automatically created and submitted after which the validation result gets sent in the API Response. Note that media upload is not used for registry verification.
You will need a separate integration to do this verification (i.e., the integration you have for IDV will not suffice.)
In order to perform a social security number (SSN) validation the following fields must be provided:
idNumber
fullName
ORfirstName
+lastName
dateOfBirth
and/oraddress
data- If
address
data is provided, then send EITHER thefullAddress
value ORstreet
+houseNumber
+postcode
values - Providing both
address
anddateOfBirth
will improve the conversion rate
- If
Request
Request method: POST
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-API-KEY: string (required)
= API key
X-HMAC-SIGNATURE: string
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
verification
:object (required)
Verification objectcallback
:string
Default is defined on settings.callbackUrl
to where the end-user is redirected after the verification session is completedperson
:object (required)
Person whose national ID will be validatedidNumber
:string (required)
National ID to validatefirstName
:string
First namelastName
:string
Last namefullName
:string
Full namephoneNumber
:string
Phone numberdateOfBirth
:string
(YYYY-MM-DD) Date of birth
address
:object
Address datafullAddress
:string
Full addressstreet
:string
StreethouseNumber
:string
House numberpostcode
:string
Postal codecity
:string
Citystate
:string
Stateunit
:string
Unit
vendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provided
Sample request
curl
curl -X POST \
--url '/v1/validate-registry' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-API-KEY: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 4776e5fb59795da4856c8176efcdeaf6fe15d0bed6a179e75c86a5f5580a250c' \
-d '{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789",
"dateOfBirth": "1980-03-06"
},
"address": {
"street": "Street 123",
"houseNumber": "456",
"postcode": "12345"
},
"vendorData": "11111111",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f"
}
}'
Node.js
var request = require('request');
var options = {
method: 'POST',
url: '/v1/validate-registry/',
headers: {
'Content-Type': 'application/json',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-API-KEY': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '4776e5fb59795da4856c8176efcdeaf6fe15d0bed6a179e75c86a5f5580a250c',
},
body: {
verification: {
person: {
firstName: 'John',
lastName: 'Smith',
idNumber: '123456789',
dateOfBirth: '1980-03-06',
},
address: {
street: 'Street 123',
houseNumber: '456',
postcode: '12345',
},
vendorData: '11111111',
endUserId: 'fa820aba-019f-455a-ae81-cfca8075bc3f'
},
},
json: true,
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3
import requests
import pprint
import json
url = '/v1/validate-registry/'
payload = json.dumps({
'verification': {,
'person': {
'firstName': 'John',
'lastName': 'Smith',
'idNumber': '123456789',
'dateOfBirth': '1980-03-06'
},
'address': {
'street': 'Street 123',
'houseNumber': '456',
'postcode': '12345',
},
'vendorData': '11111111',
'endUserId': 'fa820aba-019f-455a-ae81-cfca8075bc3f',
'features': [
'selfid'
]
}
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-API-KEY': 'API-PUBLIC-KEY',
'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '4776e5fb59795da4856c8176efcdeaf6fe15d0bed6a179e75c86a5f5580a250c'
}
response = requests.request('POST', url, data=payload, headers=headers)
pprint.pprint(response.json())
Failed request validation scenarios
Two types of validation is done: X-HMAC-SIGNATURE
and request payload validation.
Below are possible failure scenarios.
X-HMAC-SIGNATURE
validation failed
HTTP status code: 401
Message: "MissingAuthentication"
{
status: 'fail',
code: 1812,
message: 'Signature {invalid-hmac-signature value} is not a valid SHA256 hash.'
}
Required field fullName
or (firstName
+ lastName
) not provided
HTTP status code: 400
Message: "InvalidRequest"
{
status: 'fail',
code: 1102,
message: 'Request person is missing required field fullName or (firstName + lastName)'
}
Required field dateOfBirth
or address
not provided
HTTP status code: 400
Message: "InvalidRequest"
{
status: 'fail',
code: 1102,
message: 'Request is missing required field dateOfBirth or address'
}
Required field fullAddress
or (street
+ houseNumber
+ postcode
) not provided
HTTP status code: 400
Message: "InvalidRequest"
{
status: 'fail',
code: 1102,
message: 'Request address is missing required field fullAddress or (street + houseNumber + postcode)'
}
Required field idNumber
not provided
HTTP status code: 400
Message: "InvalidRequest"
{
status: 'fail',
code: 1102,
message: 'Request is missing required field idNumber'
}
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Response body signed with the shared secret key
Content-Type: application/json
Response properties explained
status
:string
Status of the responseverification
:object
Verification request decision object. Null if decision is not available yetid
:string
UUID v4 which identifies the verification sessioncode
:integer
(one of 9001, 9102, 9103, 9104, 9121) Verification response code. More information about decision codesperson
:object
Verified persongender
:null
(M, F or Null) Gender. Will always benull
idNumber
:string | null
National identification numberlastName
:string | null
Last namefirstName
:string | null
First namecitizenship
:(Deprecated)
null
dateOfBirth
:string
(YYYY-MM-DD) Date of birthnationality
:null
Nationality. Will always benull
yearOfBirth
:null
(YYYY) Year of birth. Will always benull
placeOfBirth
:null
Place of birth. Will always benull
pepSanctionsMatch
:null
PEP check result. Will always benull
reason
:string | null
Reason of failed Verificationstatus
:string
(one of approved, declined) Verification statuscomments
:array
(Deprecated)document
:object
Verified documenttype
:null
Document type. Will always benull
number
:null
Document number. Will always benull
country
:null
ISO-2 Document country. Will always benull
validFrom
:null
Document is valid from date. Will always benull
validUntil
:null
Document is valid until date. Will always benull
reasonCode
:integer | null
Reason code of failed Verification See Response and error codesvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provideddecisionTime
:string
Timestamp of the decision. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsetacceptanceTime
:string
Timestamp of the session generation. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsetadditionalVerifiedData
:object
Data which has been optionally verified for session.failedValidation
:string
Message for the failed validation
technicalData
:object
Technical data objectip
:string | null
IP of the device from which the verification was made
Sample Response
Approved decision
{
"status": "success",
"verification": {
"id": "09551b48-4d7c-4a30-8437-5301223953fa",
"code": 9001,
"person": {
"gender": null,
"idNumber": "123456789",
"lastName": "Smith",
"firstName": "John",
"citizenship": null,
"dateOfBirth": "1980-03-06",
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": null,
"number": null,
"country": null,
"validFrom": null,
"validUntil": null
},
"reasonCode": null,
"vendorData": null,
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"decisionTime": "2019-11-06T07:18:36.916Z",
"acceptanceTime": "2019-11-06T07:15:27.000Z",
"additionalVerifiedData": {}
},
"technicalData": {
"ip": null
}
}
Declined decision
{
"status": "success",
"verification": {
"id": "5ca9d2b6-3708-4540-928e-4b8e82717c3f",
"code": 9102,
"person": {
"gender": null,
"idNumber": "123456789",
"lastName": "Smith",
"firstName": "John",
"citizenship": null,
"dateOfBirth": "1980-03-06",
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": "Unable to validate National Id data",
"status": "declined",
"comments": [],
"document": {
"type": null,
"number": null,
"country": null,
"validFrom": null,
"validUntil": null
},
"reasonCode": 529,
"vendorData": null,
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"decisionTime": "2019-11-06T07:18:36.916Z",
"acceptanceTime": "2019-11-06T07:15:27.000Z",
"additionalVerifiedData": {
"failedValidation": "Neither address or date of birth matched"
}
},
"technicalData": {
"ip": null
}
}
POST /sessions/{sessionId}/consents
Uploads a consent (and specifies the type of the consent that is being uploaded) for a specific sessionId
.
- Multiple consents can be uploaded per
sessionId
but only the latest will be consider binding
Request
Request method: POST
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Request properties explained
type
:string
(required) Consent type (one ofine
,bipa
,aadhaar
)approved
:boolean
(required) Is the consent approved by the end user or nottext
:string
(required) Consent text exactly (same language) as shown to the end user
Sample request
curl
curl -X POST \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/consents' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53' \
-d '{
"type": "ine",
"approved": true,
"text": "User agrees to share their INE details",
}'
Node.js
var request = require('request');
var options = { method: 'POST',
url: '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/consents',
headers:
{ 'Content-Type': 'application/json',
'X-HMAC-SIGNATURE': '034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53',
'X-AUTH-CLIENT': 'API-PUBLIC-KEY' },
body:
{ image:
{ type: 'ine',
approved: true,
text: 'User agrees to share their INE details' } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Python3.py
import requests
import json
import pprint
url='/v1/sessions/{sessionId}/consents'
payload = json.dumps({
'type': 'ine',
'approved': True,
'text': 'User agrees to share their INE details'
})
headers = {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, data=payload, headers=headers)
pprint.pprint(response.json())
Response
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= Request body signed with the shared secret key
Content-Type: application/json
Response properties explained
id
:UUID-v4
String UUID v4 which identifies the consentcontext
:string
always 'consent'sessionId
:UUID-v4
String UUID v4 which identifies the session
Sample response
{ "status": "success",
"image":{
"context": "consent",
"id": "12551f8d-d3d6-4e9b-91b2-3978a2e7a553",
"sessionId": "39388f8d-c6d6-4e9b-92c6-6978b2e8d664"
}
}
GET /sessions/{sessionId}/decision/ine-registry
INE (Institutio Nacional Electoral - Mexican Electoral Registry) is the organization that issues the voter ID cards and maintains the voters registry.
Returns data about the INE identification number.
Request
Request properties explained
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json (required)
Query parameters:
version: string (required)
= the version number of the check
Sample request
Note: the examples below are for illustrative purposes only, and are using mock data for API URL and X-HMAC-SIGNATURE, and a placeholder for API-PUBLIC-KEY. You need to replace these with the actual values that you use.
curl
curl -X GET 'v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/ine-registry?version=1.0.0' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
-H 'Content-Type: application/json' \
Node.js
var request = require('request');
var url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/ine-registry?version=1.0.0';
var options = {
method: 'GET',
url: url,
headers: {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
};
request(options, function (error, response, body) {
if (error) {
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
Python3.py
import requests
import json
import pprint
url = "/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/ine-registry"
headers = {
"X-AUTH-CLIENT": "API-PUBLIC-KEY",
"X-HMAC-SIGNATURE": "334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14",
"Content-Type": "application/json"
}
params = {
"version": "1.0.0"
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = json.loads(response.text)
pprint.pprint(data)
else:
print(f"Error: {response.status_code}")
Response
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= payload signed with the shared secret key
Content-Type: application/json
Response properties explained
active
:boolean
Indication of if the INE identification number is active (true
) or inactive (false
).documentState
:string
Human readable description of the status of the query
Note: in the respective jurisdiction, an active = true
credential can be used for identification and related
activities; an active = false
credential could still be in the database, but it cannot be used for identification
and related activities.
Sample Response
{
"active": false,
"documentState": "No se obtuvieron datos de la consulta con los parámetros seleccionados"
}
GET /sessions/{sessionId}/decision/curp-registry
The CURP (Unique Key of Population Registry) is the name of the population number/certificate in Mexico.
Returns the check result with CURP identification number and status.
Request
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json (required)
Query parameters:
version: string (required)
= the version number of the check
Sample request
Note: the examples below are for illustrative purposes only, and are using mock data for API URL and X-HMAC-SIGNATURE, and a placeholder for API-PUBLIC-KEY. You need to replace these with the actual values that you use.
curl
curl -X GET 'v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/curp-registry?version=1.0.0' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
-H 'Content-Type: application/json' \
Node.js
var request = require('request');
var url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/curp-registry?version=1.0.0';
var options = {
method: 'GET',
url: url,
headers: {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
};
request(options, function (error, response, body) {
if (error) {
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
Python3.py
import requests
import json
import pprint
url = "/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/curp-registry"
headers = {
"X-AUTH-CLIENT": "API-PUBLIC-KEY",
"X-HMAC-SIGNATURE": "334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14",
"Content-Type": "application/json"
}
params = {
"version": "1.0.0"
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = json.loads(response.text)
pprint.pprint(data)
else:
print(f"Error: {response.status_code}")
Response
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= payload signed with the shared secret key
Content-Type: application/json
Response properties explained
statusCurp
:string | null
(One of: AN, AH, CRA CU, RCN, RCC, BD, BDA, BCC, BCN) Status of the CURP data (see below for the full forms of the acronyms)curp
:string
18-character alphanumeric code of the person (the CURP identification number)
Full forms of the statusCurp
acronyms
Active CURP: AN (Alta Normal), AH (Alta con Homonimia), CRA CU (CURP Reactivada), RCN (Registro de Cambio no Afectando a CURP), RCC (Registro de Cambio Afectando a CURP)
For inactive CURP: BD (Baja por Defuncion), BDA (Baja por Duplicidad), BCC (Baja por Cambio en CURP), BCN (Baja no Afectando a CURP)
Sample Response
{
"statusCurp": "RCN",
"curp": "FOHJ920625HGTLRR06"
}
GET /sessions/{sessionId}/decision/combined-ine-curp-registry
Returns combined result of INE/IFE and CURP.
INE (Institutio Nacional Electoral - Mexican Electoral Registry) is the organization that issues the voter ID cards and maintains the voters registry.
The CURP (Unique Key of Population Registry) is the name of the population number/certificate in Mexico.
ifeIdentifeir
and ineIdentifier
both represent person's identification number. ife
is a legacy name, it was changed
to ine
.
Request
Request properties explained
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json (required)
Query parameters:
version: string (required)
= the version number of the check
Sample request
Note: the examples below are for illustrative purposes only, and are using mock data for API URL and X-HMAC-SIGNATURE, and a placeholder for API-PUBLIC-KEY. You need to replace these with the actual values that you use.
curl
curl -X GET 'v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/combined-ine-curp-registry?version=1.0.0' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14' \
-H 'Content-Type: application/json' \
Node.js
var request = require('request');
var url = '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/combined-ine-curp-registry?version=1.0.0';
var options = {
method: 'GET',
url: url,
headers: {
'X-AUTH-CLIENT': 'API-PUBLIC-KEY',
'X-HMAC-SIGNATURE': '334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14',
'Content-Type': 'application/json'
}
};
request(options, function (error, response, body) {
if (error) {
console.error('Error:', error);
} else {
console.log('Response:', body);
}
});
Python3.py
import requests
import json
import pprint
url = "/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/decision/combined-ine-curp-registry"
headers = {
"X-AUTH-CLIENT": "API-PUBLIC-KEY",
"X-HMAC-SIGNATURE": "334141f052e317fde6668de54dc6640b4a5c47582ad86a8bed63afe566f17b14",
"Content-Type": "application/json"
}
params = {
"version": "1.0.0"
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = json.loads(response.text)
pprint.pprint(data)
else:
print(f"Error: {response.status_code}")
Response
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= payload signed with the shared secret key
Content-Type: application/json
Response properties explained
data
:object
Data related to the INE/IFE identification number and the CURP identification numberine
:object
Details about the INE/IFE identification numberactive
:boolean
Indication of if the INE identification number is active (true
) or inactive (false
)status
:string
Explanation of thedata.status
valueinformation
:string
Extra information about the INE identification numbercomments
:array
Comments regarding the status of the identificationifeIdentifier
:string | null
INE identification number. When this is returned, theineIdentifier
is not presentineIdentifier
:string | null
IFE identification number. When this is returned, theifeIdentifier
is not present
curp
:object
Details about the CURP identification numbercurp
:string
CURP identification numberstatusCurp
:string | null
Status of the CURP data (One of: AN, AH, CRA CU, RCN, RCC, BD, BDA, BCC, BCN)descriptionStatusCurp
:string
Explanation of thedetails.curp.statusCurp
valuenames
:string
NamefirstSurname
:string
First surnamesecondSurname
:string
Last surnamegender
:string
Gender (One ofHOMBRE
,MUJER
)dateOfBirth
:string
Date of birth regiondd/mm/yyyy
,nationality
:string
NationalitybirthRegion
:string
Birth regionregionCode
:string
Region codedocumentEvidence
:number
Document evidencedocEvidenceData
:object
1 Details about the document evidence dataregistrationYear
:string
Registration yearactNumber
:string
Act numberregionRegistry
:string
Region registryregistryRegionCode
:string
Registry region coderegistryCity
:string
Registry cityregistryCityCode
:string
Registry city codevolume
:string
Volumesheet
:string
Sheetbook
:string
Book
Full forms of the statusCurp
acronyms
Active CURP: AN (Alta Normal), AH (Alta con Homonimia), CRA CU (CURP Reactivada), RCN (Registro de Cambio no Afectando a CURP), RCC (Registro de Cambio Afectando a CURP)
For inactive CURP: BD (Baja por Defuncion), BDA (Baja por Duplicidad), BCC (Baja por Cambio en CURP), BCN (Baja no Afectando a CURP)
Sample Response
{
"eventType": "combined-ine-curp-registry",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"attemptId": "e30122d1-740b-4764-853f-470374a7abf4",
"vendorData": "1234567812345678",
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"version": "1.0.0",
"data": {
"status": "found",
"code": 200,
"details": {
"ine": {
"active": true,
"status": "La credencial esta vigente",
"comments": [
"CIC 000000000\r\nClave de elector JRLGLS00000000H000\r\nNúmero de emisión 1\r\nDistrito Federal 3\r\nDistrito Local 4\r\nNúmero OCR 0000000000000\r\nAño de registro 2009\r\nAño de emisión 2020",
"Fecha de actualización de la información: 10 de agosto del 2023 19:48",
"Fecha de consulta: 11 de agosto del 2023",
"Tus datos se encuentran en el Padrón Electoral, y también en la Lista Nominal de Electores"
],
"information": "CIC 000000000\r\nClave de elector JRLGLS00000000H000\r\nNúmero de emisión 1\r\nDistrito Federal 3\r\nDistrito Local 4\r\nNúmero OCR 0000000000000\r\nAño de registro 2009\r\nAño de emisión 2020\r\nFecha de actualización de la información: 10 de agosto del 2023 19:48\r\nFecha de consulta: 11 de agosto del 2023\r\nEsta vigente como medio de identificación y puedes votar.\r\nTus datos se encuentran en el Padrón Electoral, y también en la Lista Nominal de Electores.\r\nSerá válida hasta el 31 de diciembre de 2030",
"ifeIdentifier": "",
"ineIdentifier": "000000000"
},
"curp": {
"curp": "ABCD000000HVZRGS00",
"statusCurp": "RCN",
"descriptionStatusCurp": "Registro de cambio no afectando a curp",
"names": "LOREM IPSUM",
"firstSurname": "JUAREZ",
"secondSurname": "LAGUNES",
"gender": "HOMBRE",
"dateOfBirth": "06/04/1991",
"nationality": "MEX",
"birthRegion": "Veracruz",
"regionCode": "VZ",
"documentEvidence": 1,
"docEvidenceData": {
"registrationYear": "1991",
"actNumber": "00123",
"regionRegistry": "30",
"registryRegionCode": "VZ"
"registryCity": "",
"registryCityCode": "125",
"volume": "",
"sheet": "",
"book": ""
},
}
}
}
}
Test the requests in Postman
It is possible to test the Veriff API v1.0 Collection in Postman. Click on the button below to get started.
API requests signing with X-HMAC-SIGNATURE
X-HMAC-SIGNATURES are a security measure, which we generate for the API requests and webhook listeners, to make sure that the exchanged data has not been tampered with.
If you are familiar with the signing concept, jump to the Generate X-HMAC-SIGNATURE section. Here you find:
- A list of the prerequisites you need to generate an X-HMAC-SIGNATURE
- Examples of some technical options which you can use to generate the signature
- Explanation about how you can locally validate the generated signature
If you want a conceptual overview of the feature, we recommend taking a look at this What is an X-HMAC-SIGNATURE? section.
Generate an X-HMAC-SIGNATURE
Prerequisites for live requests signing
If you want to generate the X-HMAC-SIGNATURE for an actual API request, have the following info at hand and use these in your preferred signature generation tool:
- API key (you can find it in Station, on relevant integration’s page). You will use it as X-AUTH-CLIENT header
- Shared secret key (you can find it in Station, on relevant integration’s page). You will use it to sign the payload
Content-Type
header (in Veriff’s API requests case,application/json
)- API request’s payload (defined in each Endpoint’s
Headers
explanation)
If you are unsure which method you want to use, the Options to generate a X-HMAC-SIGNATURE section lists some options. You can use the mock data here to test them in your local machine.
Mock data for local testing
If you want to test the signature generation options locally, you can use the following mock shared secret key and mock payload.
Mock shared secret key:
abcdef12-abcd-abcd-abcd-abcdef012345
POST /sessions request mock payload (as .json):
{"verification":{"callback":"https://veriff.com","person":{"firstName":"John","lastName":"Smith"},"document":{"type":"PASSPORT","country":"EE"},"vendorData":"unique id of the end-user","timestamp":"2016-05-19T08:30:25.597Z"}}
If your preferred method is correct, you should get the following mock X-HMAC-SIGNATURE:
0dcab73ddd20062616d104231c7439657546a5c24e4691977da93bb854c31e25
Note: to generate an actual signature for your live API requests, the Headers
explanation
in each API request’s section tells you what to use as payload for encryption.
Options to generate a X-HMAC-SIGNATURE
There are several ways to do that:
- For ease of use, go for a dedicated HMAC signature generator which supports the generation of HMAC-SHA256 signatures, like OpenSLL, OAuth.io [↗] or Postman
- If you want control and flexibility, you can create a script (see some mock scripts here) or use a command-line tool (a mock openssl script)
- If you are familiar with a programming language, you can use built-in cryptographic libraries (see a mock Python example here)
- If you need the signature quickly and security is not a priority, you can use an online tool (see an example below)
Scripts
Command-line tools
Built-in crypto libraries
Online tools
Validate X-HMAC-SIGNATURE locally
Below are few examples how to validate the generated X-HMAC-SIGNATURE.
What is an X-HMAC-SIGNATURE?
This section aims to explain the nature and use of X-HMAC-SIGNATURES and webhook listeners, and describe the reasons why it is important to implement them.
Sessions lifecycle diagram (API)
Webhooks
To handle the response from Veriff services, you need to implement an endpoint that accepts payloads posted by our services.
Webhook delivery, receipt and resending
Delivery order: to follow the best practices, we do not guarantee that the webhooks are delivered in the order in which they are generated. Therefore, you should not expect to receive them in that order either, and should implement a logic to handle this accordingly.
Delivery approach: we guarantee the delivery of webhook at-least-once. The receiving API should be idempotent.
After sending the webhook, our systems expect a confirmation about receiving the webhook from your side. This confirmation from your server should come within 5,000 ms, and we expect it to be in the form of a successful HTTP response code (a 200 code).
If the confirmation does not arrive within that timeframe, for example there is a network connectivity issue or technical issue with delivering the notification (any non-200 response code), we will try to resend the failed webhook for up to a week.
Configuring the webhook endpoint
- Go to the Veriff environment
- Click on the Integrations on the top menu
- Find and open the relevant integration
- Navigate to the Settings tab on the integration's page
- Fill in the webhook URL input field with the URL where your endpoint is accepting payloads from Veriff
There are several types of webhooks. Veriff will post payloads to respective webhook URLs.
Note that the image below does not contain all the possible webhook URLs. The list available depends on your integration.
Recognizing your end-user
When your server receives a payload from Veriff, you need to be able to reference an end-user. You can do this by using the Veriff session ID or by using your own end-user ID.
Using the Veriff session ID
The easiest way is to track the session ID provided by Veriff during session creation. Some webhooks payloads refer to either session ID or attempt ID or both. Please see the specific webhook payload for exact info.
Using your own end-user ID
To use your own end-user ID you need to provide your internal end-user ID to Veriff, or some other key that uniquely
identifies your end-user. You can store your identifier in the vendorData
or endUserID
property during
the session creation.
Note: it is technically possible for one end-user to be associated with multiple verification sessions, and this could potentially create ambiguous situations in code if you are only recognizing end-users by your own identifier, and not Veriff's session ID.
Handling security
It is important to check that the webhook responses do indeed originate from Veriff. For that we use the X-HMAC-SIGNATURE header, which value is an HMAC-SHA256 hex encoded keyed hash using your API private key.
Different webhook types
There are several webhook types to help you to tailor your service specifically to your needs.
Webhook decisions URL
is where we post decisions about verifications (approved, declined, resubmission_required, expired, abandoned, review), see the sample payloadWebhook events URL
is where we post events during the lifecycle of a verification (started, submitted), see the sample payloadWebhook Full Auto URL
is where we post data related to the Full Auto verification. For more detailed info, see explaination of the webhook properties [↗] and sample webhook [↗] (both links require a login to the Veriff environment)Webhook watchlist screening URL
is where we post events related to both the initial and monitored results of the PEP, sanctions, and adverse media checks, see the example payloadWebhook INE registry URL
is where we post data related to the INE registry check after the check is completedWebhook CURP registry URL
is where we post data related to the CURP registry check after the check is completedWebhook combined INE CURP registry URL
is where we post data related to the combined INE and CURP registries check after the check is completedWebhook URL for sessions statuses set in Station
is where we post data when a user has added a status to an attempt in the Veriff environment
Decision webhook
This is the description of the payload sent to Webhook decisions URL
.
The result of the verification is sent back to the customer once the verification has been processed.
In most cases we send a decision webhook instantly after a decision is made, with an exception to "resubmission_requested" status.
In case resubmission is required, we allow the end-user to resubmit session data instantly without a need to exit the flow.
If the end-user does not do it within 5 minutes, we will send out a webhook with the resubmission_requested
decision.
Driver's license categories extraction: to extract the validFrom
and validUntil
dates from a driver's license,
please communicate with your solutions engineer to activate the feature.
Request properties explained:
status
:string
Status of the responseverification
:object
Verification request decision object. Null if decision is not available yetid
:string
UUID v4 which identifies the verification sessionvendorData
:string | null
End-user-specific string created by the customer to identify the end-user. We require only non-semantic data to be submitted (UUID-s etc., that can not be resolved or used outside your environment)endUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specifiedstatus
:string
(one of approved, resubmission_requested, review, declined, expired, abandoned) Verification statuscode
:integer
(one of 9001, 9102, 9103, 9104, 9121) Verification session decision code. More information about verification session decision code.reason
:string | null
Reason of failed VerificationreasonCode
:integer | null
Reason code of failed Verification See Response and error codesdecisionTime
:string
Timestamp of the decision. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone OffsetacceptanceTime
:string
Timestamp of the session generation. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offsetperson
:object
Verified personfirstName
:string | null
Person's first name as written on the document, if presentlastName
:string | null
Person's last name as written on the document, if presentdateOfBirth
:string
(YYYY-MM-DD) Date of birthgender
:string | null
(M, F or Null) Gendernationality
:string | null
NationalityidNumber
:string | null
National identification numberyearOfBirth
:string | null
(YYYY) Year of birthplaceOfBirth
:string | null
Place of birthcitizenship
:(Deprecated)
null
addresses
:array
Optional, depending on integration.fullAddress
:string | null
Address as single string.parsedAddress
:object
Object with parsedfullAddress
. Optional, depending on integration.country
:string | null
state
:string | null
city
:string | null
postcode
:string | null
street
:string | null
houseNumber
:string | null
unit
:string | null
Apartment number
fullName
:string | null
Full name of the person. Optional, depending on the integration (only for Indian Aadhaar cards registry based verification)occupation
:string
Occupation data from the document. Optional, depending on integration.employer
:string
Employer's name from the document. Optional, depending on integration.foreginerStatus
:string
Foreigner status field from the document. Optional, depending on integration.extraNames
:string
Additional name from the document. Optional, depending on integration.ifeIdentifier
:string | null
The voter's card identifier (OCR). Optional, depending on integration.ineIdentifier
:string | null
The citizen's identifier (Identificador del Ciudadano). Optional, depending on integrationpepSanctionMatch
:string | null
PEP check result. Optional, depending on integration.
document
:object
Verified documentnumber
:string | null
Document number, [a-zA-Z0-9] characters onlyvalidUntil
:string | null
Document is valid until datevalidFrom
:string | null
Document is valid from datetype
:string | null
(one of PASSPORT, ID_CARD, RESIDENCE_PERMIT, DRIVERS_LICENSE, VISA, OTHER) Document type. See the IDV document types herecountry
:string | null
Document issuing country, as ISO 3166 alpha-2 coderemarks
:string
Data extracted from the document's remarks fieldstate
:string | null
Document issuing state, as ISO 3166 alpha-2 or alpha-3 code.null
when the state data is not present on the documentplaceOfIssue
:string | null
Place where document was issued. Optional, depending on integration.firstIssue
:string | null
Date of document first issue in YYYY-MM-DD format. Optional, depending on integration.issueNumber
:string | null
Document issue number. Optional, depending on integration.issuedBy
:string | null
Document issuing authority. Optional, depending on integration.nfcValidated
:boolean
Biometric document data has been successfully decoded. Optional, depending on integration.residencePermitType
:string
Type of the residence permit from the document. Optional, depending on the integration.portraitIsVisible
:boolean
Indicates that the portrait image is visible in the session and its quality is sufficient to perform verification. Optional, depending on the integration.signatureIsVisible
:boolean
Indicates that the signature is present on the document and readable to perform the verification. Optional, depending on the integration.
additionalVerifiedData
:object
Data which has been optionally verified for session.driversLicenseNumber
:string
Number of the driver's license. Optional, depending on integration.driversLicenseCategory
:object
Optional, depending on integration.B
:Boolean | null
driversLicenseCategoryFrom
:object
Date when the driving license category was obtained. Optional, depending on integration.B
:string | null
Category is valid from date in YYYY-MM-DD format
driversLicenseCategoryUntil
:object
Driving license category expiry date. Optional, depending on integration.B
:string | null
Category is valid until date in YYYY-MM-DD format
estimatedAge
:number
Estimated age. Optional, depending on integration.estimatedGender
:number
Estimated gender. Optional, depending on integration. Values closer to 0.0 indicate 'male', values closer to 1.0 indicate 'female'UKTFCheckResult
:array
Array of UK DIATF checks results. Optional, depending on the integrationCIFAS
:string
CIFAS registry check resultElectoral roll and Credit History UK
:string
UK Electoral roll and credit history check resultPEP
:string
PEP check result
cpfValidation
:object | null
Brazilian individual taxpayer registry (CPF) validation check object. Optional, depending on integrationstatus
:string | null
Status of the entry in the registry (one of CPF is validated, CPF is suspended, CPF holder is deceased, CPF is pending regularization, CPF is cancelled (was a duplicate), Cancelled craft (meaning that it was cancelled due to reasons other than being a duplicate))cpfNumber
:string | null
Brazilian individual taxpayer registry (CPF) number of the personname
:string | null
Person's name in the CPFdateOfBirth
:string | null
Person's date of birth in the CPF as YYYY-MM-DDyearOfDeath
:string | null
Person's year of death in the CPF as YYYY
processNumber
:string
Process number (e.g., "Trámite №") from the document. Optional, depending on integration.ineBiometricRegistryValidation
:object
INE Biometric Database Verification check object. Optional, available only when the INE Biometric Validation check has been enabled for the integrationfaceMatch
:boolean | null
Indicates if the person's selfie image is a match with their image in the registry. This decision is made based on the value returned infaceMatchPercentage
(see below).null
if the check could not be completedfaceMatchPercentage
:integer | null
Indicates the level of similarity the system thinks the matched images have, in the range of 0-100. Values ≥85 indicate a match; values <85 indicate that images do not match.null
if the check could not be completedresponseStatus
:string | null
Indicates the response received from the service provider. One ofsuccess
orfailure
; ornull
if the check could not be completed
proofOfAddress
:object
Proof of address data. Optional, depending on integration.nameMatch
:boolean
Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float
Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.
biometricAuthentication
:object
Object containing data about the biometric authentication. Optional, available only when using the Biometric Authentication solutionmatchedSessionId
:string | null
Refers to the verification session ID which the face matchedmatchedSessionEndUserId
:string | null
Refers to the verification sessionendUserId
which the face matchedmatchedSessionVendorData
:string | null
Refers to the verification sessionvendorData
which the face matcheddetails
:object
Lists the results of different checks that were made to verify the end-user. Log in to the Veriff environment to see the detailed request explanation and a sample request[↗]. Veriff environment to see the detailed request explanation and a sample request[↗].
-
riskScore
:object
Data about the risk scorescore
:number
A float in the range of 0.0–1.0. Numerical value representing the overall risk associated with the session. Lower score indicates more confidence in that the session is genuine. Note: in the Veriff environment, the range is shown as 1–100.
riskLabels
:array
Optional array of risk labels related to the session. The presence of this property depends on risk labels being enabled for the integration. Full list of risk labels (requires login to Veriff environment) [↗]label
:string
Name of the risk labelcategory
:string
(one of client_data_mismatch, crosslinks, device, document, images, network, session, person)sessionIds
:array
Array of verification IDs that are referenced to the particular risk label.
comments
:array
(Deprecated)highRisk
:boolean
(Deprecated) If session is considered high risk or not. Optional, depending on integration.
technicalData
:object
Technical data objectip
:string | null
IP of the device from which the verification was made
Sample request
{
"status": "success",
"verification": {
"id": "12df6045-3846-3e45-946a-14fa6136d78b",
"vendorData": "12345678",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"status": "approved",
"code": 9001,
"reason": null,
"reasonCode": null,
"decisionTime": "2019-11-06T07:18:36.916Z",
"acceptanceTime": "2019-11-06T07:15:27.000Z",
"person": {
"firstName": "SARAH",
"lastName": "MORGAN",
"dateOfBirth": "1967-03-30",
"gender": null,
"nationality": null,
"idNumber": null,
"yearOfBirth": "1967",
"placeOfBirth": "MADRID",
"citizenship": null,
"addresses": [
{
"fullAddress": "1234 Snowy Ridge Road, Indiana, 56789 USA",
"parsedAddress": {
"city": null,
"unit": null,
"state": "Indiana",
"street": "1234 Snowy Ridge Road",
"country": "USA",
"postcode": "56789",
"houseNumber": "null"
}
}
],
"fullName": "SARAH MORGAN",
"occupation": "Engineer",
"employer": "Any Company LLC",
"foreignerStatus": "EXTRANJERO",
"extraNames": "NOM D'USAGE",
"pepSanctionMatch": null
},
"document": {
"number": "MORGA753116SM9IJ",
"validFrom": null,
"validUntil": "2022-04-20",
"type": "DRIVERS_LICENSE",
"country": "US",
"remarks": "WORK PERMITTED",
"state": "NY",
"placeOfIssue": "NEW YORK",
"firstIssue": "2015-03-21",
"issueNumber": "01",
"issuedBy": "ISSUER",
"nfcValidated": true,
"residencePermitType": "C",
"portraitIsVisible": "true",
"signatureIsVisible": "true"
}
},
"additionalVerifiedData": {
"driversLicenseNumber": "1234569",
"driversLicenseCategory": {
"B": true
},
"driversLicenseCategoryFrom": {
"B": "2019-10-06"
},
"driversLicenseCategoryUntil": {
"B": "2025-10-05"
},
"estimatedAge": 32,
"estimatedGender": 0.613,
"processNumber": "12345678912 1234",
"cpfValidation": {
"status": "CPF is validated",
"cpfNumber": "123456789",
"name": "SARAH MORGAN",
"dateOfBirth": "1967-03-30",
"yearOfDeath": null
},
"ineBiometricRegistryValidation": {
"faceMatch": true,
"faceMatchPercentage": 89,
"responseStatus": "success"
},
"proofOfAddress": {
"nameMatch": true,
"nameMatchPercentage": 100.00
},
},
"riskScore": {
"score": 0.12
},
"riskLabels": [
{
"label": "document_integration_level_crosslinked_with_fraud",
"category": "document",
"sessionIds": ["5a2358e7-fd31-4fcb-a23f-4d76651ba68a"]
},
{
"label": "document_integration_level_crosslinked_with_multiple_declines",
"category": "document",
"sessionIds": ["fd5c1563-1d23-4b1a-ae46-7ba429927ed8"]
}],
"biometricAuthentication": {
"matchedSessionId": "d40edb60-6ae6-...",
"matchedSessionEndUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"matchedSessionVendorData": "12345678",
"details": {
...
}
},
"comments": []
},
"technicalData": {
"ip": "186.153.67.122"
}
}
Event webhook
This is the description of the payload sent to Webhook events URL
. It tracks the events happening in the identity
verification process as the end-user is passing through it.
Possible events over the webhook
Webhook code | Webhook action | Description | Available | Configuration to receive events | "Waiting for decision" page enabled |
---|---|---|---|---|---|
7001 | started | The end-user arrives to Veriff verification flow and starts the verification process | via API and SDK | Not needed | Not needed |
7002 | submitted | The end-user is done with the process and submits the attempt | via API and SDK | Not needed | Not needed |
7007 | waiting_complete | The end-user gets the decision on the "waiting for decision" page | Web only | Yes, required | Yes, required |
7008 | waiting_continued | The end-user clicks on the Continue button on the "waiting for decision" page before the decision is available. This triggers the action that you have configured for the case when the end-user finishes the flow. | Web only | Yes, required | Yes, required |
7009 | flow_finished | The end-user reached the final screen and clicked on the Continue button | Web only | Yes, required | Not needed |
7010 | flow_cancelled | The end-user abandons the verification flow by clicking on the X in the UI and confirming the cancelling | Web only | Yes, required | Not needed |
As shown in the table above, 7007-7010 events can be received only when you are using Veriff's web flow, and these require some additional configuration on Veriff side. Contact your Solutions Engineer for info and configuration.
There are also events which we do not notify about. See this Knowledge Base article [↗] for more info (requires a login to the Veriff environment).
Event webhook payload
Request properties explained:
id
:string
(required) UUID v4 which identifies the verification sessionattemptId
:string
(required) UUID v4 which identifies session attemptfeature
:string
(required) Feature on which the event was triggered ("selfid" refers to the end-user flow)code
:integer
(required) Event code (one of 7001, 7002)action
:string
(required) Corresponding action description (one of started, submitted)vendorData
:string| null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or as null if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specified
Sample request
{
"id": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"attemptId": "e30122d1-740b-4764-853f-470374a7abf4",
"feature": "selfid",
"code": 7002,
"action": "submitted",
"vendorData": "QWE123",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4"
}
Watchlist screening webhook
This is the description of the payload sent to Webhook watchlist screening URL
.
Only available for customers
using the Veriff PEP and Sanctions services.
Depending on the types of solutions that have been enabled for your integration, different types of webhooks are used to return the data.
PEP & Sanction screening with IDV checks
- The PEP and Sanctions checks are returned using the decision webhook
- If optional adverse media checks are enabled, the checks are returned using the watchlist-screening webhook
- If optional ongoing monitoring is enabled, a second watchlist screening webhook is sent when the OGM check comes in verifying that he intial PEP and Sanctions result changed. This happens independently of the decision (or event) webhook
PEP & Sanction screening without IDV (including optional adverse media and ongoing monitoring checks)
Results of all the checks are returned via watchlist-screening webhook. Decision webhook is not used to pass the checks' info.
Request properties explained:
checkType
:updated_result
(one of initial_result, updated_result)attemptId
:string
UUID v4 which identifies session attemptsessionId
:string
UUID v4 which identifies sessionvendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specifiedmatchStatus
:string
(one of possible_match, no_match)searchTerm
:object
Data used to perform the checkname
:string
Full name used during the checkyear
:string
Birth year used during the check
totalHits
:integer
total number of hits returned from the checkcreatedAt
:string
Timestamp indicating when the check was performedhits
:array
Check response hits array of matched records. Empty array if no hits were not foundmatchedName
:string
The name that was matched in this hit based on the search termcountries
:array
List of countries that sources listed in relation to this hitdateOfBirth
:string
Birth date of the person in the matched listingsdateOfDeath
:string
Death date of the person in the matched listingsmatchTypes
:array
Array that shows the match type in the listingsaka
:array
Array of names that the matched person is also known asassociates
:array
Array of names that the matched person is associated withlistingsRelatedToMatch
:object
Matched listingswarnings
:array
Array of warning matches. Empty array if no warnings were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
sanctions
:array
Array of sanctions matches. Empty array if no sanctions were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
fitnessProbity
:array
Array of fitness probity matches. Empty array if no fitness probabilities were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
pep
:array
Array of PEP matches. Empty array if no PEP matches were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
adverseMedia
:array
Array of media matches. Empty array if no media were foundsourceName
:string
Name of the listingsourceUrl
:string
Url of the listingdate
:string | null
Date of the listing. Null if listing does not have a date
Sample request
{
"checkType": "updated_result",
"attemptId": "54233318-f81c-4ec4-8e4c-413168a3f5e6",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"vendorData": "12345678",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"matchStatus": "possible_match",
"searchTerm": {
"name": "Mirko Kokki",
"year": "1960"
},
"totalHits": 5,
"createdAt": "2021-06-02T11:04:00.287Z",
"hits": [
{
"matchedName": "Miro kokkino",
"countries": [
"Australia",
"Brazil"
],
"dateOfBirth": "1960",
"dateOfDeath": null,
"matchTypes": [
"aka_exact"
],
"aka": [
"Kokki Mirko",
"Mirko Kokki"
],
"associates": [
"Desmon Lamela",
"Fred Austin"
],
"listingsRelatedToMatch": {
"warnings": [
{
"sourceName": "FBI Most Wanted",
"sourceUrl": "http://www.fbi.gov/wanted",
"date": null
}
],
"sanctions": [
{
"sourceName": "Argentina Ministerio de Relaciones Exteriores y Culto Sanciones de la ONU",
"sourceUrl": "https://www.cancilleria.gob.ar/es/politica-exterior/seguridad-internacional/comite-de-sanciones",
"date": null
},
{
"sourceName": "Argentina Public Registry of People and Entities linked to acts of Terrorism and Terrorism Financing",
"sourceUrl": "https://repet.jus.gob.ar/#entidades",
"date": null
}
],
"fitnessProbity": [
{
"sourceName": "United Kingdom Insolvency Service Disqualified Directors",
"sourceUrl": "https://www.insolvencydirect.bis.gov.uk/IESdatabase/viewdirectorsummary-new.asp"
}
],
"pep": [
{
"sourceName": "United States Navy Leadership and Senior Military Officials",
"sourceUrl": "https://www.navy.mil/Leadership/Biographies/"
}
],
"adverseMedia": [
{
"date": "2020-09-23T00:00:00Z",
"sourceName": "SNA's Old Salt Award Passed to Adm. Davidson",
"sourceUrl": "https://www.marinelink.com/amp/news/snas-old-salt-award-passed-adm-davidson-443093"
}
]
}
}
]
}
INE registry validation webhook
INE (Institutio Nacional Electoral - Mexican Electoral Registry) is the organization that issues the voter ID cards and maintains the voters registry.
Below is the description of the payload sent to Webhook INE registry URL
.
The response of the check is sent back once the check is completed.
Request properties explained
eventType
:string
INE registry event namesessionId
:string
UUID for the session where this check was executedattemptId
:string
UUID v4 which identifies session attemptvendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specifiedversion
:string
Version number of the checktime
:string
Timestamp of sending the webhook. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:S+Timezone Offsetdata
:object
Array of data objectsstatus
:string
Status of the datacode
:number
An integer number of the HTTP status code. See the Common HTTP status codes table for more infodetails
:object
Details connected to the specific check against the registryactive
:boolean
Indication of if the INE identification number is active (true
) or inactive (false
)documentState
:string
Explanation of thedata.status
value
Sample request
{
"eventType": "ine_registry",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"attemptId": "e30122d1-740b-4764-853f-470374a7abf4",
"vendorData": "1234567812345678",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"version": "1.0.0",
"time": "2021-06-02T11:04:00.287Z",
"data": {
"status": "La credencial es válida",
"code": 200,
"details": {
"active": true,
"documentState": "El documento es válido."
}
}
}
CURP registry validation webhook
The CURP (Unique Key of Population Registry) is the name of the population number/certificate in Mexico.
Below is the description of the payload sent to Webhook CURP registry URL
.
The response of the check is sent back once the check is completed.
Request properties explained
type
:string
CURP registry check nameid
:string
UUID for the session where this check was executedvendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specifiedversion
:string
Version number of the checkdata
:object | null
Array of data objectsattemptId
:string
UUID v4 which identifies session attemptname
:string
Name of the checkstatus
:string
(One of: found, not found) Status of the datacode
:number
An integer number of the HTTP status code. See the Common HTTP status codes table for more infodetails
:object
Details connected to the specific check against the registrystatusCurp
:string | null
(One of: AN, AH, CRA CU, RCN, RCC, BD, BDA, BCC, BCN) Status of the CURP datacurp
:string
18-character alphanumeric code of the person (the CURP identification number)description
:string
Explanation of thedetails.statusCurp
value
Full forms of the statusCurp
acronyms
Active CURP: AN (Alta Normal), AH (Alta con Homonimia), CRA CU (CURP Reactivada), RCN (Registro de Cambio no Afectando a CURP), RCC (Registro de Cambio Afectando a CURP)
For inactive CURP: BD (Baja por Defuncion), BDA (Baja por Duplicidad), BCC (Baja por Cambio en CURP), BCN (Baja no Afectando a CURP)
Sample request
{
"type": "curp_registry",
"id": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"vendorData": "1234567812345678",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"version": "1.0.0",
"data": {
"attemptId": "e30122d1-740b-4764-853f-470374a7abf4",
"name": "curp_registry",
"status": "found",
"code": 200,
"details": {
"statusCurp": "RCN",
"curp": "VISH760905HSRLNN06",
"description": "Registro de cambio no afectando a curp"
}
}
}
Combined INE CURP validation webhook
INE (Institutio Nacional Electoral - Mexican Electoral Registry) is the organization that issues the voter ID cards and maintains the voters registry.
The CURP (Unique Key of Population Registry) is the name of the population number/certificate in Mexico.
ifeIdentifeir
and ineIdentifier
both represent person's identification number. ife
is a legacy name, it was changed
to ine
.
Below is the description of the payload sent to Webhook combined INE CURP registry URL
.
The response of the check is sent back once the check is completed.
Request properties explained
eventType
:string
CURP registry check namesessionId
:string
UUID for the session where this check was executedattemptId
:string
UUID v4 which identifies session attemptvendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specifiedversion
:string
Version number of the checkdata
:object | null
Array of data objectsstatus
:string
(One of: found, not found) Status of the datacode
:number
An integer number of the HTTP status code. See the Common HTTP status codes table for more infodetails
:object
Details connected to the specific check against the registryine
:object
Details about the INE/IFE identification numberactive
:boolean
Indication of if the INE identification number is active (true
) or inactive (false
)status
:string
Explanation of thedata.status
valueinformation
:string
Extra information about the INE identification numbercomments
:array
Comments regarding the status of the identificationifeIdentifier
:string | null
INE identification number. When this is returned, theineIdentifier
is not present.ineIdentifier
:string | null
IFE identification number. When this is returned, theifeIdentifier
is not present.
curp
:object
Details about the CURP identification numbercurp
:string
CURP identification numberstatusCurp
:string | null
Status of the CURP data (One of: AN, AH, CRA CU, RCN, RCC, BD, BDA, BCC, BCN)descriptionStatusCurp
:string
Explanation of thedetails.curp.statusCurp
valuenames
:string
NamefirstSurname
:string
First surnamesecondSurname
:string
Last surnamegender
:string
Gender (One ofHOMBRE
,MUJER
)dateOfBirth
:string
Date of birth regiondd/mm/yyyy
,nationality
:string
NationalitybirthRegion
:string
Birth regionregionCode
:string
Region codedocumentEvidence
:number
Document evidencedocEvidenceData
:object
1 Details about the document evidence dataregistrationYear
:string
Registration yearactNumber
:string
Act numberregionRegistry
:string
Region registryregistryRegionCode
:string
Registry region coderegistryCity
:string
Registry cityregistryCityCode
:string
Registry city codevolume
:string
Volumesheet
:string
Sheetbook
:string
Book
Full forms of the statusCurp
acronyms
Active CURP: AN (Alta Normal), AH (Alta con Homonimia), CRA CU (CURP Reactivada), RCN (Registro de Cambio no Afectando a CURP), RCC (Registro de Cambio Afectando a CURP)
For inactive CURP: BD (Baja por Defuncion), BDA (Baja por Duplicidad), BCC (Baja por Cambio en CURP), BCN (Baja no Afectando a CURP)
Sample request
{
"eventType": "combined-ine-curp-registry",
"sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5",
"attemptId": "e30122d1-740b-4764-853f-470374a7abf4",
"vendorData": "1234567812345678",
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"version": "1.0.0",
"data": {
"status": "found",
"code": 200,
"details": {
"ine": {
"active": true,
"status": "La credencial esta vigente",
"comments": [
"CIC 000000000\r\nClave de elector JRLGLS00000000H000\r\nNúmero de emisión 1\r\nDistrito Federal 3\r\nDistrito Local 4\r\nNúmero OCR 0000000000000\r\nAño de registro 2009\r\nAño de emisión 2020",
"Fecha de actualización de la información: 10 de agosto del 2023 19:48",
"Fecha de consulta: 11 de agosto del 2023",
"Tus datos se encuentran en el Padrón Electoral, y también en la Lista Nominal de Electores"
],
"information": "CIC 000000000\r\nClave de elector JRLGLS00000000H000\r\nNúmero de emisión 1\r\nDistrito Federal 3\r\nDistrito Local 4\r\nNúmero OCR 0000000000000\r\nAño de registro 2009\r\nAño de emisión 2020\r\nFecha de actualización de la información: 10 de agosto del 2023 19:48\r\nFecha de consulta: 11 de agosto del 2023\r\nEsta vigente como medio de identificación y puedes votar.\r\nTus datos se encuentran en el Padrón Electoral, y también en la Lista Nominal de Electores.\r\nSerá válida hasta el 31 de diciembre de 2030",
"ifeIdentifier": "",
"ineIdentifier": "000000000"
},
"curp": {
"curp": "ABCD000000HVZRGS00",
"statusCurp": "RCN",
"descriptionStatusCurp": "Registro de cambio no afectando a curp",
"names": "LOREM IPSUM",
"firstSurname": "JUAREZ",
"secondSurname": "LAGUNES",
"gender": "HOMBRE",
"dateOfBirth": "06/04/1991",
"nationality": "MEX",
"birthRegion": "Veracruz",
"regionCode": "VZ",
"documentEvidence": 1,
"docEvidenceData": {
"registrationYear": "1991",
"actNumber": "00001",
"regionRegistry": "30",
"registryRegionCode": "VZ"
"registryCity": "",
"registryCityCode": "125",
"volume": "",
"sheet": "",
"book": ""
},
}
}
}
}
User-defined session statuses webhook
This is the description of the payload sent to the Webhook URL for sessions statuses set in Station
.
This webhook is sent after the user has added a status to an attempt in the Veriff environment.
Properties explained
data
:object
verification
:object
Array of JSON objects identifying the attemptsid
:UUID
-v4 of the attemptuserDefinedData
:object
Describes the custom statuses defined by the user. Instructions how to add statuses can be found here [↗] (requires a login to the Veriff environment).status
:string
Name of the custom status as set in the Veriff environmentstatusCode
:string
Autogenerated code for the custom statusreason
:string
Name of the custom reason as set in the Veriff environment. If the user has selected the "Custom" reason for the status and typed an explanation to the text box, then the explanation is sent in this field.reasonCode
:string | null
Autogenerated code for the reason. It isnull
when the user has selected the "Custom" reason for the status and typed an explanation to the text box. This explanation is sent in thereason
parameter.createdAt
:string
Timestamp of when the custom status was added. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone Offset
time
:string
Timestamp of when the webhook was sent. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsetattemptId
:UUID
-v4 of the attempteventType
:string
(user-status.created) Indicates the event typesessionId
:UUID
of the session where the attempt belongs tovendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not specified
{
"data": {
"verification": {
"id": "a1c68aea-7f4d-478d-80ab-ca9356074f69",
"userDefinedData": {
"reason": "Looks like velocity abuse",
"status": "Custom status for suspicious attempt",
"createdAt": "2023-10-27T09:59:15.090805Z",
"reasonCode": null,
"statusCode": "custom_status_for_suspicious_attempt"
}
}
},
"time": "2023-10-27T10:00:02.998Z",
"attemptId": "f2270684-8c51-4d03-88eb-dafd43e8b486",
"eventType": "user-status.created",
"sessionId": "0b10cb53-4f3b-48af-bd74-60b85354e51f",
"vendorData": null,
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4"
}
Full Auto webhook
This section gives a more general overview of the contents of the Full Auto webhook, which is used to send decision info for Full Auto sessions that return insights, extractions and the decision score.
Log in to Veriff environment to see:
- The article explaining the webhook properties in detail [↗]
- The article showing a sample webhook in detail [↗]
Full Auto webhook request properties explained
status
:string
(one of "success", "failed" ) Status of the requesteventType
:string
("fullauto") Full Auto event namesessionId
:UUID
UUID v4 which identifies the sessionattemptId
:UUID
UUID v4 which identifies session attemptvendorData
:string | null
Customer-specific data string, max 1000 characters longversion
:string
Webhook versionacceptanceTime
:string
Timestamp of when the session was generated. Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2018-04-18T11:02:05.261Z)time
:string
Timestamp of when the event was generated. Combined ISO 8601 date and time in UTC (YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset|Z, i.e., 2018-04-18T11:02:05.261Z)data
:object
Verification data objectsverification
:object
decisionScore
:number | null
A float number, shows how confident the system is that the session is genuine. Higher number indicates higher confidence. The number is rounded up to two decimal places.decision
:string
(one of: "approved", "declined", "resubmission_requested", "abandoned", "expired") Shows system’s suggestion of what to do with the sessionperson
:object
Data extracted from the document about the person. Contains additionalobjects
with specific data that has been extracted...
:object | null
Extraction activity name. Log in to the Veriff environment to see the possible extraction activity names in the detailed request properties explanation [↗] or check the sample payload [↗] for more infoconfidenceCategory
:string | null
(one of "high", "medium", "low") Shows the confidence valuevalue
:string | null
Data extracted from the documentsources
:array | empty
(VIZ, MRZ, NFC, BARCODE) Shows the document data field where the data was extracted from
document
:object
Data extracted from the document about the document. Contains additionalobjects
with specific data that has been extractedtype
:object | null
value
:string | null
(one of "PASSPORT", "ID_CARD", "RESIDENCE_PERMIT", "DRIVERS_LICENSE", "VISA") Document type
country
:object | null
value
:string | null
ISO-2 country code of the document country
...
:object | null
Extraction activity name. Log in to the Veriff environment to see the possible extraction activity names in the detailed request properties explanation [↗] or check the sample payload [↗] for more infoconfidenceCategory
:string | null
(one of "high", "medium", "low") Shows the confidence valuevalue
:string | null
Data extracted from the documentsources
:array | empty
(VIZ, MRZ, NFC, BARCODE) Shows the document data field where the data was extracted from
insights
:array | null
Array of pieces of metadata that help explain thedecision
. Please note that the actual list of insights visible in the webhook payload depends on your integration.label
:string
Name of the insight. Log in to the Veriff environment to see the possible insights in the detailed request properties explanation [↗] or check the sample payload [↗] for more inforesult
:string
(one of "yes", "likelyYes", "no", "notApplicable") Result of the insightcategory
:string
Name of the category the insight belongs to. Log in to the Veriff environment to see the possible insights in the detailed request properties explanation [↗] or check the sample payload [↗] for more info
Note about the decision score
Parameter data.verification.decisionScore
shows how confident the system is that the session is genuine.
Lower number means that the confidence is low, higher number means that the session
is more likely to be genuine.
The score is shown on two scales:
- 0-1 in the API response and webhook
- 0-100 in the Veriff environment
Full Auto webhook lightweight sample
{
"status": "success",
"eventType": "fullauto",
"sessionId": "1234567d-1ab2-34c5-bba7-a23gh58908er",
"attemptId": "12e3d456-9ea2-7821-12io-aabb4113bgtf",
"vendorData": null,
"version": "1.0.0",
"acceptanceTime": "2023-10-05T17:34:06.882846Z",
"time": "2023-10-05T17:33:22.449Z",
"data": {
"verification": {
"decisionScore": 0.96,
"decision": "approved",
"person": {
"firstName": {
"confidenceCategory": "medium",
"value": "ASHOK",
"sources": [
"MRZ",
"VIZ"
]
},
...
},
"document":{
"type": {
"value": "id_card"
},
"country": {
"value": "IN"
},
"number": {
"confidenceCategory": "high",
"value": "123abc456",
"sources": [
"MRZ",
"VIZ"
]
},
...
},
"insights":[
{
"label": "xwz",
"result": "yes",
"category": "abc"
},
{
...
},
]
},
},
}
Webhooks testing
For testing purposes we provide an example payload, so you do not depend on Veriff sending the response. You can use the Curl command below.
Note that the signature will not match your API Public Key and API Private Key. To validate this example signature and payload, use API Private Key 'abcdef12-abcd-abcd-abcd-abcdef012345'.
curl --request POST 'https://your.url' -k \
--header 'accept:application/json' \
--header 'x-auth-client:8e4f7cd8-7a19-4d7d-971f-a076407ee03c' \
--header 'x-hmac-signature:01fa3ded011bfce75672c99877a6cc1cf7aeaeda0ccb6b43fc21b60f595063c2' \
--header 'content-type:application/json' \
--data '{"status":"success","verification":{"id":"12df6045-3846-3e45-946a-14fa6136d78b","code":9001,"person":{"gender":null,"idNumber":null,"lastName":"MORGAN","addresses":[{"fullAddress":"1234 Snowy Ridge Road, Indiana, 56789 USA","parsedAddress":{"city":null,"unit":null,"state":"Indiana","street":"1234 Snowy Ridge Road","country":"USA","postcode":"56789","houseNumber":"null"}}],"firstName":"SARAH","citizenship":null,"dateOfBirth":"1967-03-30","nationality":null,"yearOfBirth":"1967","placeOfBirth":"MADRID","pepSanctionMatch":null},"reason":null,"status":"approved","comments":[],"document":{"type":"DRIVERS_LICENSE","number":"MORGA753116SM9IJ","country":"GB","validFrom":null,"validUntil":"2022-04-20","placeOfIssue":"MADRID","firstIssue":"2015-03-21","issueNumber":"01","issuedBy":"ISSUER"},"reasonCode":null,"vendorData":"12345678","decisionTime":"2019-11-06T07:18:36.916Z","acceptanceTime":"2019-11-06T07:15:27.000Z","additionalVerifiedData":{"driversLicenseCategory":{"B":true},"driversLicenseCategoryFrom":{"B":"2019-10-06"},"driversLicenseCategoryUntil":{"B":"2025-10-05"},"estimatedAge":32,"estimatedGender":0.613},"riskLabels":[{"label":"document_integration_level_crosslinked_with_fraud","category":"document","sessionIds":["5a2358e7-fd31-4fcb-a23f-4d76651ba68a"]},{"label":"document_integration_level_crosslinked_with_multiple_declines","category":"document","sessionIds":["fd5c1563-1d23-4b1a-ae46-7ba429927ed8"]}],"biometricAuthentication":{"matchedSessionId":"d40edb60-6ae6-4475-be72-84b81669cce6","matchedSessionVendorData":"User001"}},"technicalData":{"ip":"186.153.67.122"}}'
Full Auto
This is a fully automated identity verification service, which can be integrated via SDKs and the API.
There are two options for identity verification:
- Doc only Identity Verification ("Doc only IDV"), where the end-user submits images of only their ID document (front and back)
- Identity Verification ("IDV"), where the end-user submits images of their ID document and themselves (document front and back + a selfie)
The system analyzes the images, verifies the end-user and returns the results via decision webhook. All the information can also be queried via GET sessions/{sessionId}/decision endpoint.
The results of the verification can also be viewed in the Veriff environment.
Full Auto prerequisites
Full Auto flow
Create a new session using the keys and the baseURL of the Full Auto integration (see the API Reference about how to find these in the Veriff environment).
Direct the end-user to the verification flow.
The end-user passes through the end-user flow on their device. They are required to capture the front and back of their ID document, and, in case of face validation, take a selfie.
a. When using the SDK/Web flow, the session status is automatically updated to
submitted
as soon as the end-user has submitted the images.b. When using the API requests, you need to do this manually. See the Sending the end-user data via API section below for more information.
Receive the results from Veriff via decision webhook, query them using the GET sessions/{sessionId}/decision endpoint, or view them in the Veriff environment.
Full Auto over SDK
If you have integrated with Veriff using the SDKs and you have set up the decision webhook URL in the Veriff environment, you are all set.
Full Auto over API
Before you start, make sure that you have configured the decision webhook.
Sending the end-user data via API
- Start a session using the POST /sessions
- If you want to use the Biometric Authentication, make sure to also pass the
vendorData
/endUserId
- If you want to use the Biometric Authentication, make sure to also pass the
- Upload the highly recommended device/session data via POST sessions/{sessionid}/collected-data for improved fraud detection
- Upload end-user's ID document (and selfie images, if applicable) via POST sessions/{sessionId}/media
- Specify the
image.context
as appropriate for the image (see the context types for more info) - Patch the session status to
submitted
using the PATCH sessions/{sessionId}
Getting Full Auto session decision
You can get the data from three sources:
- The decision webhook
- Query the results via GET sessions/{sessionId}/decision
- View the results in the Veriff Environment
Full Auto results in decision webhook
Results of the Full Auto session are returned in the decision webhook.
Note that below is an explanation and a sample of a decision webhook payload for a Full Auto session. The decision webhook is used for many purposes, to find more info about it, see the full decision webhook section.
Webhook payload properties explained
status
:string
Status of the responseverification
:object
Verification request decision object.null
if decision is not available yetid
:string
UUID v4 which identifies the verification sessioncode
:integer
Verification response code, one of 9001, 9102, 9103, 9104, 9121. More information about decision codesperson
:object
Verified persongender
:string | null
Person's gender, one of M, F ornull
idNumber
:string | null
Person's national identification numberlastName
:string | null
Person's last namefirstName
:string | null
Person's first namecitizenship
:(Deprecated)
null
dateOfBirth
:string
Person's date of birth, as YYYY-MM-DDnationality
:string | null
Person's nationalityyearOfBirth
:string | null
Person's year of birth, as YYYYplaceOfBirth
:string | null
Person's place of birthpepSanctionMatch
:string | null
Legacy field for PEP and Sanctions checks, should be ignored at all times
reason
:string | null
Reason for failed verificationstatus
:approved
Verification status, one ofapproved
,resubmission_requested
,review
,declined
,expired
,abandoned
comments
:array
(Deprecated)document
:object
Verified documenttype
:string
Document type, one ofPASSPORT
,ID_CARD
,RESIDENCE_PERMIT
,DRIVERS_LICENSE
,VISA
,OTHER
. A list of supported document typesnumber
:string | null
Document number, [a-zA-Z0-9] characters onlycountry
:string | null
Document issuing country, as ISO 3166 alpha-2 codestate
:string | null
Document issuing state, as ISO 3166 alpha-2 or alpha-3 code.null
when the state data is not present on the documentvalidFrom
:string | null
Document is valid from datevalidUntil
:string | null
Document is valid until date
reasonCode
:integer | null
Reason code of failed verification. A table of response and error codesvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provideddecisionTime
:string
Timestamp of the decision. Combined ISO 8601 date and time in UTC, YYYY-MM-DDTHH:MM:SSS+Timezone OffsetacceptanceTime
:string
Timestamp of the session generation. Combined ISO 8601 date and time in UTC, YYYY-MM-DDTHH:MM:SSS+Timezone OffsetadditionalVerifiedData
:object
Data which has been optionally verified for session
technicalData
:object
Technical data objectip
:string | null
IP of the device from which the verification was made
Sample request
{
"status": "success",
"verification": {
"id": "12df6045-3846-3e45-946a-14fa6136d78b",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"lastName": "MORGAN",
"addresses": [],
"firstName": "SARAH",
"citizenship": null,
"dateOfBirth": "1990-01-09",
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": "DRIVERS_LICENSE",
"state": "NY",
"number": "1234569",
"country": "US",
"validFrom": "2024-04-20",
"validUntil": "2028-04-19"
},
"endUserId": null,
"reasonCode": null,
"vendorData": "12345678",
"decisionTime": "2024-08-15T17:57:03.376067Z",
"acceptanceTime": "2024-08-15T17:56:31.021837Z",
"additionalVerifiedData": {}
},
"technicalData": {
"ip": "186.153.67.122"
}
}
Querying the Full Auto decision data via API
You can use the GET sessions/{sessionId}/decision endpoint to get the decision data.
Note that below is an explanation and a sample of a GET call payload for a Full Auto session. The GET sessions/{sessionId}/decision endpoint is used for many purposes, to find more info about it, see the GET sessions/{sessionId}/decision section.
API request
Request method: GET
Media type: application/json
Type: object
Headers
X-AUTH-CLIENT: string (required)
= API key
X-HMAC-SIGNATURE: string (required)
= sessionId
signed with the shared secret key
Content-Type: application/json
API response properties explained
status
:string
Status of the responseverification
:object
Verification request decision object.null
if decision is not available yetid
:string
UUID v4 which identifies the verification sessioncode
:integer
Verification response code, one of 9001, 9102, 9103, 9104, 9121. More information about decision codesperson
:object
Verified persongender
:string | null
Person's gender, one of M, F ornull
idNumber
:string | null
Person's national identification numberlastName
:string | null
Person's last namefirstName
:string | null
Person's first namecitizenship
:(Deprecated)
null
dateOfBirth
:string
Person's date of birth, as YYYY-MM-DDnationality
:string | null
Person's nationalityyearOfBirth
:string | null
Person's year of birth, as YYYYplaceOfBirth
:string | null
Person's place of birthpepSanctionMatch
:string | null
Legacy field for PEP and Sanctions checks, should be ignored at all timesreason
:string | null
Reason for failed verificationstatus
:approved
Verification status, one ofapproved
,resubmission_requested
,review
,declined
,expired
,abandoned
comments
:array
(Deprecated)document
:object
Verified documenttype
:string
Document type, one ofPASSPORT
,ID_CARD
,RESIDENCE_PERMIT
,DRIVERS_LICENSE
,VISA
,OTHER
. A list of supported document typesnumber
:string | null
Document number, [a-zA-Z0-9] characters onlycountry
:string | null
Document issuing country, as ISO 3166 alpha-2 codestate
:string | null
Document issuing state, as ISO 3166 alpha-2 or alpha-3 code.null
when the state data is not present on the documentvalidFrom
:string | null
Document is valid from datevalidUntil
:string | null
Document is valid until datereasonCode
:integer | null
Reason code of failed verification. A table of response and error codesvendorData
:string
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:uuid | null
End-user-specific UUID created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not provideddecisionTime
:string
Timestamp of the decision. Combined ISO 8601 date and time in UTC, YYYY-MM-DDTHH:MM:SSS+Timezone OffsetacceptanceTime
:string
Timestamp of the session generation. Combined ISO 8601 date and time in UTC, YYYY-MM-DDTHH:MM:SSS+Timezone OffsetadditionalVerifiedData
:object
Data which has been optionally verified for session
technicalData
:object
Technical data objectip
:string | null
IP of the device from which the verification was made
Sample response
{
"status": "success",
"verification": {
"id": "12df6045-3846-3e45-946a-14fa6136d78b",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"lastName": "MORGAN",
"addresses": [],
"firstName": "SARAH",
"citizenship": null,
"dateOfBirth": "1990-01-09",
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": "DRIVERS_LICENSE",
"state": "NY",
"number": "1234569",
"country": "US",
"validFrom": "2024-04-20",
"validUntil": "2028-04-19"
},
"endUserId": null,
"reasonCode": null,
"vendorData": "12345678",
"decisionTime": "2024-08-15T17:57:03.376067Z",
"acceptanceTime": "2024-08-15T17:56:31.021837Z",
"additionalVerifiedData": {}
},
"technicalData": {
"ip": "186.153.67.122"
}
}
Biometric Authentication
Veriff’s Biometric Authentication solution uses facial biometric analysis and advanced AI to swiftly and securely verify that the person authenticating themselves is the person they claim they are. This fast and fully automated process can be integrated into any stage of the user journey. Veriff Biometric Authentication is available via API, web flow, and native SDKs.
Prerequisites
- You need to have a selfie enrollment integration set up
- You need to have an authentication integration set up and connected to the selfie enrollment integration
- You must generate and attach
endUserId
* orvendorData
** to each end-user, and pass Veriff this info - The end-user needs to have an approved session from the selfie enrollment integration
*If you have generated the unique end-user identifier in the UUID v4 format, we recommend sending it in the
endUserID
field.
**If you have the unique end-user identifier in a format that is not UUID v4, you can send it in the vendorData
field.
How to set up a Biometric Authentication solution?
Set up the selfie enrollment integration
To use Veriff’s biometric authentication solution, you first need the selfie enrollment integration. Read on for more information, but contact your Solutions Engineer for configuration.
In general terms[↗], enrollment is a process of capturing biometrics samples, processing them to create a biometric template and storing the templates onto storage. In Veriff’s case, the enrollment integration is the one during which the raw biometrics data (e.g., end-user's face image) is processed and converted into a mathematical biometric template. The template is stored so it can be used in the future to verify the end-user during a biometric authentication session.
The image is taken from an approved IDV session, or a selfie-only session that is run in the enrollment integration. If the session
is approved (the image quality meets certain criteria, the endUserId
/vendorData
is present, there is no suspicion of fraudulent
activity, etc.) the selfie image from the session is stored and can be used as a reference image.
How to pass selfie images to Veriff?
The image that is used for enrollment (biometric data capturing, processing and conversion into a biometric template) can come from different sources.
Customers using the Veriff’s Doc & Selfie IDV solution | Customers not using Veriff’s Doc & Selfie IDV solution | |
The selfie image taken from an approved IDV session becomes the reference image. It is converted into a biometric template and stored for future use. It is possible to migrate* images from previous IDV sessions for authentication. | An IDV/selfie-only session is done inside the biometric enrollment integration. If the session is approved, the selfie enrollment image is converted into a biometric template and stored for future. | If existing face images are available: previously collected selfie images become reference images and are enrolled. This may require migration*. |
*In cases of migration, contact your Solutions Engineer for more info.
Set up the authentication integration
This is the integration that you will use to create biometric authentication sessions for the end-users. It must be connected to the enrollment integration, so the system has access to the following end-user-related data in the enrollment integration:
- Biometric template
- Approved session data
endUserId
/vendorData
Contact your Solutions Engineer for configuration. Once ready, you can start creating authentication sessions for your end-users in the SDKs, or send us collected end-user data over the API.
When creating the verification sessions in the SDKs or sending us the end-users’ data over the API, use the API keys and tokens of the authentication integration (you can find these in the Veriff environment. See here for more info about how to find the keys and tokens.)
Make sure to always include the endUserId
/vendorData
as we need to see that it matches the end-user’s
approved session’s endUserId
/vendorData
in the selfie enrollment integration.
How to use Biometric Authentication over the SDK?
Step-by-step guide
- Generate an authentication session using the authentication integration tokens (check the POST /sessions endpoint in the API reference)
- Make sure that you include the same
endUserId
/vendorData
that you used in the enrollment integration session
- Make sure that you include the same
- Capture end-user’s face images with Veriff’s SDKs
- Send the end-user through the verification flow to capture the new face image (using one of Veriff SDKs: iOS, Android, React Native, Flutter, InContext)
- You need the session URL generated in step 1 to use the SDKs
- Session will be submitted automatically once the end-user takes and submits necessary images of their face
- Receive the results from Veriff via decision webhook
From the end-user point of view
When the end-user needs to authenticate, they simply take a selfie using their device camera. A new template is created
and compared against the stored template from enrollment. If they match within a set accuracy threshold, and the
endUserId
/vendorData
in the enrollment integration session match that in the authentication integration session, the user
is successfully identified.
How to use Biometric Authentication over the API?
This is applicable once the end-user has an approved session containing a populated endUserID
/vendorData
.
Step-by-step guide
- Generate an authentication session using the authentication integration tokens (check the POST /sessions endpoint in the API reference)
- Make sure that you include the same
endUserId
/vendorData
that you used in the enrollment integration session
- Make sure that you include the same
- Use your face-capturing method, or prepare previously collected end-user face images
- Upload the end-user's face image via the POST /sessions/{sessionId/}media call. Specify context parameter as
face
. - Patch session status to
submitted
status using PATCH /sessions/{sessionId} call - Receive the results from Veriff via decision webhook
How to get the verification results?
All biometric authentication results are returned via the decision webhook, inside the
verification.biometricAuthentication
object.
If the session was declined, you can find additional information by checking the verification.status
,
verification.code
, verification.reason
and verification.reasonCode
data objects.
Request properties
status
:string
Status of the responseverification
:object
Verification request decision object- …
endUserId
:UUID v4 | null
End-user-specific UUID v4 created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedvendorData
:string | null
End-user-specific string created by the customer to identify the end-user. Returned unmodified in webhooks and public API calls, or asnull
if not providedstatus
:string
Verification status, one ofapproved
,resubmission_requested
,review
,declined
,expired
,abandoned
code
:integer
Verification session decision code, one of9001
,9102
,9103
,9104
,9121
. More information about verification session decision codesreason
:string | null
Reason of failed verificationreasonCode
:string | null
Reason code of failed verificationbiometricAuthentication
:object
Object containing data about the biometric authenticationmatchedSessionId
:string | null
Refers to the verification session ID which the face matchedmatchedSessionEndUserId
:string | null
Refers to the verification sessionendUserId
which the face matchedmatchedSessionVendorData
:string | null
Refers to the verification sessionvendorData
which the face matcheddetails
:object
Lists the results of different checks that were made to verify the end-user. Log in to the Veriff environment to see the check names in the detailed request explanation[↗].
Sample request properties
{
"status": "success",
"verification": {
...
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"vendorData": "12345678",
"status": "approved",
"code": 9001,
"reason": null,
"reasonCode": null
"biometricAuthentication": {
"matchedSessionId": "d40edb60-6ae6-...",
"matchedSessionEndUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"matchedSessionVendorData": "12345678",
"details": {
...
}
},
...
}
}
How to handle authentication integration statuses and decisions?
Biometric authentication session status and status code
These values are available in the decision webhook payload, in verification.status
and verification.code
data
objects.
verification.status |
verification.code |
What does it mean? | approved | 9001 | Positive: end-user was verified. The verification process is complete. Accessing the sessionURL again will show the end-user that nothing is to be done here. |
declined | 9102 | Negative: end-user has not been verified. The verification process is complete. Either it was a fraud case or some other severe reason that the end-user can not be verified. It could also have been that due to a bad image quality the end-user could not be matched. If you decide to give the end-user another try, you need to create a new session. | expired | 9104 | Negative: Verification has expired. The verification process is complete. After the session creation, if the end-user has not started the verification in 7 days, the session gets expired. |
abandoned | Negative: Verification has been abandoned. The verification process is complete. After the session creation, if the end-user has started but not completed the verification in 7 days, the session gets abandoned status. |
Biometric authentication session decision reason and reason codes
These values are available in the decision webhook payload, in verification.status
, verification.reasonCode
and
verification.reason
data objects.
verification.status |
verification.reasonCode |
verification.reason |
What does it mean? |
declined | 105 | Decline - Suspicious behavior | The session contains some suspicious behaviour, for example the face image is shown from a device, screen or print-out. The end-user is declined. |
declined | 106 | Decline - Known fraud | The session contains fraudulent behaviour, for example the photos are streamed. The end-user is declined. |
declined | 120 | Decline - Person on the portrait does not appear to match reference photo | The end-user is declined |
declined | 121 | Decline - user ID missing | The vendorData does not match the vendorData used during enrollment, the end-user
is declined. To avoid this issue, ensure the same vendorData is sent.
|
declined | 122 | Decline - No reference found | No enrollment face image (reference image) found that would match the endUserId /vendorData ,
the end-user is declined. |
declined | 128 | Decline - endUserId mismatch |
The endUserId does not match the endUserId used during enrollment, the end-user
is declined. To avoid this issue, ensure the same endUserId is sent.
|
expired | null | null | The end-user did not complete the verification flow. If you want to let them to try again, create a new session for them |
abandoned |
AML Screening
PEP & Sanction screening with IDV
PEP & Sanctions, adverse media screening together with identity verification
Prerequisites
An IDV integration with PEP & Sanctions checks configured together with optional adverse media checks and ongoing monitoring. Turn to your dedicated Solutions Engineer for configuration.
Process overview
- Once the integration is set up, generate a verification session using the regular /sessions endpoint.
- After the end-user has submitted the verification flow and the session has been verified, the AML result will be sent in a separate webhook. You can also query for the result using the watchlist-screening API endpoint
- In case ongoing monitoring is enabled, we will send a new webhook if the PEP & Sanctions status of a verified person has changed. a. The Webhook PEP & Sanctions URL can be configured from the “Integrations” menu
PEP & Sanction screening without IDV
PEP & Sanctions, adverse media screening without identity verification
Prerequisites
A non-IDV integration with PEP & Sanctions checks configured together with optional adverse media checks and ongoing monitoring. Turn to your dedicated Solutions Engineer for configuration.
Process overview
- Generate a new verification session using the /sessions endpoint and specify the following fields in the request: a. First name (required) b. Last name (required) c. Date of Birth (optional)
- Change the status of the session to “Submitted” using PATCH /sessions/{sessionId} endpoint
- The results will be sent in a separate webhook and are also available using the /watchlist-screening end-point. a. The Webhook PEP & Sanctions URL can be configured from the “Integrations” menu
UK DIATF
Veriff is a certified IDSP under the UK Digital Identity and Attributes Trust Framework (UK DIATF), UK Government site[↗]
Within the framework of UK DIATF, we offer the following solutions:
- UKDIATF Certified Identity Verification (M1A) - used with Veriff’s end-user flow (cannot be customized); no mandatory fields, 1 registry check: CIFAS
- UKDIATF Certified Identity Verification (M1B) - used with Veriff’s end-user flow (cannot be customized), sending the address is mandatory; 3 registry checks: CIFAS, PEP and UK Electoral roll
- UKDIATF Certified Identity Verification (L1B) - used with Veriff's end-user flow (can be customized); no mandatory fields, no registry checks
UKDIATF Certified Identity Verification (M1A)
This is a solution that is completed using Veriff’s end-user flow (cannot be customized). Sending the address on session creation is optional.
Below is a step-by-step overview of the flow.
Step 1: create a session using the POST /sessions endpoint
See the POST /sessions section for a detailed overview of how to create a session.
Sending the verification.address.fullAddress
parameter is optional.
Step 2: create a session using the POST /sessions endpoint
Open the response payload of the POST /sessions request you just made and use the URL in the verification.url
parameter.
A web flow will start, which will guide you through the process.
Step 3: wait for session decision and decision webhook response
As soon as the session is verified, the decision webhook will send the response with session status. It will be one of 9000-code statuses.
In case the session is declined, the webhook contains relevant info about the reason. This info is visible in
verification.code
, verification.reason
, and verification.reasonCode
parameters.
M1A webhook response
M1A Webhook response = decision webhook response (see documentation here)
UKDIATF Certified Identity Verification (M1B)
This is a solution that requires that the end-user's address is provided to return info from registries, and that the flow must be completed using Veriff's verification flow (cannot be customized). Below is a step-by-step overview of the flow.
Step 1: create a session using the POST /sessions endpoint
See the POST /sessions section for a detailed overview of how to create a session.
Sending the verification.address.fullAddress
parameter is mandatory.
Step 2: capture user pictures and videos via verification flow
Open the response payload of the POST /sessions request you just made and use the URL
in the verification.url parameter
. A web flow will start, which will guide you through the process.
Step 3: wait for session approval and decision webhook response
As soon as the session is approved, the decision webhook will send an approved response.
This response will include the session status, as well as all the data that was extracted from the UK DIATF checks.
This info is visible in verification.additionalVerifiedData.UKTFCheckResult
array.
In case the session is declined, the webhook contains relevant info about the reason. This info is visible
in verification.code
, verification.reason
, verification.reasonCode
and verification.additionalVerifiedData.UKTFCheckResult
parameters.
M1B webhook response
Response properties explained
status
:string
Status of the responseverification
:object
Verification request decision object- …
additionalVerifiedData
:object
Data which has been optionally verified for sessionUKTFCheckResult
:array
Array of UK DIATF checks results. These are executed in succession. If the preceding check fails, the succeeding one is skipped. The order is as shown below, but in webhook response the order may be random.CIFAS
:string
CIFAS registry check resultElectoral roll and Credit History UK
:string
UK Electoral Roll and Credit History check resultPEP
:string
PEP check result.
Example response of approved session
{
"status": "success",
"verification": {
…
"additionalVerifiedData": {
"UKTFCheckResult": {
"CIFAS": "Registry validation was successful",
"Electoral roll and Credit History UK": "Registry validation was successful"
"PEP": "Registry validation was successful",
}
}
},
…
}
Example responses of declined session due to failed CIFAS check
Scenario: there may be a possible match in the CIFAS database
{
"status": "success",
"verification": {
…
"additionalVerifiedData": {
"UKTFCheckResult": {
"CIFAS": "CIFAS registry detected a potential match.",
"Electoral roll and Credit History UK": "Registry check did not result in a match"
"PEP": "Registry check was not executed",
}
}
},
…
}
Example responses of declined session due to UK Electoral Roll and Credit History check
Scenario: the end-user data may be incorrect or missing in the database
{
"status": "success",
"verification": {
…
"additionalVerifiedData": {
"UKTFCheckResult": {
"CIFAS": "Registry validation was successful",
"Electoral roll and Credit History UK": "Registry check did not result in a match"
"PEP": "Registry check was not executed",
}
}
},
…
}
Example responses of declined session due to failed PEP check
Scenario: end-user detected as potential PEP
{
"status": "success",
"verification": {
…
"additionalVerifiedData": {
"UKTFCheckResult": {
"CIFAS": "Registry validation was successful",
"Electoral roll and Credit History UK": "Registry validation was successful"
"PEP": "Person detected to be potentially a PEP",
}
}
},
…
}
UKDIATF Certified Identity Verification (L1B)
The solution is a UK-certified version of Veriff’s standard identity verification. You must use Veriff’s end-user flow to capture the document & selfie, but you can customize the flow.
If you are not integrated with us yet, see the Getting started with Veriff for first steps. If you are, contact your Solutions Engineer for info and configuration.
Age Estimation
This solution estimates end-user's age from the selfie images that they capture. Customers receive the end-user's estimated age and estimated gender.
Age Estimation process overview
There are two different ways to utiliaze the Age Estimation service: via Veriff's verification flow or trough API.
Age Estimation via Veriff's verification flow
- Create a session using the Age Estimation integration's tokens (see POST /sessions for more details
about how to create a session)
- You can use
vendorData
orendUserId
parameter to pass a unique identifier for the end-user in the flow. We require only non-semantic data to be submitted (e.g. UUID-s that can not be resolved or used outside the customer's environment).
- You can use
- Direct the end-user into the verification flow
- The end-user passes through the verification flow on their device, where they are required to capture only a selfie (no ID document is needed)
- Session will be automatically set to
submitted
- Receive the results from Veriff via decision webhook; you can also query them using GET sessions/{sessionId/decision}
Age Estimation over the API
- Create a session using the Age Estimation integration's tokens (see POST /sessions for more details
about how to create a session)
- You can use
vendorData
orendUserId
parameter to pass a unique identifier for the end-user in the flow. We require only non-semantic data to be submitted (e.g. UUID-s that can not be resolved or used outside the customer's environment).
- You can use
- Upload the end users selfie via POST sessions/{sessionId}/media endpoint with
image.context
asface
- Patch the session to
submitted
using the PATCH sessions/{sessionId} - Receive the results from Veriff via decision webhook; you can also query them using GET sessions/{sessionId/decision}
In the webhook and the endpoint, the data is in:
verification.additionalVerifiedData.estimatedAge
as anumber
of the estimated exact ageverification.additionalVerifiedData.estimatedGender
as anumber
of the estimated* gender.
*Values closer to 0.0 indicate that the end-user is likely to be male, values closer to 1.0 indicate that the end-user is likely to be female.
Age Estimation session decisions
The verification.status
and verification.code
can be:
approved
, code 9001declined
, code 9102resubmission
akaresubmission_requested
, code 9104
End-user in the Age Estimation flow (diagram)
Proof of Address Capture
Proof of Address Capture (PoA Capture) feature captures the submitted document. No further analysis is performed.
The flow is completed using several IDV endpoints.
Brief overview of the flow
- Submit a session using the POST sessions endpoint
- Make a POST /sessions/{sessionId}/media request to send image file
- Update the session status to "submitted" using the PATCH /sessions/{sessionId}
- Now you can now use the following endpoints to query the document info:
- GET /sessions/{sessionId}/media
- GET /attempts/{attemptId}/media
- GET /media/{mediaId}
Step-by-step overview of the flow
Click on the step to expand.
Proof of Address Extraction
Proof of Address Extraction (PoA Extraction) feature captures the submitted document and extracts the
firstName
, fullAddress
and document.validFrom
data from it.
The flow is completed using several IDV endpoints.
It is possible to get the additional name match check enabled for your integration. See the Optional Proof of Address name match check section below for more info.
Brief overview of the PoA Extraction flow
- Submit a session using the POST sessions endpoint
- Make a POST /sessions/{sessionId}/media request to send image file
- Update the session status to "submitted" using the PATCH /sessions/{sessionId}
- Wait for the session to be approved and decision webhook to send response
- Now you can now use the following endpoints to query the document info:
- GET /sessions/{sessionId}/media
- GET /attempts/{attemptId}/media
- GET /media/{mediaId}
Step-by-step overview of the PoA Extraction flow
PoA Extraction step 1: submit a session using the POST /sessions endpoint
See the POST /sessions section for detailed overview of how to create a session.
PoA Extraction step 2: make a POST /sessions/{sessionId}/media request
You can use this endpoint to send any number of image files (also for purposes other than PoA Extraction),
but you need to upload them one at a time. Also, if you post several image files, make sure that the
value of image.context
parameter of the image relevant to the PoA Extraction flow
is "document-front", otherwise the PoA Extraction flow will not work.
Request
Request method: POST
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT
: string
(required) = API key
X-HMAC-SIGNATURE
: string
(required) = Request body signed with the shared secret key
Content-Type
: application/json
Request properties explained
image
:object
(required)context
:string
(required) In this case, it must be "document-front"content
:string
(required) base64 encoded image (.jpg, .jpeg, .png, .heif, .heic, .webp and .pdf formats are supported)
Sample request body
curl -X POST \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53' \
-d '{
"image": {
"context": "document-front",
"content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII="
}
}'
PoA Extraction step 3: update the session status to "submitted"
Use the PATCH sessions/{sessionId} endpoint to update the session status to "submitted". See the endpoint's description for detailed overview of how to update the session status.
Once done, an event webhook with submitted status will be sent. See the "Verification webhooks" section in Event webhooks for more info.
PoA Extraction step 4: wait for session approval and decision webhook response
As soon as the session is approved, the decision webhook will send an approved response. This response will include the session status, as well as all the data that was extracted from the PoA document.
Webhook payload
Request properties explained
status
:string
Status of the responseverification
:object
Verification request decision objectid
:string | null
UUID v4 which identifies the verification sessioncode
:integer
Verification response code, one of 9001, 9102, 9103, 9104, 9121. See here for more information about decision codesperson
:object
List of verified person's datagender
:string | null
(one of M, F ornull
) Person's genderidNumber
:string | null
National identification numberfirstName
:string | null
Person's first name as written on the document, if availablelastName
:string | null
Person's last name.null
unless prefilled by the customeraddresses
:array
Array of person's addressesfullAddress
:string | null
Person's full address
citizenship
:string | null
Person's citizenshipdateOfBirth
:string | null
Person's date of birthnationality
:string | null
Person's nationalityyearOfBirth
:string | null
(YYYY-MM-DD) Person's date of birthplaceOfBirth
:string | null
Person's place of birthpepSanctionMatch
:string | null
Legacy field, may not be up-do-date, should be ignored
reason
:string | null
Reason of failed verificationstatus
:string | null
Verification status, one ofapproved
,resubmission_requested
,review
,declined
,expired
,abandoned
comments
:array
(Deprecated)document
:object
List of data about the verified documenttype
:string | null
Document typenumber
:string | null
Document number, [a-zA-Z0-9] characters onlycountry
:string | null
ISO-2 Document countryvalidFrom
:string | null
Document is valid from datevalidUntil
:string | null
Document is valid until date
reasonCode
:string | null
Reason code of failed Verification. (See Response and error codesvendorData
:string | null
End-user-specific data string, max 1000 characters long, created by the customer. Sent back unmodified via API responses and webhooks, or asnull
if not providedendUserId
:string | null
End-user-specific UUID, created by the customer. Sent back unmodified via API responses and webhooks or asnull
if not provideddecisionTime
:string | null
Timestamp of the decision. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SS.SSSSSS+Timezone OffsetacceptanceTime
:string | null
Timestamp of the session generation. Combined ISO 8601 date and time in UTC YYYY-MM-DDTHH:MM:SSS+Timezone OffsetadditionalVerifiedData
:object
Data which has been optionally verified for sessionproofOfAddress
:object
Proof of address data. Optional, available only if the name match check has been enabled for the integrationnameMatch
:boolean
Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float
Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.
technicalData
:object
Technical dataip
:string | null
IP of the device from which the verification was made
Sample request
{
"status": "success",
"verification": {
"id": "ab1c2345-678d-4e3b-98a3-a75b00b715kj",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"firstName": "Jane Doe",
"lastName": "null",
"addresses": [
{
"fullAddress": "Jaan Koorti 777, 99999 Tallinn, Estonia"
}
],
"citizenship": null,
"dateOfBirth": null,
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": null,
"number": null,
"country": null,
"validFrom": "2022-11-25",
"validUntil": null
},
"reasonCode": null,
"vendorData": null,
"endUserId": "fa820aba-019f-455a-ae81-cfca8075bc3f",
"decisionTime": "2023-01-23T10:31:05.293000Z",
"acceptanceTime": "2023-01-23T10:25:40.026Z",
"additionalVerifiedData": {
"proofOfAddress": {
"nameMatch": true
"nameMatcPercentage": "100.00"
},
},
},
"technicalData": {
"ip": null
}
}
PoA Extraction step 5: use endpoints to query PoA document info
When the steps above have been successfully completed, you can use the following endpoints to query the document info:
- GET /sessions/{sessionId}/media - returns list of media objects and address media
with the
sessionId
- GET /attempts/{attemptId}/media - returns list of media objects and address media
with the
attemptId
GET /media/{mediaId} - returns a media file with the
mediaId
Note: to find the relevant
attemptId
, check theattemptId
parameter in the Event webhooks.
Optional Proof of Address name match check
In order to do the Proof of Address name match check, you can add the optional parameters person.firstName
and
person.lastName
to the POST /sessions request payload.
If the check has been enabled, and you have sent us the first name and last name
data, the check will be performed. The results are displayed in decision webhook response, in
additionalVerifiedData.proofOfAddress
object, more specifically in proofOfAddress.nameMatch
and
proofOfAddress.nameMatchpercentage
strings. If the check has been enabled, but you do not send us the name data,
the strings will be null
.
Sample POST /sessions request payload to do the optional name match check
Request method: POST
Media type: application/json
Type: object
Headers:
X-AUTH-CLIENT
: string (required)
= API key
Content-Type
: application/json
curl -X POST \
--url '/v1/sessions/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
},
}
}'
Sample decision webhook payload
The explanation and sample below show only the part of the payload that is relevant to the name match check. To see the full decision webhook response related to Proof of Address check, see the PoA Extraction Webhook payload section above.
Request properties explained
status
:string
Status of the responseverification
:object
Verification request decision object- ...
additionalVerifiedData
:object
Data which has been optionally verified for sessionproofOfAddress
:object
Proof of address data. Optional, available only if the name match check has been enabled for the integrationnameMatch
:boolean
Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float
Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.
- ...
Sample response
{
"status": "success",
"verification": {
...
"additionalVerifiedData": {
"proofOfAddress": {
"nameMatch": true
"nameMatcPercentage": "100.00"
},
},
},
...
}
INE Biometric Database Verification
Veriff INE Biometric Database Verification aka INE Biometric Validation is a check required for establishing identity in the Mexican market.
INE Biometric Validation prerequisites
- Integration configured on the Veriff side to support the check
- A verification session generated for the end-user
- End-user has given consent to pass their image to conduct the INE Biometric Validation check
INE Biometric Validation flow
- Create a identity verification session for the end-user. Make sure to include the consent.
- Collect and pass the end-user's data and media:
- If using the SDK solution, direct the end-user to the flow and wait for them to get approved
- If you have collected end-user's data and images yourself, pass them using the API endpoints
- Veriff verifies the end-user
- Check the verification results from decision webhook and/or GET /decision API call response
How to add the consent to the session?
When generating a session for INE Biometric Database Verification purposes, in the verification
object include the consents
array with type: ine
and approved: true
attributes (as shown below).
true
is mandatory to start the INE Biometric Validation. If false
or missing, the session is not created.
Below is an excerpt from the request payload, to highlight the relevant attributes. For full view of the payload, see the POST /sessions documentation.
curl -X POST \
--url '/v1/sessions/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"callback": "https://veriff.com",
"consents": [
{
"type": "ine",
"approved": true
}
],
...
}
}'
How to find results in the decision webhook?
You will find the INE Biometric Validation check results in the decision webhook request payload, as
additionalVerifiedData.ineBiometricRegistryValidation
object.
Below is an excerpt from the request payload, to highlight the relevant attributes. For full view of the payload, see the decision webhook documentation.
Request properties explained
status
:string
Status of the responseverification
:object
Verification request decision objectadditionalVerifiedData
:object
Data which has been optionally verified for sessionineBiometricRegistryValidation
:object
INE Biometric Database Verification check object. Optional, available only when the INE Biometric Validation check has been enabled for the integrationfaceMatch
:boolean | null
Indicates if the person's selfie image is a match with their image in the registry. This decision is made based on the value returned infaceMatchPercentage
(see below)null
if the check could not be completedfaceMatchPercentage
:integer | null
Indicates the level of similarity the system thinks the matched images have, in the range of 0-100. Values ≥85 indicate a match; values <85 indicate that images do not match.null
if the check could not be completedresponseStatus
:string | null
Indicates the response received from the service provider. One ofsuccess
orfailure
; ornull
if the check could not be completed
Sample request
{
"status": "success",
"verification": {
...
"additionalVerifiedData": {
"ineBiometricRegistryValidation": {
"faceMatch": true,
"faceMatchPercentage": 89,
"responseStatus": "success"
},
...
},
...
}
}
How to find results in the GET /decisions response?
You will find the INE Biometric Validation check results in the GET /decision API call response, as
additionalVerifiedData.ineBiometricRegistryValidation
object.
Below is an excerpt from the response payload, to highlight the relevant objects. For full view of the payload, see the GET /decisions response documentation.
Response properties explained
status
:string
Status of the responseverification
:object
Verification request decision objectadditionalVerifiedData
:object
Data which has been optionally verified for sessionineBiometricRegistryValidation
:object
INE Biometric Database Verification check object. Optional, available only when the INE Biometric Validation check has been enabled for the integrationfaceMatch
:boolean | null
Indicates if the person's selfie image is a match with their image in the registry. This decision is made based on the value returned infaceMatchPercentage
(see below).null
if the check could not be completedfaceMatchPercentage
:integer | null
Indicates the level of similarity the system thinks the matched images have, in the range of 0-100. Values ≥85 indicate a match; values <85 indicate that images do not match.null
if the check could not be completedresponseStatus
:string | null
Indicates the response received from the service provider. One ofsuccess
orfailure
; ornull
if the check could not be completed
Sample response
{
"status": "success",
"verification": {
...
"additionalVerifiedData": {
"ineBiometricRegistryValidation": {
"faceMatch": true,
"faceMatchPercentage": 89,
"responseStatus": "success"
},
...
},
...
}
}
Reference Info, Codes, Tables
Verification session status and decision codes
Session status
Session Status | Code | Sent by | Description |
---|---|---|---|
Started |
7001 | Event webhook | The end-user has started their session and landed in our verification flow.No decision is available yet. |
Submitted |
7002 | Event webhook | The end-user has submitted the requested data in the verification flow.No decision is available yet. |
Approved |
9001 | Decision webhook | The end-user was verified. The verification process is complete.
Accessing the sessionURL again will show the end-user that nothing is to be done here. |
Declined |
9102 | Decision webhook | The end-user has not been verified. The verification process is complete. Either it was a fraud case or some other severe reason that the end-user could not be verified. You should investigate the session further and read the reason and decision codes. If you decide to give the end-user another try, you need to create a new session.. |
Resubmission aka resubmission_requested |
9103 | Decision webhook | Resubmission has been requested. The verification process has not been completed.
Something was missing from the end-user, and they need to go through the flow once more. The same sessionURL
can and should be used for this purpose. |
Expired/Abandoned |
9104 | Decision webhook | Verification has been expired (a session will expire 7 days after having been created
unless it gets a conclusive decision before that). The verification process is complete. If the end-user started the verification process, the response shows abandoned . If the end-user has never
accessed the verification, the status will be expired . If you decide to give
the end-user another try, you need to create a new session. |
Review |
9121 | Decision webhook | Note that this status is sent only when you have implemented the fully automated verification
flow.Review status is issued whenever the automation engine could not issue a conclusive decision
and the verification session needs to be reviewed by a human on your side. |
Responses 9001, 9102, 9121
and 9104
are conclusive responses. The session is closed and the sessionURL
is
not available for the end-user.
Response 9103
is an inconclusive response. The session remains open until you receive one of the above
conclusive responses. The session is re-opened for the end-user, accepting a new attempt.
Additional info can be found in our Knowledge base article [↗] (requires a login to the Veriff environment)
Verification decision: declined
This table contains values for verification.reasonCode
in case the verfication.status
returned declined
.
If you do not see the reason code you received here, see also granular reason codes
Code | Description |
---|---|
102 | Suspected document tampering |
103 | Person showing the document does not appear to match document photo |
105 | Suspicious behaviour |
106 | Known fraud |
108 | Velocity/abuse duplicated end-user |
109 | Velocity/abuse duplicated device |
110 | Velocity/abuse duplicated ID |
112 | Restricted IP location |
113 | Suspicious behaviour - Identity Farming |
Verification decision: resubmission required
This table contains values for verification.reasonCode
in case the verfication.status
returned resubmission_requested
.
If you do not see the reason code you received here, see also granular reason codes
Note about the number of resubmissions: one user can resubmit their data up to 9 times. This means that the 10th attempt is automatically declined, and code 539 - Resubmission limit exceeded is sent. If you wish to allow the end-user to retry verification, you need to create a new session for them (see POST sessions for info).
Code | Description |
---|---|
201 | Video and/or photos missing |
204 | Poor image quality |
205 | Document damaged |
206 | Document type not supported |
207 | Document expired |
Common HTTP status codes
Code | Value | Description |
---|---|---|
200 | status : success , data |
Returned as a general "OK" code |
201 | status : created , data |
Returned when creating a session |
400 | status : fail code : 1102 |
Mandatory parameters are missing from the request See the troubleshooting codes table |
401 | status : fail |
Not authorized |
404 | status : fail |
Entry not found |
409 | status : conflict |
Returned when you try to upload media to a session that was already updated to submitted status |
500 | status : fail |
Something went wrong |
Credentials and authorization codes
Code | Description |
---|---|
1801 | Mandatory X-AUTH-CLIENT header containing the API key is missing from the request |
1802 | API key is not a valid UUID |
1803 | Integration with the API key was not found |
1804 | Integration with the API key is not active |
1812 | Signature is not a valid SHA256 hash |
1813 | Signature does not match the SHA256 hash of query ID and integration API secret |
1814 | Signature does not match the SHA256 hash of request body and integration API secret |
1818 | Signature does not match the HMAC-SHA256 of query ID and integration API secret |
1819 | Signature does not match the HMAC-SHA256 of request body and integration API secret |
Some troubleshooting codes
Code | Description |
---|---|
1001 | Query ID must be between 20 and 40 symbols. |
1002 | Query ID must be a valid UUID V4 |
1003 | Query ID must be unique, it has already been used. |
1102 | Mandatory parameters are missing from the request. |
1104 | Request includes invalid parameters. |
1201 | Invalid timestamp. Timestamp must not be older than one hour. |
1202 | Timestamp format is incorrect. YYYY-MM-DDTHH:MM:S+Timezone Offset|Z or UTC. |
1203 | Invalid ISO 8601 date. Date needs to be in format YYYY-MM-DD. |
1301 | Requested features are not supported. |
1302 | Only HTTPS return URLs are allowed. |
1303 | Invalid status. |
1304 | Cannot transition to "$STATUS" status. |
1308 | ID number is missing. |
1309 | SSN validation requires person firstName + lastName OR fullName to be provided. |
1310 | "SSN validation requires person.dateOfBirth or address data to be provided. |
1400 | Image data not found. |
1401 | Image is not in valid base64. |
1402 | Image context is not supported. |
1403 | Image property is missing. |
1500 | vendorData field cannot be more than 1000 symbols. We require only non-semantic data to be submitted (UUID-s etc., that can not be resolved or used outside the customer's domain) |
1501 | vendorData must be a string. We require only non-semantic data to be submitted (UUID-s etc., that can not be resolved or used outside the customer's domain) |
2003 | Date of birth is not a valid date. |
2101 | Document number has to be between 6 and 9 characters. |
2102 | Document number may contain only characters and numbers A-Z, 0-9. |
2103 | Document type is not supported. |
2104 | Document from provided country is not supported. |
Granular reason codes
The granular reason codes (hereinafter the GRC) mentioned here are subject to custom configuration on integration level, meaning that you may or may not receive all the reason codes listed here.
GRC verification decision: declined
This table contains values for verification.reasonCode
in case the verfication.status
returned declined
.
Code | Description |
---|---|
101 | Physical document not used |
102 | Suspected document tampering |
103 | Person showing the document does not appear to match document photo |
105 | Suspicious behaviour |
106 | Known fraud |
108 | Velocity/abuse duplicated end-user |
109 | Velocity/abuse duplicated device |
110 | Velocity/abuse duplicated ID |
112 | Restricted IP location |
113 | Suspicious behaviour - Identity Farming |
120 | Person on the portrait does not appear to match reference photo |
121 | User ID missing |
122 | No reference found |
123 | Unable to pass registry checks |
126 | Potential PEP match |
127 | Face match with blocklist |
502 | Multiple parties present in session |
503 | Attempted deceit |
504 | Attempted deceit, device screen used |
505 | Attempted deceit, printout used |
507 | Presented document tampered, data cross reference |
508 | Presented document tampered, document similarity to specimen |
509 | Person showing the document does not match document photo |
510 | Presented document type not supported |
511 | Presented document expired |
515 | Attempted deceit, device screen used for face image |
526 | Attempted deceit, photos streamed |
527 | Unable to collect proof of address data |
528 | Proof of address issue date too old |
530 | Person is under 13 years old |
531 | Person is under 14 years old |
532 | Person is under 16 years old |
533 | Person is under 18 years old |
534 | Person is under 20 years old |
535 | Person is under 21 years old |
536 | Person is under 25 years old |
537 | Unable to perform document media portrait cropping |
539 | Resubmission limit exceeded |
540 | Low confidence score for the session |
541 | Name on document does not match with name in session initialisation data |
542 | Unable to validate CPF |
543 | Reference face image has poor quality |
544 | Regisry did not respond |
545 | Reference image missing |
546 | Face image quality insufficient |
547 | Face missing |
548 | Attempted deceit, with face reference missing |
549 | NFC validation failed |
GRC verification decision: resubmit
This table contains values for verification.reasonCode
in case the verfication.status
returned resubmission_requested
.
Code | Description |
---|---|
203 | Full document not visible |
602 | Presented document type not supported |
603 | Video missing |
605 | Face image missing |
606 | Face is not clearly visible |
608 | Document front missing |
609 | Document back missing |
614 | Document front not fully in frame |
615 | Document back not fully in frame |
619 | Document data not visible |
620 | Presented document expired |
621 | Document annulled or damaged |
625 | Unable to collect surname |
626 | Unable to collect first names |
627 | Unable to collect date of birth |
628 | Unable to collect issue date |
629 | Unable to collect expiry date |
630 | Unable to collect gender |
631 | Unable to collect document number |
632 | Unable to collect personal number |
633 | Unable to collect nationality |
634 | Unable to collect home address |
635 | Document and face image missing |
636 | Presented document not real, screen used |
637 | Presented document not real, printout used |
640 | Person did not give consent |
641 | Multiple Faces Detected |
642 | Multiple Documents Uploaded |
643 | Unable to crop face image from a document front |
644 | Unable to collect Identificador de Ciudadano (INE) |
645 | Resubmit - Unable to collect OCR (IFE) |
646 | Unable to estimate age |
647 | Document not recognised |
648 | Technical issues |
649 | Unable to collect foreigner information |
650 | Unable to collect process number |
651 | Unable to collect occupation information |
652 | Unable to collect employer information |
653 | Unable to collect residence permit type |
654 | Unable to collect driver's license number |
655 | Unable to collect additional name |
657 | Open passport image missing |
662 | Unable to collect document remarks |
Image context types
The context
parameter in the request and response payload basically describes what the image or video was taken of,
for example if the image/video is about the selfie (the end-users face), the document front or back, etc.
Veriff captures multiple images. The image with the -pre
suffix is the first one, and the one without is the second
image.
Identity verification process
Context label name | Description |
---|---|
face |
Returns the selfie picture |
face-pre |
Returns the selfie picture |
face-nfc |
Returns the selfie picture extracted from the document's NFC chip |
document-front |
Returns the picture of the ID document's front |
document-front-pre |
Returns the picture of the ID document's front |
document-front-qrcode |
Returns the picture of the ID document's front, to display the QR-code |
document-front-qrcode-pre |
Returns the picture of the ID document's front, to display the QR-code |
document-front-face-cropped |
Returns a cropped portrait image from a document |
document-back |
Returns the picture of the ID document's back |
document-back-pre |
Returns the picture of the ID document's back |
document-and-face |
Returns the selfie with the the ID document's front |
document-and-face-pre |
Returns the selfie with the the ID document's front |
document-back-barcode |
Returns the picture of the ID document's back, to display the barcode |
document-back-barcode-pre |
Returns the picture of the ID document's back, to display the barcode |
document-back-qrcode |
Returns the picture of the ID document's back, to display the QR-code |
document-back-qrcode-pre |
Returns the picture of the ID document's back, to display the QR-code |
registry-face |
Returns the selfie picture extracted from a third party registry |
face-reference |
Returns the selfie picture that is used as reference image |
Proof of Address verification process
Context label name | Description |
---|---|
address-front |
Returns the image of the address that's displayed on the Proof of Address document's front |
Video context types
Context label name | Description | Platform |
---|---|---|
selfid_video |
Returns one video of the whole session, comprising the selfie, document front and document back videos | Web flow and Native SDKs |
face-pre-video |
Returns the selfie video | only Native SDKs |
document-front-pre-video |
Returns the video of the document's front | only Native SDKs |
document-back-pre-video |
Returns the video of the document's back | only Native SDKs |
document-and-face-pre-video |
Returns the selfie video with the document's front | only Native SDKs |
document-back-barcode-pre-video |
Returns the selfie video with the document's back to display the document's barcode | only Native SDKs |
document-front-qrcode-pre-video |
Returns the selfie video with the document's front to display the document's QR-code | only Native SDKs |
document-back-qrcode-pre-video |
Returns the selfie video with the document's back to display the document's QR-code | only Native SDKs |
Supported document types for IDV
In the Identity Verification process, the request and response bodies can display the document
object.
This contains the type
string. The type
can be one of the following document types:
PASSPORT
ID_CARD
DRIVERS_LICENSE
RESIDENCE_PERMIT
VISA
If it's not possible to classify the document as one of the above, the response can show "type": "OTHER"
.
See also:
- request body of POST /sessions
- response body of GET /sessions/{sessionId}/decision
- response body of decision webhook
Document data fields
Abbreviation | Field name | Explanation |
---|---|---|
VIZ | Visual Inspection Zone | The data group of this zone includes the photograph, the document designation, personal data and the date of issue and validity of the document |
MRZ | Machine Readable Zone | The two to three lines where the information from the viewing zone is strung together with alphanumeric characters and the "<" symbol |
Barcode | The barcode or the QR code on the document | |
NFC | Near Field Communication | Document's NFC chip |
Media file mimetypes
In API responses, the mimetype
parameter indicates the format of the media file.
Possible values are:
image/jpg
image/jpeg
image/png
image/heic
image/heif
image/webp
image/pdf
video/mp4
video/webm
Reasons for different types of decisions
Preconditions for approval decisions
We give a positive conclusive decision (status approved, code 9001) when the end-user has provided us with:
- Photos and videos uploaded to us
- The data on the document is readable and matches throughout the document
- The end-user's portrait photo is recognizable
- The end-user on the portrait photo corresponds to the person on the document photo
- The document is valid (dates, etc.,) A positive decision means that the person was verified. The verification process is complete.
Accessing the KYC session URL again will tell the end-user that nothing more is to be done.
Reasons for negative conclusive decisions
We give a negative conclusive decision (status declined, code 9102) when:
- Physical document not used
- Suspected document tampering
- Person showing the document does not appear to match document photo
- Suspicious behaviour
- Velocity/abuse
- Known fraud
A negative decision means that the person has not been verified. The verification process is complete. Either it was a fraud case or some other severe reason that the person can not be verified. You should investigate the session further and read the "reason". If you decide to give the client another try you need to create a new session.
Reasons for inconclusive decisions
We give an inconclusive decision (status resubmission_requested, code 9103), when
- Video and/or photos missing
- Face not clearly visible
- Full document not visible
- Poor image quality
- Document damaged
- Document type not supported
- Document expired
Final decisions
You have the right to make the final decision about verifying an end-user even after they have completed the verification process with Veriff.
In order for you to make the final decision, we recommend you create an appropriate functionality in your back-end. This will enable you to either approve or reject applications after the person has completed Veriff’s verification session.
When you perform additional checks outside of Veriff’s service, it is necessary to have another layer of decision-making. The decision has to be motivated based on further checks or extra information independent of Veriff’s decision.
The additional verification details can be determined in accordance with your business needs and the amount of data and background information available to you about the end-user.
Potential use cases:
- Age checks
- Name validation checks
- An end-user is unable to pass verification as required, but their attempt is sincere and the document is legitimate
- An end-user has made multiple fraudulent attempts to verify and cannot pass Veriff's verification anymore
- You wish to restrict the end-user's access to your platform based on their earlier behavior
Veriff provides a more standardized solution where unconventional end-user behavior is not deferred to for the benefit of overall decision quality.
Storing verification media
For businesses which are regulated by various KYC and AML laws and rules, storing proof of the end-user's verification is often a requirement. While Veriff stores and holds the end-user's media - photos and videos - it might also be mandatory and more convenient for the business to store this media internally.
Downloading the photo and video files
- You need to get the
sessionId
of a session you want to download the media for. This can be found from the decision webhook (verification.id
parameter), which is automatically sent after a decision has been made for a verification session. - With the
sessionId
, make a GET request to /sessions/{sessionId}/media endpoint. - From there, you will find a
mediaId
for every media file we have stored. - With the
mediaId
-s, you can make a request to GET /media/{mediaId} endpoint to get the media file in .jpeg or .mp4 format.
Glossary
Term | Context | Definition | Additional info | |
---|---|---|---|---|
API Key | Public API | A unique identifier of an integration and a required parameter for authentication. It is used to create the X-AUTH-CLIENT header value for API requests. |
You can find it in Station > Integration's page (requires a Station login). Occasionally, referred to as the API public key or Publishable key. |
|
API request | Public API | A message sent to a server asking for the API to provide service or information. | Also referred to as the API call. | |
API URL | Public API | An address that allows you to access an API and its various features. It consists of a BaseURL and an Endpoint. | Also referred to as the API URL path. | |
Attempt ID | Public API, Webhooks |
An UUID v4 of a specific attempt. You can find its value in your GET /sessions/{sessionId}/attempts response, as verification.id .
|
In the API requests' context, an "attempt" is one step (uploading required data
and getting a decision) inside a verification session, and it can be made several times during
a verification session. This means that calling the
GET /sessions/{sessionId}/attempts can return several
verification objects, each one with a unique id value.
|
|
BaseURL | Public API |
A "base address" for the specific API that you’re using. Used to create the API URL value for API requests. |
Found in Station > Integration page (requires a Station login). | |
Body | Public API, Webhooks | Data inside the request and response payloads in an API request. | A GET request's payload does not contain a body. | |
Callback URL | Public API |
URL address of the page where the end-user is sent after they have completed the web
verification flow You can find its value in the response payload of your
POST /sessions, as verification.callback .
|
If the callback URL is not specified for the session, the end-user will be redirected to
integration's default callback URL, which is visible in the Veriff environment >
Integration > Settings tab. Changing the value in the POST /sessions request body will
overwrite the default callback URL, but it will not change the callback URL that is visible
in the Veriff environment This does not yet contain any verification or decision info. See here [↗] for more info about how to set it up. Also referred to as the redirect URL. |
|
Customer | General | Veriff's customer who is using our verification services. | Occasionally, referred to as the vendor | |
Content-type header | Public API | Indicates the media type of the resource, in Veriff's context, usually "application/json". | ||
Decision code | General | Numeric value representing the decision given to a verification session. | See the Verification session status and decision codes for more info. | |
End-user | General | User of Veriff's customer's solution, the person who goes through the verification flow (aka the end-user flow). | ||
endUserId
|
General, Biometric Authentication |
A unique uuid created by the customer for their end-user. It is recommended for Biometric
Authentication solutions, especially if you are not sending the vendorData field, but can be used
for other solutions as well. It is always retruned unmodified in webhooks and public API calls,
or as null if not provided.
|
It must be uuid , no text or .json values are allowed.
It is stored by the customer, but also by Veriff for biometric authentication purposes. It must be
usable only inside customer's environment and in relation to only the specific end-user. It is a great
alternative to vendorData , especially if you are already using the UUID format to create
unique end-user identifiers.
|
|
Endpoint | Public API |
A specific “point of entry” in an API. You attach these to the end of your BaseURL,
thus completing the API URL. The results that you'll get from the API request will depend on
the Endpoint you attach. |
You can find a list of endpoints in the Endpoints section. | |
Granular Reason Code | General | It is a kind of code which is sent depending on the configuration of the client's integration. | See the Granular reason codes table for more info. | |
Headers | Public API | Mandatory elements in the API requests, containing the metadata. | ||
IDV | General | Abbreviation of Identity Verification. | ||
Integration | Station | An environment created according to client's needs to carry out, manage and observe verifications. | Client can find the list of their integrations in Station > Integrations page on the top of the page (requires a Station login. | |
Live Integration | General | Integration which is created as per your requirements. It is used for production and verification sessions created will count towards paid usage. | For live integration sessions, the sessions' statuses are set automatically. You need to define the Webhook decisions URL in Station (see here for instructions). | |
Payload | Public API, Webhooks, SDK | The data that you send when you make an API request, or that you receive when you get a response. | In the API requests context, the hashed hex encoded payload is signed with the shared secret key to generate the X-HMAC-SIGNATURE. | |
PoA | General | Abbreviation of Proof of Address. | See the article [↗] in the Knowledge Base for more info. | |
Reason code | General | Numeric value representing the reason for rejecting a verification session or for asking it to be resubmitted. | See the tables here for more info. | |
Session status | General | A label describing the status of a verification session. | See the table here for more info. | |
Session ID | Public API, Webhooks |
A unique identifier of a verification session. It is automatically created as soon as you create a session. You can find its value in the response payload of your POST /sessions, as verification.id .
|
In the API requests' context, one verification session comprises many steps (uploading data, uploading images, getting a decision, etc.). You can call several endpoints using the same session ID, to get all kinds of different data from that specific session. | |
sessionToken
|
Public API |
Session-specific token for a verification session. You can find its value in the response payload of the POST /sessions, as verification.sessionToken .
|
It is a JSON Web Token (JWT) that consists of the session ID and the session creation timestamp.
It should always have the variable max length type and must be able to accept data up to 8KB. |
|
Session URL | Public API, SDKs |
A combination of the base URL and the sessionToken , created as soon as a
session is started.You can find its value in the response payload of your POST /sessions, as verification.url .
|
This where the end-user is directed to go through the verification flow,
and it is unique for each verification session. |
|
Shared secret key | Public API | Required parameter for authentication, used to sign the payload to create the X-HMAC-SIGNATURE for API requests. |
This is a secret credential. You can find it in Station > Integration's page
(requires a Station login). Occasionally, referred to as the API private key or the Private key. |
|
Test Integration | General | Integration which is automatically created for every client who onboards with Veriff. It is used for development purposes, and verification sessions that are created will not count towards paid usage. | Veriff will not provide statuses for sessions created in test integration, you need to set them manually in the Station (see here for instructions). The Webhook decision URL is automatically created. | |
UUID
|
General | Abbreviation of the Universal Unique Identifier. It is a 128-bit value used to uniquely identify an object or entity on the internet. Must meet the regular expression pattern [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}. | ||
UUID v4
|
General |
It is an UUID (see above) which has been created using a random number generator. In Veriff context,
whenever a UUID is needed, it is the v4.
|
||
vendorData
|
General | A unique identifier of the end-user, created by the customer. |
It can be max 1,000 characters long and contain only non-semantic data, for example UUID-s etc., that
can not be resolved or used outside your systems or environments. Veriff returns it unmodified in webhooks
and API response payloads, or as null if it has not been provided. It has many use-cases, but it is
a recommended field to improve fraud mitigation solutions. It is an alternative to endUserId
if you have been creating the unique end-user identifiers in some non-UUID format.
See this article[↗] for more
info (requires a signin to the Veriff environment).
|
|
Veriff Environment | General | Veriff customer back-office, a dashboard where the customers can see their end-users' verification data. Also referred to as Veriff Customer Portal, Veriff Station or Veriff Hub. |
See an introductory video here[↗]. Depending on your setup, you may be required to access the environment via station.veriff.com or hub.veriff.com. Please check your sign-up email to make sure that you log in via correct address. |
|
Verification flow | General | A process where the end-user submits the data required to get verified. | Also referred to as the end-user flow. | |
Verification session | General | One verification session from start to end, i.e., from the moment a session is created until the moment a conclusive decision (“approved”, “declined”, “expired”/”abandoned”) is granted. | Each verification session receives an unique ID, aka the session ID used in the API request endpoints. | |
Verification session lifecycle | General | Umbrella term for the whole process of completing a verification process, comprising the stages completed by the client, the end-user, and Veriff. | ||
Webhook | Public API | An event-triggered API, meaning that rather than sending information or performing a function as a response to an application's request, it performs this when a certain trigger event happens. | There are different types of webhooks, see the Webhooks section for more info. | |
X-AUTH-CLIENT header | Public API | A mandatory header field in API requests, required to identify the request sender. Its value is the API Key (see above). | ||
X-HMAC-SIGNATURE header | Public API |
A mandatory header field in API requests, required to authenticate the request sender. Its value is a HMAC-SHA256 hex encoded hashed value of the request payload that has been signed using a shared secret key known to both the sending and receiving party. |
See the relevant API request in the API Reference section for more details about which payload to encode, and the X-HMAC-SIGNATURE section for more info about the signature itself. | |
X-SIGNATURE Legacy solution |
Public API | A solution used before the X-HMAC-SIGNATURE header was implemented (see above). |