Introduction
Shufti Pro offers multiple API methods to help you build business processes powered by the Shufti Pro API. While Shufti Pro API is organized around REST, it accepts form-encoded request bodies, returns JSON-encoded responses and uses standard HTTP response codes and authentication. Our API can help automate your business processes through by providing the following services:
- KYC Identity Verification
- Video KYC Identity Verification
- Biometric Verification
- Phone (2FA)
- AML Background Checks
- KYB (Know Your Business)
- OCR For Business
Getting Started
Before getting started, make sure you have the following:
Shufti Pro Account. This is your individual user account to access the Shufti Pro’s REST API and back-office. To set up your Shufti Pro account, click here.
API Keys. Shufti Pro API uses API keys to authenticate requests. You can view your API keys in the settings of your back-office. To get your API keys, click here.
Authorization
Shufti Pro API uses API keys to authenticate requests. You can view and manage your API keys in your Shufti Pro Backoffice. Authorization to API is performed via HTTP Basic Auth & Access Token. The verification request will fail without authorization.
BASIC AUTH
BASIC AUTH
/POST / HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
{
"reference" : "1234567",
"callback_url" : "http://www.example.com/",
"email" : "[email protected]",
"country" : "GB",
"language" : "EN",
"verification_mode" : "any",
"face" : {
"proof" : ""
}
}
<?php
$url = 'https://api.shuftipro.com/';
$client_id = 'YOUR-CLIENT-ID';
$secret_key = 'YOUR-SECRET-KEY';
$verification_request = [
"reference" => "ref-".rand(4,444).rand(4,444),
"callback_url" => "https://yourdomain.com/profile/notifyCallback",
"email" => "[email protected]",
"country" => "GB",
"language" => "EN",
"verification_mode" => "any",
];
$verification_request['face'] = [
"proof" => ""
];
$auth = $client_id.":".$secret_key;
$headers = ['Content-Type: application/json'];
$post_data = json_encode($verification_request);
$response = send_curl($url, $post_data, $headers, $auth);
function send_curl($url, $post_data, $headers, $auth){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return json_decode($body,true);
}
echo $response['verification_url'];
let payload = {
reference : `SP_REQUEST_${Math.random()}`,
callback_url : "https://yourdomain.com/profile/sp-notify-callback",
email : "[email protected]",
country : "GB",
language : "EN",
verification_mode : "any",
}
payload['face'] = {
proof : ""
}
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY");
fetch('https://api.shuftipro.com/', { method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token
},
body: JSON.stringify(payload)}).then(function(response) {
return response.json();
}).then(function(data) { return data; });
import requests, base64, json, hashlib
from random import randint
url = 'https://api.shuftipro.com/'
client_id = 'YOUR-CLIENT-ID'
secret_key = 'YOUR-SECRET-KEY'
verification_request = {
"reference" : "ref-{}{}".format(randint(1000, 9999), randint(1000, 9999)),
"callback_url" : "https://yourdomain.com/profile/notifyCallback",
"email" : "[email protected]",
"country" : "GB",
"language" : "EN",
"verification_mode" : "any"
}
verification_request['face'] = {
"proof" : ""
}
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"},
data=json.dumps(verification_request))
json_response = json.loads(response.content)
print('Verification URL: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
require 'open-uri'
url = URI("https://api.shuftipro.com/")
CLIENT_ID = "YOUR-CLIENT-ID"
SECRET_KEY = "YOUR-SECRET-KEY"
verification_request = {
reference: "Ref-"+ (0...8).map { (65 + rand(26)).chr }.join,
callback_url: "https://yourdomain.com/profile/notifyCallback",
email: "[email protected]",
country: "GB",
language: "EN",
redirect_url: "http://www.example.com",
verification_mode: "any"
}
verification_request["face"] = {
proof: ""
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}"
request.body = verification_request.to_json
response = http.request(request)
puts response.read_body
Shufti Pro provides Authorization to clients through the Basic Auth header. Your Client ID will serve as your Username while the Secret Key will serve as your Password. The API will require this header for every request.
Fields | Required | Description |
---|---|---|
username | Yes | Enter Client ID as username. |
password | Yes | Enter your Secret Key as password. |
ACCESS TOKEN
ACCESS TOKEN
//POST / HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Bearer NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
{
"reference" : "1234567",
"callback_url" : "http://www.example.com/",
"email" : "[email protected]",
"country" : "GB",
"language" : "EN",
"verification_mode" : "any",
"face" : {
"proof" : ""
}
}
<?php
$url = 'https://api.shuftipro.com/';
$access_token = 'YOUR-ACCESS-TOKEN';
$verification_request = [
"reference" => "ref-".rand(4,444).rand(4,444),
"callback_url" => "https://yourdomain.com/profile/notifyCallback",
"email" => "[email protected]",
"country" => "GB",
"language" => "EN",
"verification_mode" => "any",
];
$verification_request['face'] = [
"proof" => ""
];
$headers = ['Content-Type: application/json', 'Authorization: Bearer ' . $access_token];
$post_data = json_encode($verification_request);
$response = send_curl($url, $post_data, $headers);
function send_curl($url, $post_data, $headers){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($html_response, $header_size);
curl_close($ch);
return json_decode($body,true);
}
echo $response['verification_url'];
let payload = {
reference : `SP_REQUEST_${Math.random()}`,
callback_url : "https://yourdomain.com/profile/sp-notify-callback",
email : "[email protected]",
country : "GB",
language : "EN",
verification_mode : "any",
}
payload['face'] = {
proof : ""
}
var token = "YOUR_ACCESS_TOKEN";
fetch('https://api.shuftipro.com/', { method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Bearer ' +token
},
body: JSON.stringify(payload)}).then(function(response) {
return response.json();
}).then(function(data) { return data; });
import requests, base64, json, hashlib
from random import randint
url = 'https://api.shuftipro.com/'
access_token = 'YOUR-ACCESS-TOKEN';
verification_request = {
"reference" : "ref-{}{}".format(randint(1000, 9999), randint(1000, 9999)),
"callback_url" : "https://yourdomain.com/profile/notifyCallback",
"email" : "[email protected]",
"country" : "GB",
"language" : "EN",
"verification_mode" : "any"
}
verification_request['face'] = {
"proof" : ""
}
response = requests.post(url,
headers={"Authorization": "Bearer %s" % access_token, "Content-Type": "application/json"},
data=json.dumps(verification_request))
json_response = json.loads(response.content)
print('Verification URL: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
require 'open-uri'
url = URI("https://api.shuftipro.com/")
ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
verification_request = {
reference: "Ref-"+ (0...8).map { (65 + rand(26)).chr }.join,
callback_url: "https://yourdomain.com/profile/notifyCallback",
email: "[email protected]",
country: "GB",
language: "EN",
redirect_url: "http://www.example.com",
verification_mode: "any"
}
verification_request["face"] = {
proof: ""
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer #{ACCESS_TOKEN}"
request.body = verification_request.to_json
response = http.request(request)
puts response.read_body
Shufti Pro provides Bearer Access Token Authorization method. Client can generate temporary access token using new access token endpoint. The shared token will be used to authorize API requests. The token shared with the client will be valid for 10 minutes and can be used once only.
Field | Required | Description |
---|---|---|
Authorization | Yes | Enter your authorization token. |
Off-site Verification without OCR
Every verification request received from the end-user or Shufti Pro customer is assessed on certain parameters (discussed in detail below) by Shufti Pro’s intelligent system. These parameters allow Shufti Pro to:
- Identify its customers.
- Check the authenticity of the client’s credentials.
- Read the client’s data.
- Decide what information is being sent to perform a certain verification.
Request Parameters
Herein it is essential to note that each service module is independent of the other and each one of them will be activated according to the nature of the request received from Shufti Pro’s client. Services can be used in combination including document, address, face, consent and phone verification as well as AML background checks.
Each verification service is optional. Shufti Pro can provide clients with a single service or multiple services depending on their requirements.
Verification Request
Off-site without OCR Verification Request
//POST / HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
// replace "Basic" with "Bearer in case of Access Token"
{
"reference" : "56745631",
"callback_url" : "http://www.example.com/",
"email" : "[email protected]",
"country" : "GB",
"language" : "EN",
"verification_mode" : "any",
"face": {
"proof": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII="
},
"document" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"additional_proof": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types" : ["id_card","driving_license","passport"],
"name" : {
"first_name" : "Johon",
"last_name" : "Livone"
},
"dob" : "1990-10-10",
"age" : 18,
"issue_date" : "2015-10-10",
"expiry_date" : "2025-10-10",
"document_number" : "1234-1234-ABC",
"gender" : ""
},
"address" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types" : ["id_card","bank_statement"],
"name" : {
"first_name" : "Johon",
"last_name" : "Livone"
},
"issue_date" : "2015-10-10",
"full_address" : "Candyland Avenue",
"address_fuzzy_match":"1"
},
"consent":{
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types" : ["printed"],
"text" : "My name is John Doe and I authorise this transaction of $100/- Date: July 15, 2020"
},
"background_checks": {
"name" : {
"first_name" : "John",
"middle_name" : "Middleman",
"last_name" : "Doe"
},
"dob": "1980-11-12"
}
}
<?php
$url = 'https://api.shuftipro.com/';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
// $access_token = 'YOUR-ACCESS-TOKEN';
$verification_request = [
'reference' => 'ref-'.rand(4,444).rand(4,444),
'country' => 'GB',
'language' => 'EN',
'email' => '[email protected]',
'callback_url' => 'https://yourdomain.com/profile/notifyCallback',
'verification_mode' => 'any',
];
//Use this key if you want to perform face verification
$verification_request['face'] = [
'proof' => base64_encode(file_get_contents('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg'))
];
//Use this key if want to perform document verification
$verification_request['document'] =[
'proof' => base64_encode(file_get_contents('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg')),
'name' => [
'first_name' => 'Your first name',
'last_name' => 'You last name',
'fuzzy_match' => '1'
],
'dob' => '1992-10-10',
'age' => 18,
'document_number' => '2323-5629-5465-9990',
'expiry_date' => '2025-10-10',
'issue_date' => '2015-10-10',
'supported_types' => ['id_card','passport'],
"gender" => ""
];
//Use this key if you want to perform address verification
$verification_request['address'] = [
'proof' => base64_encode(file_get_contents('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg')),
'name' => [
'first_name' => 'Your first name',
'last_name' => 'You last name',
'fuzzy_match' => '1'
],
'full_address' => 'your address',
'address_fuzzy_match' => '1',
'issue_date' => '2015-10-10',
'supported_types' => ['utility_bill','passport','bank_statement']
];
//Use this key if you want to perform consent verification
$verification_request['consent'] =[
'proof' => base64_encode(file_get_contents('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg')),
'text' => 'some text for consent verification',
'supported_types' => ['handwritten'],
];
//Use this key if you want to perform aml/background checks verification
$verification_request['background_checks'] = [
'name' => [
'first_name' => 'Your first name',
'last_name' => 'You last name'
],
'dob' => '1992-10-10',
];
$auth = $client_id.":".$secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization : Bearer ' . $access_token);
$post_data = json_encode($verification_request);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $post_data, $headers, $auth); // remove this in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
// calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
$decoded_response = json_decode($response_data,true);
$event_name = $decoded_response['event'];
if(in_array($event_name, ['verification.accepted', 'verification.declined', 'request.received']) ){
if($sp_signature == $calculate_signature){
echo $event_name." :". $response_data;
}else{
echo "Invalid signature :". $response_data;
}
}else{
echo "Error : $response_data";
}
function send_curl($url, $post_data, $headers, $auth){ // remove this in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$curl_info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers,'body' => $body];
}
?>
import base64, requests, json, hashlib, urllib2
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
verification_request = {
'reference' : 'ref-{}{}'.format(randint(1000, 9999), randint(1000, 9999)),
'country' : 'GB',
'language' : 'EN',
'email' : '[email protected]',
'callback_url' : 'https://yourdomain.com/profile/notifyCallback',
'verification_mode' : 'any',
}
# Use this key if want to perform face verification
verification_request['face'] = {
'proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-face.jpg').read()).decode()
}
# Use this key if you want to perform document verification
verification_request['document'] = {
'proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').read()).decode(),
'additional_proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').read()).decode(),
'name' : {
'first_name' : 'Your first name',
'last_name' : 'Your last name',
'fuzzy_match' : '1'
},
'dob' : '1992-10-10',
'age' : 18,
'document_number' : '2323-5629-5465-9990',
'expiry_date' : '2025-10-10',
'issue_date' : '2015-10-10',
'supported_types' : ['id_card','passport'],
"gender" : ""
}
# Use this key if want to perform address verification
verification_request['address'] = {
'proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').read()).decode(),
'name' : {
'first_name' : 'Your first name',
'last_name' : 'Your last name',
'fuzzy_match' : '1'
},
'full_address' : 'your address',
'address_fuzzy_match' : '1',
'issue_date' : '2015-10-10',
'supported_types' : ['utility_bill','passport','bank_statement']
}
# Use this key if you want to perform consent verification
verification_request['consent'] = {
'proof' : base64.b64encode(urllib2.urlopen('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-consent-document.jpg').read()),
'text' : 'some text for consent verification',
'supported_types' : ['handwritten']
}
# Use this key if you want to perform AML/Background Checks verification
verification_request['background_checks'] = {
'name' : {
'first_name' : 'Your first name',
'last_name' : 'You last name'
},
'dob' : '1992-10-10'
}
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"},
data=json.dumps(verification_request))
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Get Shufti Pro Signature
sp_signature = response.headers.get('Signature','')
# Convert json string to json object
json_response = json.loads(response.content)
# Get event returned
event_name = json_response['event']
print (json_response)
if event_name == 'verification.accepted':
if sp_signature == calculated_signature:
print ('Verification accepted: {}'.format(response.content))
else:
print ('Invalid signature: {}'.format(response.content))
else:
print ("Error: {}".format(response.content))
var payload = {
reference : `SP_REQUEST_${Math.random()}`,
callback_url : "https://yourdomain.com/profile/sp-notify-callback",
redirect_url : "https://yourdomain.com/site/sp-redirect",
country : "GB",
language : "EN",
verification_mode : "any",
document : {},
address : {},
}
/*Get face sample proof Base64*/
convertImgToBase64URL('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-face.jpg').then(response=>{
payload['face'] = {
proof : response
}
})
//get Document proof base64
convertImgToBase64URL('https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg').then(response=>{
//Use this key if you want to perform document verification with OCR
payload['document'] = {
proof : response,
additional_proof : response,
name : {
first_name : 'Your first name',
last_name : 'You last name',
fuzzy_match : '1'
},
dob : '1992-10-10',
age : 18,
document_number : '2323-5629-5465-9990',
expiry_date : '2025-10-10',
issue_date : '2015-10-10',
supported_types : ['id_card','passport'],
gender : ""
}
//Use this key if you want to perform address verification with OCR
payload['address'] = {
proof : response,
name : {
first_name : 'Your first name',
last_name : 'You last name',
fuzzy_match : '1'
},
full_address : 'your address',
address_fuzzy_match : '1',
issue_date : '2015-10-10',
supported_types : ['utility_bill','passport','bank_statement']
}
//Use this key if you want to perform background checks verification
payload['background_checks'] = {
name : {
first_name : 'Your first name',
middle_name : 'Your middle name',
last_name : 'Your last name'
},
dob : '1994-10-03'
}
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/',
{
method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
},
body: JSON.stringify(payload)
})
.then(function(response) {
return response.json();
}).then(function(data) {
console.log(data)
return data;
});
})
/*METHOD USED TO Get image BASE 64 string*/
function convertImgToBase64URL(url){
return new Promise(function(resolve, reject) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'), dataURL;
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
dataURL = canvas.toDataURL('image/jpeg');
resolve(dataURL);
canvas = null;
};
img.src = url;
})
}
require 'uri'
require 'net/http'
require 'base64'
require 'json'
require 'open-uri'
url = URI("https://api.shuftipro.com/")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
# Sample image
SAMPLE_DOCUMENT_IMAGE = "https://raw.githubusercontent.com/shuftipro/RESTful-API-v1.3/master/assets/real-id-card.jpg"
verification_request = {
reference: "Ref-"+ (0...8).map { (65 + rand(26)).chr }.join,
callback_url: "https://yourdomain.com/profile/notifyCallback",
email: "[email protected]",
country: "GB",
language: "EN",
redirect_url: "http://www.example.com",
verification_mode: "any",
}
# Use this key if you want to perform document verification with OCR
verification_request["document"] = {
proof: Base64.encode64(open(SAMPLE_DOCUMENT_IMAGE).read),
supported_types: ["id_card","driving_license","passport"],
name: {
first_name: "Johon",
last_name: "Livone"
},
dob: "1990-10-10",
age: 18,
issue_date: "2015-10-10",
expiry_date: "2025-10-10",
document_number: "1234-1234-ABC",
gender: ""
}
# Use this key if you want to perform address verification with OCR
verification_request["address"] = {
proof: Base64.encode64(open(SAMPLE_DOCUMENT_IMAGE).read),
supported_types: ["id_card","bank_statement"],
name: {
first_name: "Johon",
last_name: "Livone"
},
issue_date: "2015-10-10",
full_address: "Candyland Avenue",
address_fuzzy_match: "1"
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}" # replace "Basic" with "Bearer" in case of access token
request.body = verification_request.to_json
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Off-site verification means that Shufti Pro will be provided with data to perform Identity verification.
In the verification request, Shufti Pro customer specifies the keys and data for the parameters to be verified. Next, Shufti Pro’s intelligently driven system verifies the provided documents for authenticity.
Shufti Pro offers following services in Off-site verification: (Face, Document, Address, Consent and Background Checks)
Parameters | Description |
---|---|
reference | Required: Yes Type: string Minimum: 6 characters Maximum: 250 characters Each request is issued a unique reference ID which is sent back to Shufti Pro’s client with each response. This reference ID helps to verify the request. The client can use this ID to check the status of already performed verifications. |
country | Required: No Type: string Length: 2 characters You may omit this parameter if you don't want to enforce country verification. If a valid country code is provided, then the proofs for document verification or address verification must be from the same country. Country code must be a valid ISO 3166-1 alpha-2 country code. Please consult Supported Countries for country codes. |
language | Required: No Type: string Length: 2 characters If the Shufti Pro client wants their preferred language to appear on the verification screens they may provide the 2-character long language code of their preferred language. The list of Supported Languages can be consulted for the language codes. If this key is missing in the request the system will select the default language as English. |
Required: No Type: string Minimum: 6 characters Maximum: 128 characters This field represents email of the end-user. |
|
callback_url | Required: No Type: string Minimum: 6 characters Maximum: 250 characters A number of server-to-server calls are made to Shufti Pro’s client to keep them updated about the verification status. This allows the clients to keep the request updated on their end, even if the end-user is lost midway through the process. |
verification_mode | Required: No Type: string Accepted Values: any, image_only, video_only This key specifies the types of proof that can be used for verification. In a “video_only” mode, Shufti Pro’s client can only send “Base64” of videos wherein formats of proofs should be MP4 or MOV. “any” mode can be used to send a combination of images and videos as proofs for verification. |
show_results | Required: No Type: string Accepted Values: 0, 1 Default Value: 1 If Value for this parameter is 1, verification result will be displayed. If the value of this parameter is set 0, verification results will not be shown. In case of offsite verification if show_results is set to 0, then a request.received callback is returned in case of a valid verification. |
decline_on_single_step | Required: No Type: string Accepted Values: 0, 1 Default Value: 1 When the value of this parameter is set to “1”, it declines the entire verification request when any one of the verification steps fails (and no further steps are verified). Note: All the Production Accounts created before 11 Jun 2020 will have default value set to 0. |
manual_review | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 This key can be used if the client wants to review verifications after processing from Shufti Pro has completed. Once the user submits any/all required documents, Shufti Pro returns a status of review.pending. The client can then review the verification details and Accept OR Decline the verifications from the back-office. |
enhanced_originality_checks | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 If enabled, this key will be used for performing a strict text edit check on the ID document and decline the verification request if the edited text is found. It will restrict the end-users to scan a QR code to continue the verification journey on mobile if the process is initiated from a Desktop device. This configuration will ensure quality image from the native camera to detect edited text on ID documents. |
face | Required: No Type: object This service key corresponds to Face Verification Service in which unique facial features of end-user are identified and verified in real-time. Example 1 { "proof" : "base_64_encoded_image"} for more details Face Service |
document | Required: No Type: object This service key corresponds to Document verification service in which the authenticity of identity documents submitted by end-users is checked. Once verified, these identity documents serve as proof of end-user’s identity. Example 1 {"proof" : "base_64_encoded_image" , "document_number": "ABC1234XYZ098", "issue_date": "2015-12-31", "expiry_date": "2025-12-31", "dob": "1990-12-31", "name": { "first_name" : "John", "last_name" : "Doe" } , "supported_types": ["id_card", "credit_or_debit_card", "passport"]} for more details Document Service |
address | Required: No Type: object This service key corresponds to Address Verification service in which the authenticity of an end-user's provided address is checked with the help of an authentic Identity document, Utility bill or bank statement Example 1 {"proof" : "base_64_encoded_image", "supported_types" : ["id_card","bank_statement"],"name" : {"first_name" : "John", "last_name" : "Doe" } ,"full_address": "Candyland Avenue" } for more details Address Service |
consent | Required: No Type: object This service key corresponds to Consent Verification services in which the consent provided by end-user for a certain action is cross-checked with the help of a handwritten document or customized printed document Example 1 {"proof" : "base_64_encoded_image","text" : "Hi, I am giving my consent"} for more details Consent Service |
phone | Required: No Type: object This service key corresponds to Phone Verification service of Shufti Pro. A customized code is sent to end-user on their phone number, that is sent back by end-user to verify their identity. Example 1 {"phone_number" : "+00000000000000","random_code" : "12345","text" : "Your Shuftipro verification code is "} for more details Phone Service |
background_checks | Required: No Type: object This service key corresponds to AML Screening service offered by Shufti Pro. An AML background check is performed for every end-user in this service against a financial risk database compiled by Shufti Pro Example 1 {"name" : {"first_name" : "John", "last_name" : "Doe"}, "dob" : "1990-12-31" } for more details Background Checks service |
Verification Response
Responses will contain the following parameters:
Sample Response
//Content-Type: application/json
//Signature: NmI4NmIyNzNmZjM0ZmNl
{
"reference": "17374217",
"event": "verification.accepted",
"verification_url": "",
"verification_result": {
"document": {
"name": 1,
"dob": 1,
"age": 1,
"expiry_date": 1,
"issue_date": 1,
"document_number": 1,
"document": 1,
"gender" : ""
},
"address": {
"name": 1,
"full_address": 1
}
},
"verification_data": {
"document": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
"document_number": "1456-0989-5567-0909",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"driving_license",
"passport"
],
"gender" : ""
},
"address": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"full_address": "3339 Maryland Avenue, Largo, Florida",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"bank_statement"
]
}
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
},
"additional_data": {
"document": {
"proof": {
"gender": "M",
"height": "183",
"country": "United Kingdom",
"authority": "HMPO",
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"country_code": "GBR",
"document_type": "P",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
"personal_number": "12345678910",
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
}
}
}
}
Parameters | Description |
---|---|
reference | Your unique request reference, which you provided us at the time of request, so that you can identify the response in relation to the request made. |
events | This is the request event which shows status of request. Event is changed in every response. Please consult Events for more information. |
error | Whenever there is an error in your request, this parameter will have the details of that error. |
token | This is the unique request token of the request. |
verification_result | This object will be returned in case of verification.accepted or verification.declined. This includes the results of each verification. 1 means accepted 0 means declined null means not processed Check verification.accepted and verification.declined responses in Events section for a sample response. |
verification_data | This object will be returned in case of verification.accepted or verification.declined. This object will include all the gathered data in a request process. Check verification.accepted and verification.declined responses in Events section for a sample response. |
info | This object will be returned in case of verification.accepted or verification.declined. It contains the following keys: Agent provides information about the device and browser of the end-user. Geolocation provides information about the geographical location of the end-user. For Details on info object go to Info |
additional_data | This object will be returned in case of verification.accepted or verification.declined. This object contains the additional data extracted by Shuftipro on the document. For Details on additional_data object go to Additional Data |
declined_reason | This parameter will have the reason due to which a verification has been declined, and is only returned in this case in the callback URL. |
declined_codes | This array contains status codes of all declined verification reasons. It will return only for verification.declined. |
services_declined_codes | This object contains status codes of declined reasons for each service separately. Each service object will contain an array of status codes for declined reasons specific to that service. It will return only for verification. declined. |
Verification Services
Shufti Pro is performing variety of verifications for its customers. Our diverse services suite allows us to validate the identity of users through facial verification, documents verification and address verification. We can also check the authenticity of customised documents like official IDs and perform background checks for AML compliance. A mix of various service modules can also be acquired to perform multifunctional verifications like facial and document verification can help you perform a thorough KYC procedure.
Face Service
Face service sample object
{
"face" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wDAP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"allow_offline" : "1",
"check_duplicate_request" : "1"
}
}
The face verifications of end-users are the simplest to perform.
Parameters | Description |
---|---|
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB Provide valid BASE64 encoded string. |
check_duplicate_request | Required: No Type: string Accepted Values: 0, 1 Default-Value: 0 This parameter is used to enable the duplicate account detection service. Face mapping technology identify duplicate faces across all customers through which duplicate accounts are detected. The duplicate account detection will be disabled if the value is 0 and enabled if the value is 1. |
Document Service
Document service sample object
{
"document" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"additional_proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types": ["id_card","driving_license"],
"name" : {
"first_name" : "Johon",
"last_name" : "Livone"
},
"dob" : "1990-10-10",
"age" : 18,
"issue_date" : "2015-10-10",
"expiry_date" : "2025-10-10",
"document_number" : "1234-1234-ABC",
"allow_offline" : "1",
"fetch_enhanced_data" : "1",
"backside_proof_required" : "0",
"gender":"M",
"show_ocr_form" : "1"
}
}
Shufti Pro provides document verification through various types of documents. The supported formats are passports, ID Cards, driving licenses and debit/credit cards. You can opt for more than 1 document type as well.
Parameters | Description |
---|---|
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB Provide valid BASE64 encoded string. |
additional_proof | Required: No Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB Provide valid BASE64 encoded string. |
supported_types | Required: No Type: Array All supported types are listed here Example 1 ["driving_license"] Example 2 ["id_card", "credit_or_debit_card", "passport"] |
dob | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 1990-12-31 |
age | Required: No Type: integer/array Allowed values are integers or array. The Age parameter allows the client to set a minimum and maximum limit for acceptance of a user. The minimum age is defined as min and the maximum is defined as max within this object. Example 18 For More Details Age |
document_number | Required: No Type: string Maximum: 100 chracters Allowed Characters are numbers, alphabets, dots, dashes, spaces, underscores and commas. Examples 35201-0000000-0, ABC1234XYZ098 |
issue_date | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 2015-12-31 |
expiry_date | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 2025-12-31 |
gender | Required: No Type: string Accepted Values: M,F,O,m,f,o Provide the gender which is given in the document. F: Female M: Male O: Others Example: M |
fetch_enhanced_data | Required: No Type: string Value Accepted: 1 Provide 1 for enabling enhanced data extraction for the document. Shufti Pro provides its customers with the facility of extracting enhanced data features using OCR technology. Now, instead of extracting just personal information input fields, Shufti Pro can fetch all the additional information comprising more than 100 data points from the official ID documents supporting 150 languages. For example height, place_of_birth, nationality, marital_status, weight, etc.(additional charges apply) Extrated data will be returned in object under the key additional_data in case of verification.accepted or verification.declined. For Details on additional_data object go to Additional Data |
name | Required: No Type: object In name object used in document service, first_name and last_name are required. Other fields are optional. Example 1 { "first_name" : "John", "last_name" : "Doe" } Example 2 { "first_name" : "John", "last_name" : "Doe", "fuzzy_match" : "1"} Parameters for name are listed here |
backside_proof_required | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 If the value of this parameter is set to 1, Shufti Pro will require the end-user to capture/upload both sides of the document to verify the identity. Enabling this parameter will also activate the front and back sides document match feature, which will verify if captured/uploaded front and back sides belong to the same document. |
verification_instructions | Required: No Type: Object This key allows clients to provide additional instruction for the service (document, document_two and address service). Such as if the client wants to allow paper-based, photocopied or laminated documents for verification. Example {"allow_paper_based" : "1"} For more details on Instructions Parameters click here |
show_ocr_form | Required: No Type: boolean Accepted Values: 0, 1 default value: 1 The default value for this is 1. If this is set to 0, the user will not be shown the OCR form to validate the extracted information. This can be used within the Document, Document Two, and Address service. This value can also be applied to all services collectively. However, preference will be given to the value set within the service. Note: Setting the value at 0 may cause data inaccuracy as the user does not have option to validate the extracted information. |
Document Two Service
Document Two service sample object
{
"document_two" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"additional_proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types": ["id_card","driving_license"],
"name" : {
"first_name" : "Johon",
"last_name" : "Livone"
},
"dob" : "1990-10-10",
"age" : 18,
"issue_date" : "2015-10-10",
"expiry_date" : "2025-10-10",
"document_number" : "1234-1234-ABC",
"allow_offline" : "1",
"fetch_enhanced_data" : "1",
"backside_proof_required" : "0",
"show_ocr_form" : "1"
}
}
Document Two Service is provided to verify the personal details of a user from more than 1 document e.g. If you have verified the DOB & Name of a user from their ID Card, you can use Document Two Service to verify the Credit Card Number of your customer.
Just like the “Document Service”, the supported formats for this service are also passports, ID Cards, driving licenses and debit/credit cards and more than one document type can be selected as well.
It goes without saying that provided document proofs should belong to the same person in order to verify the identity of the user.
Parameters | Description |
---|---|
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB Provide valid BASE64 encoded string. |
additional_proof | Required: No Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB Provide valid BASE64 encoded string. |
supported_types | Required: No Type: Array All supported types are listed here Example 1 ["driving_license"] Example 2 ["id_card", "credit_or_debit_card", "passport"] |
dob | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 1990-12-31 |
age | Required: No Type: string/array Allowed values are integers or array. The Age parameter allows the client to set a minimum and maximum limit for acceptance of a user. The minimum age is defined as min and the maximum is defined as max within this object. Example 18 For More Details Age |
document_number | Required: No Type: string Maximum: 100 chracters Allowed Characters are numbers, alphabets, dots, dashes, spaces, underscores and commas. Examples 35201-0000000-0, ABC1234XYZ098 |
issue_date | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 2015-12-31 |
expiry_date | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 2025-12-31 |
gender | Required: No Type: string Accepted Values: M,F,O,m,f,o Provide the gender which is given in the document. F: Female M: Male O: Others Example: M |
fetch_enhanced_data | Required: No Type: string Value Accepted: 1 Provide 1 for enabling enhanced data extraction for the document. Shufti Pro provides its customers with the facility of extracting enhanced data features using OCR technology. Now, instead of extracting just personal information input fields, Shufti Pro can fetch all the additional information comprising more than 100 data points from the official ID documents supporting 150 languages. For example height, place_of_birth, nationality, marital_status, weight, etc.(additional charges apply) Extrated data will be returned in object under the key additional_data in case of verification.accepted or verification.declined. For Details on additional_data object go to Additional Data |
name | Required: No Type: object In name object used in document service, first_name and last_name are required. Other fields are optional. Example 1 { "first_name" : "John", "last_name" : "Doe" } Example 2 { "first_name" : "John", "last_name" : "Doe", "fuzzy_match" : "1"} Parameters for name are listed here |
backside_proof_required | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 If the value of this parameter is set to 1, Shufti Pro will require the end-user to capture/upload both sides of the document to verify the identity. Enabling this parameter will also activate the front and back sides document match feature, which will verify if captured/uploaded front and back sides belong to the same document. |
verification_instructions | Required: No Type: Object This key allows clients to provide additional instruction for the service (document, document_two and address service). Such as if the client wants to allow paper-based, photocopied or laminated documents for verification. Example {"allow_paper_based" : "1"} For more details on Instructions Parameters click here |
show_ocr_form | Required: No Type: boolean Accepted Values: 0, 1 default value: 1 The default value for this is 1. If this is set to 0, the user will not be shown the OCR form to validate the extracted information. This can be used within the Document, Document Two, and Address service. This value can also be applied to all services collectively. However, preference will be given to the value set within the service. Note: Setting the value at 0 may cause data inaccuracy as the user does not have option to validate the extracted information. |
Address Service
Address service sample object
{
"address" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types" : ["id_card","bank_statement"],
"name" : {
"first_name": "Johon",
"last_name": "Livone"
},
"issue_date" : "2015-10-10",
"full_address" : "Candyland Avenue",
"address_fuzzy_match" : "1",
"backside_proof_required" : "0",
"show_ocr_form" : "1"
}
}
For address verification, a valid identity document is required with the same address printed on it as the one claimed by the end-user. The address can also be verified with the help of Utility Bills and Bank Statements.
Parameters | Description |
---|---|
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB |
supported_types | Required: No Type: Array Following is the list of supported types for address verification is here. Example 1 [ "utility_bill" ] Example 2 [ "id_card", "bank_statement" ] |
full_address | Required: Yes Type: string Minimum: 6 characters Maximum: 250 chracters Allowed Characters are numbers, alphabets, dots, dashes, spaces, underscores, hashes and commas. |
address_fuzzy_match | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 Provide 1 for enabling a fuzzy match for address verification. Enabling fuzzy matching attempts to find a match which is not 100% accurate. Default value will be 0, which means that only 100% accurate address will be verified. |
issue_date | Required: No Type: string Format: yyyy-mm-dd Provide a valid date. Example 2015-12-31 |
name | Required: No Type: object In name object used in document service, first_name and last_name are required. Other fields are optional. Example 1 { "first_name" : "John", "last_name" : "Doe" } Example 2 { "first_name" : "John", "last_name" : "Doe", "fuzzy_match" : "1"} Parameters for name are listed here |
backside_proof_required | Required: No Type: string Accepted Values: 0, 1 Default Value: 0 If the value of this parameter is set to 1, Shufti Pro will require the end-user to capture/upload both sides of the document to verify the identity. Enabling this parameter will also activate the front and back sides document match feature, which will verify if captured/uploaded front and back sides belong to the same document. |
verification_instructions | Required: No Type: Object This key allows clients to provide additional instruction for the service (document, document_two and address service). Such as if the client wants to allow paper-based, photocopied or laminated documents for verification. Example {"allow_paper_based" : "1"} For more details on Instructions Parameters click here |
show_ocr_form | Required: No Type: boolean Accepted Values: 0, 1 default value: 1 The default value for this is 1. If this is set to 0, the user will not be shown the OCR form to validate the extracted information. This can be used within the Document, Document Two, and Address service. This value can also be applied to all services collectively. However, preference will be given to the value set within the service. Note: Setting the value at 0 may cause data inaccuracy as the user does not have option to validate the extracted information. |
Consent Service
Consent service sample object
{
"consent" : {
"proof" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAALCAYAAABCm8wlAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoPAxIb88htFgAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAACxSURBVBjTdY6xasJgGEXP/RvoonvAd8hDyD84+BZBEMSxL9GtQ8Fis7i6BkGI4DP4CA4dnQON3g6WNjb2wLd8nAsHWsR3D7JXt18kALFwz2dGmPVhJt0IcenUDVsgu91eCRZ9IOMfAnBvSCz8I3QYL0yV6zfyL+VUxKWfMJuOEFd+dE3pC1Finwj0HfGBeKGmblcFTIN4U2C4m+hZAaTrASSGox6YV7k+ARAp4gIIOH0BmuY1E5TjCIUAAAAASUVORK5CYII=",
"supported_types" : ["printed"],
"text" : "My name is John Doe and I authorise this transaction of $100/- Date: July 15, 2020",
"allow_offline" : "1"
}
}
Customised documents/notes can also be verified by Shufti Pro. Company documents, employee cards or any other personalised note can be authenticated by this module. You can choose handwritten or printed document format but only one form of document can be verified in this verification module. Text whose presence on the note/customized document is to be verified, is also needed to be provided.
Parameters | Description |
---|---|
proof | Required: Yes Type: string Image Format: JPG, JPEG, PNG, PDF Maximum: 16MB Video Format: MP4/MOV Maximum: 20MB |
supported_types | Required: No Type: Array Text provided in the consent verification can be verified by handwritten documents or printed documents. Supported types are listed here Example 1 ["printed"] Example 2 ["printed", "handwritten"] |
text | Required: Yes Type: string Minimum: 2 characters Maximum: 100 chracters Provide text in the string format which will be verified from a given proof. |
with_face | Required: No Type: string Accepted Values: 0, 1 Default Value: 1 This parameter is applicable if supported_type is handwritten and default value is 1. If value of with_face is 1 then hand written note will be accepted only with face which means your customer must need to show his/her face along with the consent on a paper. If value of with_face is 0 then hand written note is accepted with or without face. |
Background Checks Service
Background Checks service sample
{
"background_checks" : {
"name" : {
"first_name" : "John",
"middle_name" : "Middle",
"last_name" : "Doe"
},
"dob" : "1990-10-10"
}
}
{
"background_checks" : {
"name" : {
"full_name" : "John Carter Doe"
},
"dob" : "1995-10-10"
}
}
{
"background_checks" : {
"name" : {
"first_name" : "John",
"middle_name" : "Carter",
"last_name" : "Doe"
}
}
}
It is a verification process that will require you to send us the full Name of end-user in addition to date of birth. Shufti Pro will perform AML based background checks based on this information.
Parameters | Description |
---|---|
dob | Required: Yes Type: string Format: yyyy-mm-dd Provide a valid date. Example 1990-12-31 Note: It is recommended to send dob for more accurate results. |
name | Required: Yes Type: object In name object used in background checks service, first_name required and other fields are optional. Parameters for name are listed here: Example 1 { "first_name" : "John", "last_name" : "Doe"} Example 2 { "first_name" : "John", "middle_name" : "Carter", "last_name" : "Doe"} Example 3 { "full_name" : "John Carter Doe"} Note: If full name is provided with first and last name priority will be given to full name. |
ongoing | Required: No Accepted values: 0, 1 Default: 0 This Parameter is used for Ongoing AML Screening, and is allowed only on Production Accounts. If Shufti Pro detects a change in AML statuses, then we will send you a webhook with event verification.status.changed. The new AML status can be checked using get status endpoint, or from the back-office. Use fuzzy_match = 1 in the name object for better results for Ongoing AML Screening. |
Request
Status Request
Status Request Sample
//POST /status HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
// replace "Basic" with "Bearer in case of Access Token"
{
"reference" : "17374217"
}
<?php
$url = 'https://api.shuftipro.com/status';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
//$access_token = 'YOUR-ACCESS-TOKEN';
$status_request = [
"reference" => "your_request_reference",
];
$auth = $client_id.":".$secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization : Bearer ' . $access_token);
$post_data = json_encode($status_request);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $post_data, $headers, $auth); // remove $auth in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
// calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
if($sp_signature == $calculate_signature){
echo "Response : $response_data";
}else{
echo "Invalid signature : $response_data";
}
function send_curl($url, $post_data, $headers, $auth){ // remove $auth in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$curl_info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers,'body' => $body];
}
?>
var payload = {
reference : 'your_request_reference'
}
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/status',
{
method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
},
body: JSON.stringify(payload)
})
.then(function(response) {
return response.json();
}).then(function(data) {
return data;
});
import base64, requests, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/status'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
status_request = {
"reference" : "your_request_reference"
}
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"},
data=json.dumps(status_request))
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Convert json string to json object
json_response = json.loads(response.content)
sp_signature = response.headers.get('Signature','')
if sp_signature == calculated_signature:
print ('Response : {}'.format(json_response))
else:
print ('Invalid Signature: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
url = URI("https://api.shuftipro.com/status")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
post_data = {
reference: "your_request_reference"
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}" # replace "Basic" with "Bearer" in case of access token
request.body = post_data.to_json
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Once a verification request is completed, you may request at status end point to get the verification status. You’ll have to provide reference ID for status request and you will be promptly informed about the status of that verification.
Parameter | Description |
---|---|
reference | Required: Yes Type: string Minimum: 6 characters Maximum: 250 characters This is the unique reference ID of request, which we will send you back with each response, so you can verify the request. |
Status Request Response
Sample Response
//Content-Type: application/json
//Signature: NmI4NmIyNzNmZjM0ZmNl
{
"reference" : "17374217",
"event" : "verification.accepted",
"country" : "GB",
"proofs" : {
"face": {
"proof": "https://api.shuftipro.com/storage/aZa8mncOFLrbtxXk7Ka/face/proof.png?access_token=1a6c9985e88051092b31d62d043"
},
"document": {
"proof": "https://api.shuftipro.com/storage/aZa8mncOFLrbtxXk7Ka/document/proof.png?access_token=1a6c9985e88051092b31d62d043"
},
"address": {
"proof": "https://api.shuftipro.com/storage/aZa8mncOFLrbtxXk7Ka/address/proof.png?access_token=1a6c9985e88051092b31d62d043"
},
"consent": {
"proof": "https://api.shuftipro.com/storage/aZa8mncOFLrbtxXk7Ka/consent/proof.png?access_token=1a6c9985e88051092b31d62d043"
},
"verification_video": "https://api.shuftipro.com/storage/aZa8mncOFLrbtxXk7Ka/video/video.mp4?access_token=3242f486e3346db90f442c9ac06a4ad1771ead3c"
},
"verification_data": {
"document": {
"issue_date": "1990-01-01",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"passport",
"driving_license",
"credit_or_debit_card"
]
},
"address": {
"full_address": "Candyland Avenue",
"selected_type": [
"utility_bill"
],
"supported_types": [
"utility_bill",
"driving_license",
"bank_statement",
"envelope",
"id_card",
"passport",
"rent_agreement",
"employer_letter",
"insurance_agreement",
"tax_bill"
]
},
"consent": {
"text": "My name is John Doe and I authorise this transaction of $100/- Date: July 15, 2020",
"selected_type": [
"handwritten"
],
"supported_types": [
"handwritten",
"printed"
]
},
"background_checks": {
"dob": "1990-01-01",
"name": {
"last_name": "John",
"first_name": "Doe"
}
},
"aml_for_business": {
"business_name": "Company Name",
"business_incorporation_date": "1975-07-01",
"aml_data": {
"filters": [
"sanction",
"warning",
"fitness-probity",
"pep",
"pep-class-1",
"pep-class-2",
"pep-class-3",
"pep-class-4"
],
"hits": [
{
"name": "Company Name",
"entity_type": "organisation",
"score": 24.911245,
"match_types": [
"name_exact"
],
"alternative_names": [
"Company Name"
],
"assets": [
{
"public_url": "http://example.s3.amazonaws.com/834refjadfkjhq4-ahfdkddfa8a.pdf",
"source": "us-securities-exchange-commission-litigation-releases",
"type": "pdf"
}
],
"associates": [],
"fields": {
"Activation Date": [
{
"value": "Jul. 17, 2019",
"source": "united-states-securities-and-exchange-commission-administrative-proceedings-organisation",
"tag": ""
}
],
"Adverse Media Subtypes": [
{
"value": "antitrust, corporate-fraud, corruption, fines, insider-trading, litigation, money-laundering, other-crime, security, tax-evasion",
"source": "company-am",
"tag": ""
}
],
"Date": [
{
"value": "2002-08-03",
"source": "us-securities-exchange-commission-litigation-releases",
"tag": ""
}
],
"Enforcement Agency": [
{
"value": "United States Securities and Exchange Commission",
"source": "united-states-securities-and-exchange-commission-administrative-proceedings-organisation",
"tag": ""
}
],
"Related URL": [
{
"value": "http://www.sec.gov/litigation/link423.shtml",
"source": "us-securities-exchange-commission-litigation-releases",
"tag": "related_url"
},
{
"value": "https://www.sec.gov/litigation/admin/2019/34-72891heq89.pdf",
"source": "united-states-securities-and-exchange-commission-administrative-proceedings-organisation",
"tag": "related_url"
}
],
"Release": [
{
"value": "Release information about company...",
"source": "us-securities-exchange-commission-litigation-releases",
"tag": ""
}
],
"Release Number": [
{
"value": "34-46017",
"source": "us-securities-exchange-commission-litigation-releases",
"tag": ""
}
],
"Related Url": [
{
"value": "http://www.sec.gov/litigation/admin/34-234324.htm",
"source": "us-securities-exchange-commission-litigation-releases",
"tag": "related_url"
}
]
},
"media": [
{
"date": "2019-09-15T00:00:00Z",
"snippet": "The NYPD said 12 men and 75 women were charged with obstructing traffic after blocking cars outside the company's flagship shop on 5th Avenue between 53rd and 54th streets on Satur day",
"title": "Dozens of ICE Protesters Arrested in Midtown - American Renaissance",
"url": "https://www.amren.com/news/2019/23/dozens-of-ice-protesters-arrtedaddsa-in-midtown/"
},
{
"date": "2019-09-15T00:00:00Z",
"snippet": "The NYPD said 12 men and 75 women were charged with obstructing traffic after blocking cars outside the company's flagship shop on 5th Avenue between 53rd and 54th streets on Satur day",
"title": "Dozens of ICE protesters arrested in Midtown",
"url": "https://nypost.com/2019/10/23/dozens-of-ice-asdf-asdfd-in-midtown/"
}
],
"source_notes": {
"company-am": {
"aml_types": [
"adverse-media",
"adverse-media-financial-crime",
"adverse-media-fraud",
"adverse-media-general"
],
"name": "company AM"
},
"united-states-securities-and-exchange-commission-administrative-proceedings-organisation": {
"aml_types": [
"warning"
],
"listing_started_utc": "2019-07-25T00:00:00Z",
"name": "United States Securities and Exchange Commission Administrative Proceedings - organisation",
"url": "https://www.sec.gov/litigation/asddfa.shtml"
},
"us-securities-exchange-commission-litigation-releases": {
"aml_types": [
"warning"
],
"listing_ended_utc": "2016-12-22T00:00:00Z",
"name": "Warnings USA SEC Litigation Releases",
"url": "http://www.sec.gov/litigation/asdfasdf.shtml"
}
},
"sources": [
"company-am",
"united-states-securities-and-exchange-commission-administrative-proceedings-organisation",
"us-securities-exchange-commission-litigation-releases"
],
"types": [
"adverse-media",
"adverse-media-financial-crime",
"adverse-media-fraud",
"adverse-media-general",
"warning"
]
}
]
}
}
},
"verification_result": {
"background_checks": 1,
"consent": {
"consent": 1,
"selected_type": 1
},
"address": {
"partial_address_match_with_id_and_utility_bill": 1,
"full_address": 1,
"address_document_visibility": 1,
"address_document_must_not_be_expired": 1,
"address_document": 1,
"address_document_country": 1,
"selected_type": 1
},
"document": {
"issue_date": 1,
"document_visibility": 1,
"document_must_not_be_expired": 1,
"document": 1,
"document_country": 1,
"selected_type": 1
},
"face": 1
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
}
}
The Shufti Pro Verification API will send a JSON response if a status request is made. Make sure to validate the request by generating signature and matching it with Signature value from response header.
Parameters | Description |
---|---|
reference | Your unique request reference, which you provided us at the time of request, so that you can identify the response in relation to the request made. |
event | This is the request event which shows status of request. Event is changed in every response. Please consult Events for more information. |
country | This contains country code sent by the merchant at the time of request. Country code in the format of ISO 3166-1 alpha-2. Please consult Supported Countries for country codes. Type: string Example: DE null if not provided by merchant. |
proofs | This contains all the proofs that were used to verify data. The Proof URLs returned are temporary and valid for 15 minutes only. Note: verification_video It contains the video URL and will be returned only for the video recorded on-site. |
verification_result | This object will be returned in case of verification.accepted or verification.declined. This includes the results of each verification. 1 means accepted 0 means declined null means not processed Check verification.accepted and verification.declined responses in Events section for a sample response. |
verification_data | This object will be returned in case of verification.accepted or verification.declined. This object will include all the gathered data in a request process. Check verification.accepted and verification.declined responses in Events section for a sample response. |
info | This object will be returned in case of verification.accepted or verification.declined. It contains the following keys: Agent provides information about the device and browser of the end-user. Geolocation provides information about the geographical location of the end-user. For Details on info object go to INFO |
additional_data | This object will be returned in case of verification.accepted or verification.declined. This object contains the additional data extracted by Shuftipro on the document. For Details on additional_data object go to Additional Data |
declined_reason | This parameter will have the reason due to which a verification has been declined, and is only returned in this case in the callback URL. |
declined_codes | This array contains status codes of all declined verification reasons. It will return only for verification.declined. |
services_declined_codes | This object contains status codes of declined reasons for each service separately. Each service object will contain an array of status codes for declined reasons specific to that service. It will return only for verification. declined. |
Delete Request
Delete Request Sample
//POST /delete HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
// replace "Basic" with "Bearer in case of Access Token"
{
"reference" : "17374217",
"comment" : "Customer asked to delete his/her data"
}
<?php
$url = 'https://api.shuftipro.com/delete';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
//$access_token = 'YOUR-ACCESS-TOKEN';
$delete_request = [
"reference" => "your_request_reference",
"comment" => "Customer asked to delete his/her data"
];
$auth = $client_id . ":" . $secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization : Bearer ' . $access_token);
$post_data = json_encode($delete_request);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $post_data, $headers, $auth); // remove $auth in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
if($sp_signature == $calculate_signature){
echo "Response :". $response_data;
}else{
echo "Invalid signature :". $response_data;
}
function send_curl($url, $post_data, $headers, $auth){ // remove $auth in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$html_response = curl_exec($ch);
$curl_info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers, 'body' => $body];
}
?>
var payload = {
reference : 'your_request_reference',
comment : 'Customer asked to delete his/het data'
}
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/delete',
{
method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
},
body: JSON.stringify(payload)
})
.then(function(response) {
return response.json();
}).then(function(data) {
return data;
});
import base64, requests, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/delete'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
delete_request = {
"reference" : "your_request_reference",
"comment" : "Customer asked to delete his/her data"
}
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"},
data=json.dumps(delete_request))
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Convert json string to json object
json_response = json.loads(response.content)
sp_signature = response.headers.get('Signature','')
if sp_signature == calculated_signature:
print ('Response : {}'.format(json_response))
else:
print ('Invalid Signature: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
url = URI("https://api.shuftipro.com/delete")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
post_data = {
reference: "your_request_reference",
comment: "Customer asked to delete his/her data"
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}"
request.body = post_data.to_json
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Once a verification request is completed, you may request at delete request endpoint to delete the verification data. You’ll have to provide reference ID for that request and you will be promptly informed about the deletion of the request.
Parameter | Description |
---|---|
reference | Required: Yes Type: string Minimum: 6 characters Maximum: 250 characters This is the unique reference ID of request which needs to be deleted. |
comment | Required: Yes Type: string Minimum: 5 characters Maximum: 200 characters Add a comment why the request is deleted for your future reference |
Delete Request Response
Sample Response
//Content-Type: application/json
//Signature: NmI4NmIyNzNmZjM0ZmNl
{
"reference": "17374217",
"event": "request.deleted"
}
The Shufti Pro Verification API will send a JSON response if a delete request is made. Make sure to validate the request by generating signature and matching it with Signature value from response header.
Parameters | Description |
---|---|
reference | Your unique request reference, which you provided us at the time of request, so that you can identify the response in relation to the request made. |
event | This is the request event which shows status of request. Event is changed in every response. Please consult Events for more information. |
Account Info Request
Sample Account Info Request
//GET /account/info/ HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/account/info/',
{
method : 'get',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
}
})
.then(function(response) {
return response.json();
}).then(function(data) {
return data;
});
<?php
$url = 'https://api.shuftipro.com/account/info/';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
//$access_token = 'YOUR-ACCESS-TOKEN';
$auth = $client_id.":".$secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization: Bearer ' . $access_token);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $headers, $auth); // remove $auth in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
// calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
if($sp_signature == $calculate_signature){
echo "Response :" . $response_data;
}else{
echo "Invalid signature :" . $response_data;
}
function send_curl($url, $headers, $auth){ // remove $auth in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers,'body' => $body];
}
?>
import base64, requests, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/account/info/'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.get(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"})
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Convert json string to json object
json_response = json.loads(response.content)
sp_signature = response.headers.get('Signature','')
if sp_signature == calculated_signature:
print ('Response : {}'.format(json_response))
else:
print ('Invalid Signature: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
url = URI("https://api.shuftipro.com/account/info/")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}" # replace "Basic" with "Bearer" in case of access token
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Sample Account Info Response
{
"account": {
"name": "your account name",
"status": "production",
"balance": {
"amount": "99.85",
"currency": "USD"
}
}
}
{
"account": {
"name": "your account name",
"status": "production",
"balance": {
"amount": "99.85",
"currency": "USD"
},
"subscription_plan_details": {
"kyc": [
{
"total_requests": 100,
"used_requests": 0,
"remaining_requests": 100,
"start_date": "2020-05-03",
"end_date": "2020-05-18"
},
{
"total_requests": 100,
"used_requests": 0,
"remaining_requests": 100,
"start_date": "2020-05-18",
"end_date": "2020-05-30"
}
],
"aml": [
{
"total_requests": 500,
"used_requests": 0,
"remaining_requests": 500,
"start_date": "2020-05-01",
"end_date": "2020-05-30"
},
{
"total_requests": 200,
"used_requests": 0,
"remaining_requests": 200,
"start_date": "2020-05-30",
"end_date": "2020-06-27"
}
],
"kyb": [
{
"total_requests": 3000,
"used_requests": 0,
"remaining_requests": 3000,
"start_date": "2020-05-08",
"end_date": "2020-05-30"
}
]
}
}
}
{
"account": {
"name": "your account name",
"status": "trial",
"balance": {
"amount": "99.85",
"currency": "USD"
}
}
}
This end-point provides account information to the customer such as account status, balance, and type (production mode or trial mode).
Access Token Request
Sample Access Token Request
//POST https://api.shuftipro.com/get/access/token HTTP/1.1
//Host: api.shuftipro.com
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
<?php
$url = 'https://api.shuftipro.com/get/access/token';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
$auth = $client_id . ":" . $secret_key;
$headers = ['Content-Type: application/json'];
//Calling Shufti Pro request API using curl
$response = send_curl($url, $headers, $auth);
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
$calculate_signature = hash('sha256',$response_data.$secret_key);
if($sp_signature == $calculate_signature){
echo "Response :" . $response_data;
}else{
echo "Invalid signature :" . $response_data;
}
function send_curl($url, $headers, $auth){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers, 'body' => $body];
}
?>
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/get/access/token',
{
method : 'post',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token
}
})
.then(function(response) {
return response.json();
}).then(function(data) {
return data;
});
import base64, requests, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/get/access/token'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
response = requests.post(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"})
# Calculating signature for verification
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Convert json string to json object
json_response = json.loads(response.content)
sp_signature = response.headers.get('Signature','')
if sp_signature == calculated_signature:
print ('Response : {}'.format(json_response))
else:
print ('Invalid Signature: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
url = URI("https://api.shuftipro.com/get/access/token")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}"
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Sample Access Token Response
{
"access_token": "NzA4N2I2YjAwZjQyYmUyNDc1YTUxZmZiMzJjMTQ4M2IxOTY2ZTFmMg=="
}
This end-point is used to generate an access_token which is used to authorize API requests. This token will be useful for 10 minutes and can be used for one request to the API.
Technical Appendix
Enhanced Data Extraction
Shufti Pro provides its customers with the facility of extracting enhanced data features using OCR technology. Now, instead of extracting just personal information input fields, Shufti Pro can fetch all the additional information comprising more than 100 data points from the official ID documents supporting 150 languages. For example height, place_of_birth, nationality, marital_status, weight, etc. Shufti Pro is the first digital identity verification service that can fetch a huge bunch of information efficiently in mere seconds.(additional charges apply)
This feature can be used with document and document_two services.
{
"fetch_enhanced_data" :"1"
}
Parameters | Description |
---|---|
fetch_enhanced_data | Required: No Type: string Value Accepted: 1 Provide 1 for enabling enhanced data extraction for the document. Extracted data will be returned in object under the key additional_data in case of verification.accepted or verification.declined. For Details on additional_data object go to Additional Data |
Name
name is an object and contains the following parameters
Name sample object
{
"name" : {
"first_name" : "John",
"middle_name" : "Carter",
"last_name" : "Doe",
"fuzzy_match" : "1"
}
}
{
"name" : {
"full_name" : "John Carter Doe",
"fuzzy_match" : "1"
}
}
Parameters | Description |
---|---|
first_name | Required: No Type: string Minimum: 1 character Maximum: 32 chracters Allowed Characters are alphabets, - (dash), comma, space, dot and single quotation mark. Example John'O Harra |
middle_name | Required: No Type: string Minimum: 1 character Maximum: 32 chracters Allowed Characters are alphabets, - (dash), comma, space, dot and single quotation mark. Example Carter-Joe |
last_name | Required: No Type: string Minimum: 1 character Maximum: 32 chracters Allowed Characters are alphabets, - (dash), comma, space, dot and single quotation mark. Example John, Huricane Jr. |
fuzzy_match | Required: No Type: string Value Accepted: 1 Provide 1 for enabling a fuzzy match of the name. Enabling fuzzy matching attempts to find a match which is not a 100% accurate. |
full_name | Required: No Type: string Minimum: 1 character Maximum: 64 characters Some countries don't have the identity document holder name as their first, middle or last name instead its written in full. In such cases, you may provide the full name. |
Age
Shufti Pro provides its clients with an option to configure the Age verification from within the API request. This service allows the acceptance of users within the specified age limits according to their DOB. The client can specify lower and upper limit and according to that, the users age will be verified. In case, minimum and maximum values are not set, Shufti Pro will calculate and return Age according to the DOB. If DOB is not present on the document, the verification will decline as Age will not be verified
Age is an object or integer that can be used to set the lower and upper limit for Age of the user according to DOB. It contains the following parameters.Min is used to specify the lower limit whereas Max is used to specify the upper limit.
Age sample object
{
"age" : 18
}
{
"age" : {
"min" : "17",
"max" : "165"
}
}
Parameters | Description |
---|---|
age | Required: No Type: integer/array Allowed values are integers or array. Example 18 |
min | Required: No Type: integer Minimum Value: 1 Allowed values are integers or array. Example 17 |
max | Required: No Type: integer Maximum Value: 170 Allowed values are integers or array. Example 165 |
Response Signature
Every HTTP and Callback responses will be in application/json with a key Signature in the header. It can be used to validate the source of the request. Make a signature using the following procedure:
- Concatinate Secret Key at the end of the raw response string. (i.e. response + secret_key).
- Take SHA256 of concatinated string.
- Match the SHA256 string with Signature value from the header of the response.
In short, make signature as hash('sha256', response . your_secret_key)
and match it with the signature provided in the header in Signature key.
HTTP Status Codes and Events
Instant Capture & Verification API uses conventional HTTP response codes to indicate the success or failure of an API request. Every response is generated in JSON with a specific HTTP code. Go to Status Codes for a complete list of status codes. Events are sent in responses which show the status of request. These events are sent in both HTTP and callback responses. Please consult Events for a complete list of events.
Status Codes
Shufti Pro Verification API uses conventional HTTP response codes to indicate the success or failure of an API request. Every response is generated in JSON with a specific HTTP code.
HTTP Codes
Following is a list of HTTP codes which are generated in responses by Shufti Pro Verification API.
HTTP code | HTTP message | Message |
---|---|---|
200 | OK | success |
400 | Bad Request | bad request: one or more parameter is invalid or missing |
401 | Unauthorized | unauthorized: invalid signature key provided in the request |
402 | Request Failed | invalid request data: missing required parameters |
403 | Forbidden | forbidden: service not allowed |
404 | Not Found | resource not found |
409 | Conflict | conflicting data: already exists |
500 | Server Error | internal server error |
429 | Too Many Requests | Too Many Attempts. |
Response Events
Events are sent in responses which show the status of request. These events are sent in both HTTP and callback responses.
request.received
{
"reference": "17374217",
"event": "request.received",
"email": "[email protected]",
"country": "UK"
}
request.invalid
{
"reference": "17374217",
"event": "request.invalid",
"error": {
"service": "document",
"key": "dob",
"message": "The dob does not match the format Y-m-d."
},
"email": null,
"country": null
}
request.deleted
{
"reference": "17374217",
"event": "request.deleted"
}
request.timeout
{
"reference": "17374217",
"event": "request.timeout",
"country": "GB",
"proofs": {}
}
request.unauthorized
{
"reference": "",
"event": "request.unauthorized",
"error": {
"service": "",
"key": "",
"message": "Authorization keys are missing/invalid."
},
"email": null,
"country": null"
}
verification.accepted
{
"reference": "17374217",
"event": "verification.accepted",
"verification_result": {
"document": {
"name": 1,
"dob": 1,
"age": 1,
"expiry_date": 1,
"issue_date": 1,
"document_number": 1,
"document": 1
},
"address": {
"name": 1,
"full_address": 1
}
},
"verification_data": {
"document": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
"document_number": "1456-0989-5567-0909",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"driving_license",
"passport"
]
},
"address": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"full_address": "3339 Maryland Avenue, Largo, Florida",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"bank_statement"
]
}
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
},
"additional_data": {
"document": {
"proof": {
"gender": "M",
"height": "183",
"country": "United Kingdom",
"authority": "HMPO",
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"country_code": "GBR",
"document_type": "P",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
"personal_number": "12345678910",
"dob": "1978-03-13",
"age": 18
}
}
}
}
verification.declined
{
"reference": "95156124",
"event": "verification.declined",
"verification_result": {
"document": {
"name": 0,
"dob": 1,
"age": 1,
"expiry_date": 1,
"issue_date": 1,
"document_number": 1,
"document": null
},
"address": {
"name": null,
"full_address": null
}
},
"verification_data": {
"document": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
"document_number": "1456-0989-5567-0909",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"driving_license",
"passport"
]
},
"address": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"full_address": "3339 Maryland Avenue, Largo, Florida",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"bank_statement"
]
}
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
},
"declined_reason": "Name on the document doesn't match",
"declined_codes":[
"SPDR07",
"SPDR06",
"SPDR23"
],
"additional_data": {
"document": {
"proof": {
"gender": "M",
"height": "183",
"country": "United Kingdom",
"authority": "HMPO",
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"country_code": "GBR",
"document_type": "P",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
"personal_number": "12345678910",
"dob": "1978-03-13",
"age": 18
}
}
},
"services_declined_codes": {
"document": [
"SPDR13",
"SPDR12"
],
"address": [
"SPDR22",
"SPDR26"
],
"face": [
"SPDR01"
]
}
}
verification.status.changed
{
"reference": "17374217",
"event": "verification.status.changed"
}
review.pending
{
"reference": "95156124",
"event": "review.pending",
"verification_result": {
"document": {
"name": 0,
"dob": 1,
"age": 1,
"expiry_date": 1,
"issue_date": 1,
"document_number": 1,
"document": null
},
"address": {
"name": null,
"full_address": null
}
},
"verification_data": {
"document": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
"gender" : "M"
"document_number": "1456-0989-5567-0909",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"driving_license",
"passport"
]
},
"address": {
"name": {
"first_name": "John",
"middle_name": "Carter",
"last_name": "Doe"
},
"full_address": "3339 Maryland Avenue, Largo, Florida",
"selected_type": [
"id_card"
],
"supported_types": [
"id_card",
"bank_statement"
]
}
},
"info": {
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
},
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
},
"declined_reason": "Name on the document doesn't match",
"declined_codes":[
"SPDR07",
"SPDR06",
"SPDR23"
],
"additional_data": {
"document": {
"proof": {
"height": "183",
"country": "United Kingdom",
"authority": "HMPO",
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"country_code": "GBR",
"document_type": "P",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
"personal_number": "12345678910",
"dob": "1978-03-13",
"age": 18,
"gender" : "M"
}
}
},
"services_declined_codes": {
"document": [
"SPDR13",
"SPDR12"
],
"address": [
"SPDR22",
"SPDR26"
],
"face": [
"SPDR01"
]
}
}
Event | description | HTTP Response | Callback Response |
---|---|---|---|
request.received | Request has been received. | Yes | Yes |
request.invalid | Request parameters provided in request are invalid. | Yes | No |
request.deleted | Request has been deleted. | Yes | Yes |
request.timeout | Request has timed out after a specific period of time. | No | Yes |
request.unauthorized | Request is unauthorized. The information provided in authorization header is invalid. | Yes | No |
verification.accepted | Request was valid and accepted after verification. | Yes | Yes |
verification.declined | Request was valid and declined after verification. | Yes | Yes |
verification.status.changed | Request status has been updated. | No | Yes |
review.pending | Documents are collected and request is pending for client to review and Accept/Decline. | Yes | Yes |
Instructions Parameters
Instruction Parameters
{
"document":{
"proof":"",
"supported_types":["id_card","driving_license","passport"],
"verification_instructions" : {
"allow_paper_based" : "1",
"allow_photocopy" : "1",
"allow_laminated" : "1",
"allow_screenshot" : "1",
"allow_cropped" : "1",
"allow_scanned" : "1"
}
}
}
Instruction Parameters
{
"document_two":{
"proof":"",
"supported_types":["id_card","driving_license","passport"],
"verification_instructions" : {
"allow_paper_based" : "1",
"allow_photocopy" : "1",
"allow_laminated" : "1",
"allow_screenshot" : "1",
"allow_cropped" : "1",
"allow_scanned" : "1"
}
}
}
Instruction Parameters
{
"address":{
"proof":"",
"supported_types":["id_card","driving_license","passport"],
"verification_instructions" : {
"allow_paper_based" : "1",
"allow_photocopy" : "1",
"allow_laminated" : "1",
"allow_screenshot" : "1",
"allow_cropped" : "1",
"allow_scanned" : "1"
}
}
}
These parameters can be used with Document, Document Two and Address Service.
Parameters | Description |
---|---|
allow_paper_based | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept paper-backed documents for verification. |
allow_photocopy | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept photocopied documents for verification. |
allow_laminated | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept laminated documents for verification. |
allow_screenshot | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept screenshot documents for verification. |
allow_cropped | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept cropped documents for verification. |
allow_scanned | Required: No Type: string Value Accepted: 0, 1 Default Value: 0 If this string is assigned value “1” then Shufti Pro will accept scanned documents for verification. |
Strict Originality Configuration
{
"verification_mode": "video_only",
"allow_online": "1",
"allow_offline": "0"
}
Supported Types
Shufti Pro supports different types of ID and address documents, along with various consent notes. All the supported types are mentioned below.
Document Supported Types
All document supported types are listed below.
Supported Types |
---|
1. passport |
2. id_card |
3. driving_license |
4. credit_or_debit_card |
Address Supported Types
All address supported types are listed below.
Supported Types |
---|
1. id_card |
2. passport |
3. driving_license |
4. utility_bill |
5. bank_statement |
6. rent_agreement |
7. employer_letter |
8. insurance_agreement |
9. tax_bill |
10. envelope |
11. cpr_smart_card_reader_copy |
12. property_tax |
13. lease_agreement |
14. insurance_card |
15. permanent_residence_permit |
16. credit_card_statement |
17. insurance_policy |
18. e_commerce_receipt |
19. bank_letter_receipt |
20. birth_certificate |
21. salary_slip |
22. any |
Note: The "any" supported type allows the acceptance of all address document types if it has the user's Name and Address on it. |
Consent Supported Types
All consent supported types are listed below.
Supported Types |
---|
1. handwritten |
2. printed |
Rate Limiting
Shufti Pro has induced request limits for the Production and Trial accounts. The limits for both types of accounts are mentioned below.
Production Account
For the production account, Shufti Pro allows 60 requests per min. This limit is per IP.
Trial Account
For the trial account, Shufti Pro allows 3 requests per minute. This limit is per account.
Webhook IPs
All webhook requests will come from the following IPs:
- Europe:
- 142.132.144.101
- 65.108.103.45
- United States:
- 5.161.114.110
- 5.161.87.219
- 5.78.56.7
- 5.78.58.196
Please make sure that you allow these IPs in order to receive webhook notifications.
Info
This object will be returned in case of verification.accepted or verification.declined. It contains the following keys:
The Agent provides information about the device and browser of the end-user.
Geolocation provides information about the geographical location of the end-user.
Agent
agent is an object and contains the following parameters
Agent sample object
{
"agent": {
"is_desktop": true,
"is_phone": false,
"useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"device_name": "Macintosh",
"browser_name": "",
"platform_name": "OS X - 10_14_0"
}
}
Parameters | Description |
---|---|
is_desktop | Type: Boolean Example: true Shows empty string “” if not detected. |
is_phone | Type: Boolean Example: false Shows empty string “” if not detected. |
useragent | Type: string Example: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 Shows empty string “” if not detected. |
device_name | Type: string Example: Macintosh Shows empty string “” if not detected. |
browser_name | Type: string Example: Chrome - 70.0.3538.80 Shows empty string “” if not detected. |
platform_name | Type: string Example: OS X - 10_14_0 Shows empty string “” if not detected. |
Geo location
geolocation is an object and contains the following parameters
geolocation sample object
{
"geolocation": {
"host": "212.103.50.243",
"ip": "212.103.50.243",
"rdns": "212.103.50.243",
"asn": "9009",
"isp": "M247 Ltd",
"country_name": "Germany",
"country_code": "DE",
"region_name": "Hesse",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60326",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": "50.1049",
"longitude": "8.6295",
"metro_code": "",
"timezone": "Europe/Berlin"
}
}
Parameters | Description |
---|---|
host | Type: string Example: 212.103.50.243 Shows empty string “” if not detected. |
ip | Type: string** Example: 212.103.50.243 Shows empty string “” if not detected. |
rdns | Type: string Example: 212.103.50.243 Shows empty string “” if not detected. |
asn | Type: string Example: 9009 Shows empty string “” if not detected. |
isp | Type: string Example: M247 Ltd Shows empty string “” if not detected. |
country_name | Type: string Example: Germany Shows empty string “” if not detected. |
country_code | Type: string Example: DE Shows empty string “” if not detected. |
region_name | Type: string Example: Hesse Shows empty string “” if not detected. |
region_code | Type: string Example: HE Shows empty string “” if not detected. |
city | Type: string Example: Frankfurt am Main Shows empty string “” if not detected. |
postal_code | Type: string Example: 60326 Shows empty string “” if not detected. |
continent_name | Type: string Example: Europe Shows empty string “” if not detected. |
continent_code | Type: string Example: EU Shows empty string “” if not detected. |
latitude | Type: string Example: 50.1049 Shows empty string “” if not detected. |
longitude | Type: string Example: 50.1049 Shows empty string “” if not detected. |
metro_code | Type: string Example: 501 Shows empty string “” if not detected. |
timezone | Type: string Example: Europe/Berlin Shows empty string “” if not detected. |
Additional Data
Additional Data object
{
"additional_data": {
"document": {
"proof": {
"gender": "M",
"height": "183",
"country": "United Kingdom",
"authority": "HMPO",
"last_name": "Doe",
"first_name": "John",
"issue_date": "2018-01-31",
"expiry_date": "2028-01-30",
"nationality": "BRITSH CITIZEN",
"country_code": "GBR",
"document_type": "P",
"place_of_birth": "BRISTOL",
"document_number": "GB1234567",
"personal_number": "12345678910",
"dob": "1978-03-13",
"age": 18,
"issue_date": "2015-10-10",
"expiry_date": "2025-12-31",
"signature": "335,300,435,400",
}
}
}
}
This object will be returned in case of verification.accepted or verification.declined. This object contains the additional data extracted by Shuftipro. For example height, place_of_birth, nationality, marital_status, weight. The values in the object will be in string format. For keys ('face', 'finger_print', 'signature') comma-separated string will be returned, which will contain coordinates x1,y1,x2,y2 (top-left and bottom-right).
Note: keys in this object may change based on data extracted from the document.
Declined Reasons
Face
Description |
---|
1. Face could not be verified |
2. Face could not be detected in image, please upload image again with your face clearly visible |
3. Image is altered or photoshopped |
4. Copy of the image found on web |
5. Face in the image is with wearing glasses |
6. Face proof is from another screen |
7. Face proof is taken from the web |
8. More than one face in one image |
9. Face proof is a screenshot |
10. Face doesn't match the face image uploaded at the time of signup |
11. Document doesn’t match the document uploaded at the time of signup |
12. Camera is not accessible for verification |
Document & Document Two
Description |
---|
1. Image of the face not found on the document |
2. Document originality could not be verified |
3. Name on the document doesn't match |
4. DOB on the document doesn't match |
5. The expiry date of the document does not match the record, please upload a document with valid expiry date |
6. Issue date on the document doesn't match |
7. Date on the document doesn't match |
8. Number on the document doesn't match |
9. The issuing country of document is not supported, please upload a valid document |
10. Document doesn't match the provided options |
11. You are not eligible because you don't fall in the provided age range |
12. Face on the document doesn't match with camera image |
13. The document is expired, please upload a new document which is not expired |
14. The uploaded image of the document is blur, please provide a clear photo of document |
15. Face could not be detected in image, please upload image again with your face clearly visible |
16. Image is altered or photoshopped |
17. Copy of the image found on web |
18. Proof and Additional Proof are of different documents |
19. Front and backside images of the document did not match, please upload images of the same document |
20. Document proof is a screenshot |
21. Document proof is altered/edited |
22. Document proof is paper based which is not accepted |
23. Document proof is punched/broken |
24. Document proof is from another screen |
25. Hologram is missing on the document |
26. Document proof is not fully displayed. |
27. Document is blur |
28. Information on the document proof is not visible |
29. Information on the document is edited |
30. Information on the document is hidden |
31. Document should be from the provided country |
32. Issue date does not match with the provided one |
33. Expiry date does not match with the provided one |
34. Submitted document is expired |
35. Issue date on the document is not clearly visible |
36. Expiry date on the document is not clearly visible |
37. Date of Birth on the document does not match with the provided one |
38. Date of Birth on the document is not clearly visible |
39. Name on the document does not match with the provided one |
40. Name on the document is not clearly visible |
41. Document number does not match with the provided one |
42. Document number is not clearly visible |
43. Original document number could not be authenticated |
44. Front and backside images are not of the same document |
45. Proof and additional proof does not belong to the same person |
46. Address proof and document proof does not match |
47. Both documents should belong to the same person |
48. Document doesn’t match the document uploaded at the time of signup |
49. Camera is not accessible for verification |
50. Gender could not be verified |
51. Place of issue could not be verified |
52. The provided document is broken |
53. The provided document is photocopy(color or black & white) |
54. The provided document is edited |
55. The provided document is scanned |
56. The provided document is punched |
57. The provided document is cracked |
58. The provided document is cropped |
59. The provided document is handwritten |
Address
Description |
---|
1. Image of the face not found on the document |
2. Document originality could not be verified |
3. Name on the Address Document doesn't match |
4. Address did not match the record, please provide a document with valid address. |
5. Document type is different from the provided options |
6. Country on the address document could not be verified |
7. Addresses on the Identity Document and Utility Bill do not match |
8. The address document is expired, please upload a document which is not expired |
9. The uploaded image of the document is blur, please provide a clear photo of address document |
10. Document doesn't match the provided options |
11. Issue date on the address document doesn't match |
12. Image is altered or photoshopped |
13. Copy of the image found on web |
14. Proof and Additional Proof are of different documents |
15. Address proof and document proof are of different persons |
16. Front and backside images of the document did not match, please upload images of the same document |
17. Document proof is a screenshot |
18. Document proof is altered/edited |
19. Document proof is paper based which is not accepted |
20. Document proof is punched/broken |
21. Document proof is from another screen |
22. Hologram is missing on the document |
23. Document proof is not fully displayed. |
24. Document is blur |
25. Information on the document proof is not visible |
26. Information on the document is edited |
27. Information on the document is hidden |
28. Document should be from the provided country |
29. Issue date does not match with the provided one |
30. Expiry date does not match with the provided one |
31. Submitted document is expired |
32. Issue date on the document is not clearly visible |
33. Expiry date on the document is not clearly visible |
34. Date of Birth on the document does not match with the provided one |
35. Date of Birth on the document is not clearly visible |
36. Name on the document does not match with the provided one |
37. Name on the document is not clearly visible |
38. Document number does not match with the provided one |
39. Document number is not clearly visible |
40. Original document number could not be authenticated |
41. Address proof and document proof does not match |
42. Both documents should belong to the same person |
43. Address on the document does not match with the provided one |
44. Address provided is invalid |
45. Address on the document is not clearly visible |
46. Address could not be validated |
47. You are not eligible because you doesn't fall in the provided age range |
48. Camera is not accessible for verification |
49. Same ID Document can not be submitted as proof of address |
50. The provided document is broken |
51. The provided document is photocopy(color or black & white) |
52. The provided document is edited |
53. The provided document is scanned |
54. The provided document is punched |
55. The provided document is cracked |
56. The provided document is cropped |
57. The provided document is handwritten |
Consent
Description |
---|
1. Image of the face not found on the document |
2. Consent note information is not correct, please upload a note with valid information |
3. Consent type is different from provided options |
4. Image is altered or photoshopped |
5. Copy of the image found on web |
6. Camera is not accessible for verification |
Background Checks
Description |
---|
1. AML screening failed |
2. AML screening failed. User found in Sanction lists |
3. AML screening failed. User found in Warning lists |
4. AML screening failed. User found in Fitness-Probity lists |
5. AML screening failed. User found in PEP lists |
6. AML screening failed. User found in Adverse-Media lists |
AML For Businesses
Description |
---|
1. AML screening failed |
2. AML screening failed. Business found in Sanction lists |
3. AML screening failed. Business found in Warning lists |
4. AML screening failed. Business found in Fitness-Probity lists |
5. AML screening failed. Business found in PEP lists |
6. AML screening failed. Business found in Adverse-Media lists |
Phone Number
Note:
Verification is declined if a user enters the wrong code consecutively for five times.
If the user is unable to receive code then, user is provide with Code not received option if user clicks the “Code not received” option the verification will be declined automatically (because either the phone number was wrong or unreachable).
Description |
---|
1. Your phone number did not match the record, please provide a valid phone number |
2. Phone number not verified because end-user entered the wrong code multiple times |
3. Phone number not verified because the provided number was unreachable |
Declined Status Code
Sample Decline Reasons Request
//GET /decline/reasons/ HTTP/1.1
//Host: api.shuftipro.com/
//Content-Type: application/json
//Authorization: Basic NmI4NmIyNzNmZjM0ZmNlMTlkNmI4WJRTUxINTJHUw==
// replace "Basic" with "Bearer in case of Access Token"
//Use your Shufti Pro account client id and secret key
var token = btoa("YOUR_CLIENT_ID:YOUR_SECRET_KEY"); //BASIC AUTH TOKEN
// if Access Token
//var token = "YOUR_ACCESS_TOKEN";
//Dispatch request via fetch API or with whatever else which best suits for you
fetch('https://api.shuftipro.com/decline/reasons',
{
method : 'get',
headers : {
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Authorization' : 'Basic ' +token // if access token then replace "Basic" with "Bearer"
}
})
.then(function(response) {
return response.json();
}).then(function(data) {
return data;
});
<?php
$url = 'https://api.shuftipro.com/decline/reasons';
//Your Shufti Pro account Client ID
$client_id = 'YOUR-CLIENT-ID';
//Your Shufti Pro account Secret Key
$secret_key = 'YOUR-SECRET-KEY';
//OR Access Token
//$access_token = 'YOUR-ACCESS-TOKEN';
$auth = $client_id.":".$secret_key; // remove this in case of Access Token
$headers = ['Content-Type: application/json'];
// if using Access Token then add it into headers as mentioned below otherwise remove access token
// array_push($headers, 'Authorization: Bearer ' . $access_token);
//Calling Shufti Pro request API using curl
$response = send_curl($url, $headers, $auth); // remove $auth in case of Access Token
//Get Shufti Pro API Response
$response_data = $response['body'];
//Get Shufti Pro Signature
$exploded = explode("\n", $response['headers']);
// Get Signature Key from Hearders
$sp_signature = null;
foreach ($exploded as $key => $value) {
if (strpos($value, 'signature: ') !== false || strpos($value, 'Signature: ') !== false) {
$sp_signature=trim(explode(':', $exploded[$key])[1]);
break;
}
}
//Calculating signature for verification
// calculated signature functionality cannot be implement in case of access token
$calculate_signature = hash('sha256',$response_data.$secret_key);
if($sp_signature == $calculate_signature){
echo "Response :" . $response_data;
}else{
echo "Invalid signature :" . $response_data;
}
function send_curl($url, $headers, $auth){ // remove $auth in case of Access Token
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $auth); // remove this in case of Access Token
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // remove this in case of Access Token
$html_response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($html_response, 0, $header_size);
$body = substr($html_response, $header_size);
curl_close($ch);
return ['headers' => $headers,'body' => $body];
}
?>
import base64, requests, json, hashlib
from random import randint
'''
Python 2
--------
import urllib2
Python 3
--------
import urllib.request
urllib.request.urlopen(url).read()
'''
url = 'https://api.shuftipro.com/decline/reasons'
# Your Shufti Pro account Client ID
client_id = 'YOUR-CLIENT-ID'
# Your Shufti Pro account Secret Key
secret_key = 'YOUR-SECRET-KEY'
# OR Access Token
# access_token = 'YOUR-ACCESS-TOKEN';
# Calling Shufti Pro request API using python requests
auth = '{}:{}'.format(client_id, secret_key)
b64Val = base64.b64encode(auth.encode()).decode()
# if access token
# b64Val = access_token
# replace "Basic with "Bearer" in case of Access Token
response = requests.get(url,
headers={"Authorization": "Basic %s" % b64Val, "Content-Type": "application/json"})
# Calculating signature for verification
# calculated signature functionality cannot be implement in case of access token
calculated_signature = hashlib.sha256('{}{}'.format(response.content.decode(), secret_key).encode()).hexdigest()
# Convert json string to json object
json_response = json.loads(response.content)
sp_signature = response.headers.get('Signature','')
if sp_signature == calculated_signature:
print ('Response : {}'.format(json_response))
else:
print ('Invalid Signature: {}'.format(json_response))
require 'uri'
require 'net/http'
require 'base64'
require 'json'
url = URI("https://api.shuftipro.com/decline/reasons")
# Your Shufti Pro account Client ID
CLIENT_ID = "YOUR-CLIENT-ID"
# Your Shufti Pro account Secret Key
SECRET_KEY = "YOUR-SECRET-KEY"
# if access token
# ACCESS_TOKEN = "YOUR-ACCESS-TOKEN"
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
header_auth = Base64.strict_encode64("#{CLIENT_ID}:#{SECRET_KEY}")
# if Access Token
# header_auth = ACCESS_TOKEN
request["Content-Type"] = "application/json"
request["Authorization"] = "Basic #{header_auth}" # replace "Basic" with "Bearer" in case of access token
response = http.request(request)
response_headers = response.instance_variable_get("@header")
response_data = response.read_body
sp_signature = !(response_headers['signature'].nil?) ? response_headers['signature'].join(',') : ""
# calculated signature functionality cannot be implement in case of access token
calculated_signature = Digest::SHA256.hexdigest response_data + SECRET_KEY
if sp_signature == calculated_signature
puts response_data
else
puts "Invalid signature"
end
Sample Decline Reason Response
{
"decline_reasons": [
{
"status_code": "SPDR01",
"description": "Face could not be verified"
},
{
"status_code": "SPDR02",
"description": "Image of the face not found on the document"
}
]
}
This end-point returns verification decline reasons with their status codes and descriptions.
Face Status Codes
Status Code | Description |
---|---|
SPDR01 | Face could not be verified |
SPDR19 | Face could not be detected in image, please upload image again with your face clearly visible |
SPDR03 | Image is altered or photoshopped |
SPDR04 | Copy of the image found on web |
SPDR58 | Face in the image is with wearing glasses |
SPDR59 | Face proof is from another screen |
SPDR60 | Face proof is taken from the web |
SPDR61 | More than one face in one image |
SPDR62 | Face proof is a screenshot |
SPDR38 | Face doesn't match the face image uploaded at the time of signup |
SPDR39 | Document doesn’t match the document uploaded at the time of signup |
SPDR43 | Camera is not accessible for verification |
Document & Document Two Status Code
Status Code | Description |
---|---|
SPDR02 | Image of the face not found on the document |
SPDR05 | Names on both the documents do not match |
SPDR06 | Document originality could not be verified |
SPDR07 | Name on the document doesn't match |
SPDR08 | DOB on the document doesn't match |
SPDR14 | Age could not be verified |
SPDR16 | The expiry date of the document does not match the record, please upload a document with valid expiry date |
SPDR10 | Issue date on the document doesn't match |
SPDR09 | Date on the document doesn't match |
SPDR11 | Number on the document doesn't match |
SPDR12 | The issuing country of document is not supported, please upload a valid document |
SPDR13 | Document doesn't match the provided options |
SPDR14 | You are not eligible because you doesn't fall in the provided age range |
SPDR15 | Face on the document doesn't match with camera image |
SPDR17 | The document is expired, please upload a new document which is not expired |
SPDR18 | The uploaded image of the document is blur, please provide a clear photo of document |
SPDR19 | Face could not be detected in image, please upload image again with your face clearly visible |
SPDR03 | Image is altered or photoshopped |
SPDR04 | Copy of the image found on web |
SPDR21 | Proof and Additional Proof are of different documents |
SPDR36 | Both Documents do not belong to the same person |
SPDR42 | Front and backside images of the document did not match, please upload images of the same document |
SPDR47 | Document proof is a screenshot |
SPDR48 | Document proof is altered/edited |
SPDR49 | Document proof is paper based which is not accepted |
SPDR50 | Document proof is punched/broken |
SPDR51 | Document proof is from another screen |
SPDR52 | Hologram is missing on the document |
SPDR53 | Document proof is not fully displayed. |
SPDR54 | Document is blur |
SPDR55 | Information on the document proof is not visible |
SPDR56 | Information on the document is edited |
SPDR57 | Information on the document is hidden |
SPDR67 | Document should be from the provided country |
SPDR68 | Issue date does not match with the provided one |
SPDR69 | Expiry date does not match with the provided one |
SPDR70 | Submitted document is expired |
SPDR71 | Issue date on the document is not clearly visible |
SPDR72 | Expiry date on the document is not clearly visible |
SPDR73 | Date of Birth on the document does not match with the provided one |
SPDR74 | Date of Birth on the document is not clearly visible |
SPDR75 | Name on the document does not match with the provided one |
SPDR76 | Name on the document is not clearly visible |
SPDR77 | Document number does not match with the provided one |
SPDR78 | Document number is not clearly visible |
SPDR79 | Original document number could not be authenticated |
SPDR63 | Front and backside images are not of the same document |
SPDR64 | Proof and additional proof does not belong to the same person |
SPDR65 | Address proof and document proof does not match |
SPDR66 | Both documents should belong to the same person |
SPDR39 | Document doesn’t match the document uploaded at the time of signup |
SPDR43 | Camera is not accessible for verification |
SPDR44 | Gender could not be verified |
SPDR45 | Place of issue could not be verified |
SPDR45 | Place of issue could not be verified |
SPDR86 | E-document data does not match with provided document proof |
SPDR87 | Face on the E-document does not match with selfie |
SPDR88 | Uploaded document is Black and White |
SPDR89 | Uploaded image of the document is edited or cropped |
SPDR90 | Uploaded image is found on the internet |
SPDR91 | Document is laminated |
SPDR92 | Document is scanned or colored copy |
SPDR93 | Document is paper-based or laminated |
SPDR94 | Uploaded document is a test card |
SPDR187 | Nationality could not be verified. |
SPDR190 | The provided document is broken |
SPDR193 | The provided document is photocopy(color or black & white) |
SPDR194 | The provided document is edited. |
SPDR197 | The provided document is scanned |
SPDR200 | The provided document is punched |
SPDR201 | The provided document is cracked |
SPDR202 | The provided document is cropped |
SPDR203 | The provided document is handwritten |
SPDR204 | Document does not belong to GCC countries |
SPDR205 | Document type is not supported. |
SPDR206 | Document type is not allowed. |
SPDR207 | MRZ not detected on the document |
SPDR208 | The provided document is blank |
SPDR209 | Student card is not acceptable |
SPDR210 | Dual cards detected |
SPDR211 | The uploaded document is not supported. |
Address Status Code
Status Code | Description |
---|---|
SPDR02 | Image of the face not found on the document |
SPDR06 | Document originality could not be verified |
SPDR14 | Age could not be verified |
SPDR22 | Name on the Address Document doesn't match |
SPDR23 | Address did not match the record, please provide a document with valid address. |
SPDR24 | Document type is different from the provided options |
SPDR25 | Country on the address document could not be verified |
SPDR26 | Addresses on the Identity Document and Utility Bill do not match |
SPDR27 | The address document is expired, please upload a document which is not expired |
SPDR28 | The uploaded image of the document is blur, please provide a clear photo of address document |
SPDR13 | Document doesn't match the provided options |
SPDR30 | Issue date on the address document doesn't match |
SPDR03 | Image is altered or photoshopped |
SPDR04 | Copy of the image found on web |
SPDR21 | Proof and Additional Proof are of different documents |
SPDR31 | Address proof and document proof are of different persons |
SPDR42 | Front and backside images of the document did not match, please upload images of the same document |
SPDR47 | Document proof is a screenshot |
SPDR48 | Document proof is altered/edited |
SPDR49 | Document proof is paper based which is not accepted |
SPDR50 | Document proof is punched/broken |
SPDR51 | Document proof is from another screen |
SPDR52 | Hologram is missing on the document |
SPDR53 | Document proof is not fully displayed. |
SPDR54 | Document is blur |
SPDR55 | Information on the document proof is not visible |
SPDR56 | Information on the document is edited |
SPDR57 | Information on the document is hidden |
SPDR67 | Document should be from the provided country |
SPDR68 | Issue date does not match with the provided one |
SPDR69 | Expiry date does not match with the provided one |
SPDR70 | Submitted document is expired |
SPDR71 | Issue date on the document is not clearly visible |
SPDR72 | Expiry date on the document is not clearly visible |
SPDR73 | Date of Birth on the document does not match with the provided one |
SPDR74 | Date of Birth on the document is not clearly visible |
SPDR75 | Name on the document does not match with the provided one |
SPDR76 | Name on the document is not clearly visible |
SPDR77 | Document number does not match with the provided one |
SPDR78 | Document number is not clearly visible |
SPDR79 | Original document number could not be authenticated |
SPDR65 | Address proof and document proof does not match |
SPDR66 | Both documents should belong to the same person |
SPDR80 | Address on the document does not match with the provided one |
SPDR81 | Address provided is invalid |
SPDR82 | Address on the document is not clearly visible |
SPDR83 | Address could not be validated |
SPDR14 | You are not eligible because you doesn't fall in the provided age range |
SPDR43 | Camera is not accessible for verification |
SPDR46 | Same ID Document can not be submitted as proof of address |
SPDR88 | Uploaded document is Black and White |
SPDR89 | Uploaded image of the document is edited or cropped |
SPDR90 | Uploaded image is found on the internet |
SPDR91 | Document is laminated |
SPDR92 | Document is scanned or colored copy |
SPDR93 | Document is paper-based or laminated |
SPDR94 | Uploaded document is a test card |
SPDR112 | Country on the address document could not verified |
SPDR188 | Bank Transfer Number could not be verified |
SPDR189 | Tax Identity Number could not be verified |
SPDR190 | The provided document is broken |
SPDR193 | The provided document is photocopy(color or black & white) |
SPDR194 | The provided document is edited. |
SPDR197 | The provided document is scanned |
SPDR200 | The provided document is punched |
SPDR201 | The provided document is cracked |
SPDR202 | The provided document is cropped |
SPDR203 | The provided document is handwritten |
Consent Status Code
Status Code | Description |
---|---|
SPDR02 | Image of the face not found on the document |
SPDR32 | Consent note information is not correct, please upload a note with valid information |
SPDR33 | Consent type is different from provided options |
SPDR03 | Image is altered or photoshopped |
SPDR04 | Copy of the image found on web |
SPDR43 | Camera is not accessible for verification |
Background Checks Status Code
Status Code | Description |
---|---|
SPDR34 | AML screening failed |
SPDR160 | AML screening failed. User found in Sanction lists |
SPDR161 | AML screening failed. User found in Warning lists |
SPDR162 | AML screening failed. User found in Fitness-Probity lists |
SPDR163 | AML screening failed. User found in PEP lists |
SPDR164 | AML screening failed. User found in Adverse-Media lists |
AML For Businesses Status Code
Status Code | Description |
---|---|
SPDR34 | AML screening failed |
SPDR182 | AML screening failed. Business found in Sanction lists |
SPDR183 | AML screening failed. Business found in Warning lists |
SPDR184 | AML screening failed. Business found in Fitness-Probity lists |
SPDR185 | AML screening failed. Business found in PEP lists |
SPDR186 | AML screening failed. Business found in Adverse-Media lists |
Phone Number Status Code
Note:
Verification is declined if a user enters the wrong code consecutively for five times.
If the user is unable to receive code then, user is provide with Code not received option if user clicks the “Code not received” option the verification will be declined automatically (because either the phone number was wrong or unreachable).
Status Code | Description |
---|---|
SPDR35 | Your phone number did not match the record, please provide a valid phone number |
SPDR84 | Phone number not verified because end-user entered the wrong code multiple times |
SPDR85 | Phone number not verified because the provided number was unreachable |
Supported Countries
Shufti Pro provides support for all countries. The country code for each country of the world is stated below. Make sure to use them accordingly.
Country Name | Country Code |
---|---|
1. Afghanistan | AF |
2. Aland Islands | AX |
3. Albania | AL |
4. Algeria | DZ |
5. American Samoa | AS |
6. Andorra | AD |
7. Angola | AO |
8. Anguilla | AI |
9. Antarctica | AQ |
10. Antigua and Barbuda | AG |
11. Argentina | AR |
12. Armenia | AM |
13. Aruba | AW |
14. Australia | AU |
15. Austria | AT |
16. Azerbaijan | AZ |
17. Bahamas | BS |
18. Bahrain | BH |
19. Bangladesh | BD |
20. Barbados | BB |
21. Belarus | BY |
22. Belgium | BE |
23. Belize | BZ |
24. Benin | BJ |
25. Bermuda | BM |
26. Bhutan | BT |
27. Bolivia | BO |
28. Bosnia and Herzegovina | BA |
29. Botswana | BW |
30. Bouvet Island | BV |
31. Brazil | BR |
32. British Indian Ocean Territory | IO |
33. Brunei | BN |
34. Bulgaria | BG |
35. Burkina Faso | BF |
36. Burma (Myanmar) | MM |
37. Burundi | BI |
38. Cambodia | KH |
39. Cameroon | CM |
40. Canada | CA |
41. Cape Verde | CV |
42. Cayman Islands | KY |
43. Central African Republic | CF |
44. Chad | TD |
45. Chile | CL |
46. China | CN |
47. Christmas Island | CX |
48. Cocos (Keeling) Islands | CC |
49. Colombia | CO |
50. Comoros | KM |
51. Congo, Dem. Republic | CD |
52. Congo, Republic | CG |
53. Cook Islands | CK |
54. Costa Rica | CR |
55. Croatia | HR |
56. Cuba | CU |
57. Cyprus | CY |
58. Czech Republic | CZ |
59. Denmark | DK |
60. Djibouti | DJ |
61. Dominica | DM |
62. Dominican Republic | DO |
63. East Timor | TL |
64. Ecuador | EC |
65. Egypt | EG |
66. El Salvador | SV |
67. Equatorial Guinea | GQ |
68. Eritrea | ER |
69. Estonia | EE |
70. Ethiopia | ET |
71. Falkland Islands | FK |
72. Faroe Islands | FO |
73. Fiji | FJ |
74. Finland | FI |
75. France | FR |
76. French Guiana | GF |
77. French Polynesia | PF |
78. French Southern Territories | TF |
79. Gabon | GA |
80. Gambia | GM |
81. Georgia | GE |
82. Germany | DE |
83. Ghana | GH |
84. Gibraltar | GI |
85. Greece | GR |
86. Greenland | GL |
87. Grenada | GD |
88. Guadeloupe | GP |
89. Guam | GU |
90. Guatemala | GT |
91. Guernsey | GG |
92. Guinea | GN |
93. Guinea-Bissau | GW |
94. Guyana | GY |
95. Haiti | HT |
96. Heard Island and McDonald Islands | HM |
97. Honduras | HN |
98. HongKong | HK |
99. Hungary | HU |
100. Iceland | IS |
101. India | IN |
102. Indonesia | ID |
103. Iran | IR |
104. Iraq | IQ |
105. Ireland | IE |
106. Israel | IL |
107. Italy | IT |
108. Ivory Coast | CI |
109. Jamaica | JM |
110. Japan | JP |
111. Jersey | JE |
112. Jordan | JO |
113. Kazakhstan | KZ |
114. Kenya | KE |
115. Kiribati | KI |
116. Korea, Dem. Republic of | KP |
117. Kuwait | KW |
118. Kyrgyzstan | KG |
119. Laos | LA |
120. Latvia | LV |
121. Lebanon | LB |
122. Lesotho | LS |
123. Liberia | LR |
124. Libya | LY |
125. Liechtenstein | LI |
126. Lithuania | LT |
127. Luxemburg | LU |
128. Macau | MO |
129. Macedonia | MK |
130. Madagascar | MG |
131. Malawi | MW |
132. Malaysia | MY |
133. Maldives | MV |
134. Mali | ML |
135. Malta | MT |
136. Man Island | IM |
137. Marshall Islands | MH |
138. Martinique | MQ |
139. Mauritania | MR |
140. Mauritius | MU |
141. Mayotte | YT |
142. Mexico | MX |
143. Micronesia | FM |
144. Moldova | MD |
145. Monaco | MC |
146. Mongolia | MN |
147. Montenegro | ME |
148. Montserrat | MS |
149. Morocco | MA |
150. Mozambique | MZ |
151. Namibia | NA |
152. Nauru | NR |
153. Nepal | NP |
154. Netherlands | NL |
155. Netherlands Antilles | AN |
156. New Caledonia | NC |
157. New Zealand | NZ |
158. Nicaragua | NI |
159. Niger | NE |
160. Nigeria | NG |
161. Niue | NU |
162. Norfolk Island | NF |
163. Northern Mariana Islands | MP |
164. Norway | NO |
165. Oman | OM |
166. Pakistan | PK |
167. Palau | PW |
168. Palestinian Territories | PS |
169. Panama | PA |
170. Papua New Guinea | PG |
171. Paraguay | PY |
172. Peru | PE |
173. Philippines | PH |
174. Pitcairn | PN |
175. Poland | PL |
176. Portugal | PT |
177. Puerto Rico | PR |
178. Qatar | QA |
179. Reunion Island | RE |
180. Romania | RO |
181. Russian Federation | RU |
182. Rwanda | RW |
183. Republic of Kosovo | XK |
184. Saint Barthelemy | BL |
185. Saint Kitts and Nevis | KN |
186. Saint Lucia | LC |
187. Saint Martin | MF |
188. Saint Pierre and Miquelon | PM |
189. Saint Vincent and the Grenadines | VC |
190. Samoa | WS |
191. San Marino | SM |
192. Saudi Arabia | SA |
193. Senegal | SN |
194. Serbia | RS |
195. Seychelles | SC |
196. Sierra Leone | SL |
197. Singapore | SG |
198. Slovakia | SK |
199. Slovenia | SI |
200. Solomon Islands | SB |
201. Somalia | SO |
202. South Africa | ZA |
203. South Georgia and the South Sandwich Islands | GS |
204. South Korea | KR |
205. Spain | ES |
206. Sri Lanka | LK |
207. Sudan | SD |
208. Suriname | SR |
209. Svalbard and Jan Mayen | SJ |
210. Swaziland | SZ |
211. Sweden | SE |
212. Switzerland | CH |
213. Syria | SY |
214. São Tomé and Príncipe | ST |
215. Taiwan | TW |
216. Tajikistan | TJ |
217. Tanzania | TZ |
218. Thailand | TH |
219. Togo | TG |
220. Tokelau | TK |
221. Tonga | TO |
222. Trinidad and Tobago | TT |
223. Tunisia | TN |
224. Turkey | TR |
225. Turkmenistan | TM |
226. Turks and Caicos Islands | TC |
227. Tuvalu | TV |
228. Uganda | UG |
229. Ukraine | UA |
230. United Arab Emirates | AE |
231. United Kingdom | GB |
232. United States | US |
233. United States Minor Outlying Islands | UM |
234. Uruguay | UY |
235. Uzbekistan | UZ |
236. Vanuatu | VU |
237. Vatican City State | VA |
238. Venezuela | VE |
239. Vietnam | VN |
240. Virgin Islands (British) | VG |
241. Virgin Islands (U.S.) | VI |
242. Wallis and Futuna | WF |
243. Western Sahara | EH |
244. Yemen | YE |
245. Zambia | ZM |
246. Zimbabwe | ZW |
247. South Sudan | SS |
Supported Languages
Shufti Pro offers worldwide language coverage. Use the appropriate language code from the list given below.
Languages | Language Code |
---|---|
1. Afrikaans | AF |
2. Albanian | SQ |
3. Amharic | AM |
4. Arabic | AR |
5. Armenian | HY |
6. Azerbaijani | AZ |
7. Basque | EU |
8. Belarusian | BE |
9. Bengali | BN |
10. Bosnian | BS |
11. Bulgarian | BG |
12. Burmese | MY |
13. Catalan | CA |
14. Chichewa | NY |
15. Chinese | ZH |
16. Corsican | CO |
17. Croatian | HR |
18. Czech | CS |
19. Danish | DA |
20. Dutch | NL |
21. English | EN |
22. Esperanto | EO |
23. Estonian | ET |
24. Filipino | TL |
25. Finnish | FI |
26. French | FR |
27. Frisian | FY |
28. Galician | GL |
29. Georgian | KA |
30. German | DE |
31. Greek (modern) | EL |
32. Gujarati | GU |
33. Haitian, Haitian Creole | HT |
34. Hausa | HA |
35. Hebrew (modern) | HE |
36. Hindi | HI |
37. Hungarian | HU |
38. Indonesian | ID |
39. Irish | GA |
40. Igbo | IG |
41. Icelandic | IS |
42. Italian | IT |
43. Japanese | JA |
44. Javanese | JV |
45. Kannada | KN |
46. Kazakh | KK |
47. Khmer | KM |
48. Kirghiz, Kyrgyz | KY |
49. Korean | KO |
50. Kurdish | KU |
51. Latin | LA |
52. Luxembourgish, Letzeburgesch | LB |
53. Lao | LO |
54. Lithuanian | LT |
55. Latvian | LV |
56. Macedonian | MK |
57. Malagasy | MG |
58. Malay | MS |
59. Malayalam | ML |
60. Maltese | MT |
61. Maori | MI |
62. Marathi | MR |
63. Mongolian | MN |
64. Nepali | NE |
65. Norwegian | NO |
66. Punjabi | PA |
67. Persian | FA |
68. Polish | PL |
69. Pashto | PS |
70. Portuguese | PT |
71. Romanian | RO |
72. Russian | RU |
73. Sindhi | SD |
74. Samoan | SM |
75. Serbian | SR |
76. Scottish Gaelic | GD |
77. Shona | SN |
78. Sinhala | SI |
79. Slovak | SK |
80. Slovenian | SL |
81. Somali | SO |
82. Sesotho | ST |
83. Spanish | ES |
84. Sundanese | SU |
85. Swahili | SW |
86. Swedish | SV |
87. Tamil | TA |
88. Telugu | TE |
89. Tajik | TG |
90. Thai | TH |
91. Turkish | TR |
92. Ukrainian | UK |
93. Urdu | UR |
94. Uzbek | UZ |
95. Vietnamese | VI |
96. Welsh | CY |
97. Xhosa | XH |
98. Yiddish | YI |
99. Yoruba | YO |
100. Zulu | ZU |
Supported Browsers and Devices
In case of on-site verification, a verify iframe is shown to users. This iframe is supported on the following list of browsers.
Browsers | Minimum Version/SDK |
---|---|
1. Chrome (Recommended) | 65 |
2. Firefox (Recommended) | 58 |
3. Safari | 8 |
4. Opera | 52 |
5. Internet Explorer | 11 |
6. Edge | 16 |
Here a list of supported operating systems on mobile devices.
Mobile OS | Minimum Version/SDK |
---|---|
1. Android | 6.0 (Marshmallow) |
2. iOS | 10 |
Test ID Samples
The below-provided Test ID Samples for different services can be used either during the testing or the integration process. This facilitates the technical teams to use dummy documents in order to test out the requests, responses, callbacks, etc without having them upload/provide their real identity documents.
Face Test ID Samples
Document/Document Two Test ID Samples
Address Document Test ID Samples
Consent Test ID Samples
Revision History
Date | Description |
---|---|
13 Jan 2023 | Added new Parameter enhanced_originality_checks in verification request. |
25 Oct 2022 | Introduced new service Questionnaire. |
14 Sep 2022 | Added new Parameter check_duplicate_request inside face service in verification request. |
02 Nov 2021 | Added new Parameter manual_review in verification request. |
21 Oct 2021 | Added new Parameter show_ocr_form in document, document_two and address service. |
18 Oct 2021 | Introduced new service Age Verification. |
13 Oct 2021 | Added New Supported types property_tax, lease_agreement, insurance_card, credit_card_statement, insurance_policy, e_commerce_receipt, bank_letter_receipt, birth_certificate, salary_slip, permanent_residence_permit and any for Address service. |
28 Sep 2021 | Added New Parameter in verification_instructions object for document, document_two and address service. |
24 Sep 2021 | Added declined_codes in Background Checks & AML For Businesses. Note: This Feature is currently available for trial accounts and will be available for production accounts from "27 Sep 2021" |
13 July 2021 | Updated php sample code. |
03 June 2021 | dob key in Background Checks Service made optional. |
29 Mar 2021 | face_match_confidence key is now available. |
24 Mar 2021 | Added new endpoint to get all verification decline reasons. |
11 Mar 2021 | Added new key face_match_confidence under the verification_data object in verification response. Note: This Key will be available from "29 MARCH 2021" |
01 Jan 2021 | Introduced new type Others in Gender. |
11 Dec 2020 | Introduced new service OCR For Business. |
20 Nov 2020 | Added New key services_declined_codes in Verification Response. |
04 Nov 2020 | Updated declined reasons. |
04 Nov 2020 | Added New Parameter verification_instructions in document, document_two and address service. |
21 Sep 2020 | Added allow_retry in verification request. |
18 Sep 2020 | Added allow_na_ocr_inputs in verification request. |
08 Sep 2020 | Added ttl in verification request. |
20 Jul 2020 | consent service sample object and test IDs updated. |
14 Jul 2020 | callback_url parameter made optional. |
16 June 2020 | Added New Supported type cpr_smart_card_reader_copy for Address service. |
15 June 2020 | Added full_name key to name object for background checks service. |
11 June 2020 | Added decline_on_single_step in verification request. |
10 June 2020 | Added gender key for document and document_two service. |
19 May 2020 | Added subscription plan details to account info Response. |
08 May 2020 | Added Country Key to Status Responses. |
05 May 2020 | Increased max length of AML for Business Name from 64 to 255. |
16 Apr 2020 | business_incorporation_date in AML for Businesses service made optional. |
08 Apr 2020 | Added video KYC documentation. |
07 Apr 2020 | Added backside_proof_required parameter. |
27 Mar 2020 | Updated Api urls. |
26 Mar 2020 | Added Api flow charts. |
04 Mar 2020 | Temporary access token introduced. |
31 Dec 2019 | Added allow_online in verification request. |
31 Dec 2019 | Biometric SDK documentation added. |
24 Dec 2019 | Added "fetch_enhanced_data" key from Enhanced data extraction for document and document_two service. |
24 Dec 2019 | Removed "allowed_offline" key from address service request object. |
24 Dec 2019 | Updated declined reasons. |
25 Nov 2019 | Added verification_video in status response end-point, inside proof key. Returned only if on-site video is recorded. |
25 Nov 2019 | Added KYC Request Instructions for onsite and offisite verification |
18 Nov 2019 | HTTP status code updated. |
14 Nov 2019 | Request status response sample updated. |
11 Nov 2019 | updated KYB request response |
31 Oct 2019 | Introduced new service Know Your business (KYB). |
24 Oct 2019 | Introduced new service for Businesses AML checks(AML for Businesses). |
10 Oct 2019 | Updated Onsite verification javascript code. |
09 Oct 2019 | Added the show_feedback_form in verification request. |
24 Sep 2019 | Added declined_codes in verification response, for all accounts. |
11 Sep 2019 | Old declined reason added in appendix. |
09 Sep 2019 | Added declined_codes in verification response. Note: This Feature is currently available for trial accounts and will be available for production accounts from "24 Sep 2019" |
09 Sep 2019 | Declined reasons description updated and added status code for each reason. |
27 Aug 2019 | Added full_name key to name object. |
20 Jul 2019 | Updated declined reasons. |
20 Jul 2019 | Added request time out time. |
16 Jul 2019 | Added Ongoing in Background checks. |
15 Jul 2019 | Added info object key in responses date has been extended to 18 Jul 2019. |
04 Jul 2019 | Added info object key in responses just in API documentation. (Shufti Pro API will send this object in response from 15 Jul 2019 ) |
04 Jul 2019 | Added declined reasons for document, document two and address services. |
02 Jul 2019 | Added Rate Limiting for requests. |
12 June 2019 | Added Document Two Service for verification. |
24 May 2019 | Update declined reason. |
22 May 2019 | Added with_face key in consent service. |
03 May 2019 | Added Declined Reasons of verificatiton Request. |
16 Apr 2019 | Added Fuzzy match in Background checks. |
09 Apr 2019 | Added a new endpoint /api/account/info/ to get account info. |
05 Apr 2019 | country key updated. |
11 Mar 2019 | 1. Added new params verification_data, verification_result and declined_reason in verification status endpoint. 2. Added a new event request.received |
07 Mar 2019 | Added issue_date key in address service request parameters. |
20 Feb 2019 | Added selected_type key in address, document, consent services webhook/callback response. |
19 Feb 2019 | 1. Added show_consent and show_privacy_policy parameters in verification request. 2. Added address_fuzzy_match parameter in address service. 3. Added allow_offline parameter in face, document, address and consent services. |
18 Feb 2019 | Signature key added into SP Http, Callback headers for signature validation. |
28 Jan 2019 | 1. Added a new endpoint /api/delete to delete a request data. 2. Added a new event request.deleted which is returned whenever a request is deleted. 3. Status response now returns proofs also. 4. Added show_results key in request which allows end-users to see verification results. |
24 Jan 2019 | Added a new callback with event verification.status.changed. It is sent to clients whenever a verification status is updated. |
21 Dec 2018 | Corrected the get status request url. |
20 Dec 2018 | Corrected verification.cancelled event name from events listing. |
06 Dec 2018 | Minimum characters limit is set to 1 for first, middle and last name. |
29 Nov 2018 | Updated POSTMAN collection link, removed format key and added supported_types key for consent service in POSTMAN collection. |
26 Nov 2018 | Added allow_offline key in request parameters. |
29 Oct 2018 | Allowed PDF documents as proofs in image_only and any verification modes. |
29 Oct 2018 | Changed format key to Supported_types in consent Service. |
22 Oct 2018 | Added declined reason key in response. |
17 Oct 2018 | Updated Test IDs for demo/test verifications. |
09 Oct 2018 | 1. Last name field made optional in all name objects. 2. Added signature in response headers to validate the source of responses. |