Integrate facial recognition and identity verification into your applications
The VeriLink API provides secure, scalable identity verification services powered by advanced Facial Verification technology.
End-to-end encryption, GDPR compliance, and SOC 2 Type II certified infrastructure.
99.9% uptime SLA, sub-second response times, and global CDN distribution.
All API requests require valid authentication using your VeriLink API key and license key.
To use the VeriLink API, you must provide two required authentication fields with every request:
ApiKey - Your unique VeriLink API keyLicKey - Your VeriLink license keyThe authentication system provides several security benefits:
Understanding common authentication errors can help you troubleshoot issues:
| Code | Description | Solution |
|---|---|---|
14 |
Invalid license or API key | Verify your credentials in the dashboard |
401 |
Company not found or inactive | Contact VeriLink support |
403 |
License expired or suspended | Renew your license or contact support |
Base URL: https://app.verilink.online/authenticate
You are required to send an object that has been JSON-encoded and then Base64-encoded. This object should include the following fields, allowing you to specify the verification steps needed for the client.
data: {
"Company": "YourCompanyName",
"TrgEmail": "john@doe.com", #User Email that is already Verilinked
"UserFullName": "FirstName_LastName", #add _middlename if a client has one
"UniqueID": "unique_identifier", #your unique identifier (no spaces allowed)
"ImageUrl": "https://example.com/image.jpg", #optional: URL to user's image for verification
"ApiKey": "your_api_key_here", #required: your VeriLink API key
"LicKey": "your_license_key_here", #required: your VeriLink license key
"ReturnUrl": "https://your-domain.com/return-endpoint",
"ReturnIdentifier": "company-token", #Found in the verilink dashboard
"Verify": {
"Face": true,
"Liveliness": true
},
"NeededInfo": {
"IdNumber": true,
"Location": false,
"FaceEncodings": false
}
}
Company - Your company nameTrgEmail - User's email (must be already VeriLinked)UserFullName - User's full name (use underscores to separate)UniqueID - Your unique identifier (no spaces allowed)ApiKey - Your VeriLink API keyLicKey - Your VeriLink license keyImageUrl - URL to user's image for verificationReturnUrl - Your callback endpointReturnIdentifier - Your company token// Define expected options
$expectedVerify = ['Face', 'Liveliness'];
$expectedInfo = ['IdNumber', 'Location', 'FaceEncodings'];
// Create base object
$veriData = (object)[];
$veriData->Company = $CompanyName;
$veriData->UserFullName = $FirstName . "_" . $MiddleName . "_" . $LastName;
$veriData->UniqueID = $UniqueID;
$veriData->ImageUrl = $ImageUrl; // Optional: URL to user's image
$veriData->ApiKey = $YourApiKey; // Required: Your VeriLink API key
$veriData->LicKey = $YourLicenseKey; // Required: Your VeriLink license key
$veriData->ReturnUrl = "https://yourdomain.com/endpoint";
$veriData->ReturnIdentifier = $CompanyToken;
// Add Verify object
$veriData->Verify = (object)[];
foreach ($expectedVerify as $key) {
$veriData->Verify->$key = in_array($key, $selFaceOpts);
}
// Add NeededInfo object
$veriData->NeededInfo = (object)[];
foreach ($expectedInfo as $key) {
$veriData->NeededInfo->$key = in_array($key, $selFaceOpts);
}
// Encode to base64 JSON string
$encodedData = base64_encode(json_encode($veriData));
// Send via cURL
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://app.verilink.online/authenticate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array("data" => $encodedData),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
{
"success": true,
"message": "Data received and sent to user."
}
{
"success": false,
"message": "Error description",
"code": 10
}
| Code | Description | Action Required |
|---|---|---|
10 |
Unique ID already exists | Choose another unique identifier |
14 |
Invalid license or API key | Verify your API key and license key |
401 |
Company not found or inactive | Contact VeriLink support |
400 |
Missing or invalid data field | Check request format |
405 |
Method not allowed | Use POST method only |
422 |
Invalid or missing required fields | Verify all required fields are present |
// Step 5: Send to returnUrl via cURL
$dataToPost = [
"scannedData" => $scannedDataSent, #scannedData in Verilink
"idNumber" => $idNumber,
"address" => $address,
"faceEncD" => $faceEncD,
"verified" => $verified
];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $returnUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
CURLOPT_POSTFIELDS => json_encode($dataToPost)
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
Face - Perform facial recognition verificationLiveliness - Check if the person is live (not a photo)IdNumber - Return the user's ID numberLocation - Return location dataFaceEncodings - Return face encoding dataThis endpoint receives CIF (Customer Information File) data from the VeriLink app when users choose to share their verified information with your server. The data is sent as a JSON payload containing user verification results and requested information.
{
"endpoint": "https://app.verilink.online/get-cif-data",
"token": "generated_verification_token",
"target": "your_server_url_or_email"
}
When you receive this payload, your server must:
endpoint, token, and target valueshttps://app.verilink.online/get-cif-datatoken and target to retrieve the actual user data<?php
// Your server endpoint to receive CIF data request
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(400);
echo json_encode(["status" => "error", "message" => "Only POST allowed"]);
exit;
}
// Get the raw input data
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (!$data || !isset($data['endpoint'], $data['token'], $data['target'])) {
http_response_code(400);
echo json_encode(["status" => "error", "message" => "Missing required fields"]);
exit;
}
// Now make a request to VeriLink to get the actual CIF data
$ch = curl_init();
$postData = [
'token' => $data['token'],
'target' => $data['target']
];
curl_setopt_array($ch, [
CURLOPT_URL => $data['endpoint'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
http_response_code(500);
echo json_encode(["status" => "error", "message" => "Failed to retrieve CIF data: " . $curlError]);
exit;
}
if ($httpCode !== 200) {
http_response_code($httpCode);
echo json_encode(["status" => "error", "message" => "VeriLink returned HTTP " . $httpCode]);
exit;
}
// Parse the response from VeriLink
$cifData = json_decode($response, true);
if (!$cifData || !isset($cifData['success']) || !$cifData['success']) {
http_response_code(500);
echo json_encode(["status" => "error", "message" => "Invalid response from VeriLink"]);
exit;
}
// Now you have the actual user data in $cifData['cifData']
$userData = $cifData['cifData'];
// Process the user data as needed
// ... your business logic here ...
// Return success response
http_response_code(200);
echo json_encode(["status" => "success", "message" => "CIF data processed successfully"]);
?>
Your server should respond with an HTTP status code:
// Success Response
HTTP 200 OK
{
"status": "success",
"message": "CIF data processed successfully"
}
// Error Response (if validation fails)
HTTP 400 Bad Request
HTTP 405 Method Not Allowed (if not POST)
HTTP 500 Internal Server Error (if VeriLink request fails)
When making requests to https://app.verilink.online/get-cif-data, you may encounter these error responses:
// Link expired (24-hour limit)
{
"success": false,
"message": "This link has expired. CIF links are only valid for 24 hours for security reasons.",
"errorType": "expired"
}
// Invalid or expired link
{
"success": false,
"message": "Invalid or expired link. Please check your email for the correct link.",
"errorType": "invalid"
}
// Data corruption
{
"success": false,
"message": "Error processing the CIF data. The information may be corrupted.",
"errorType": "corrupted"
}
// Database error
{
"success": false,
"message": "An error occurred while processing your request. Please try again later.",
"errorType": "database"
}
// Method not allowed
{
"success": false,
"message": "Method not allowed",
"errorType": "method"
}
// Missing parameters
{
"success": false,
"message": "Missing required parameters",
"errorType": "invalid"
}
success field and handle the errorType appropriately in your application. The message field provides human-readable error descriptions.
https://app.verilink.online/get-cif-dataThis endpoint allows you to retrieve a users CIF data using a verification token and target server URL. The data is retrieved from the database and returned in its original format.
{
"token": "verification_token",
"target": "server_url_or_email"
}
<?php
// Retrieve CIF data using token and target
$curl = curl_init();
$postData = [
'token' => 'your_verification_token',
'target' => 'https://your-server.com/endpoint'
];
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://app.verilink.online/get-cif-data',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_HTTPHEADER => array('Content-Type: application/json')
));
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode === 200) {
$result = json_decode($response, true);
if ($result['success']) {
$cifData = $result['cifData'];
// Process the retrieved CIF data
echo "Data retrieved successfully";
} else {
echo "Error: " . $result['message'];
}
} else {
echo "HTTP Error: " . $httpCode;
}
?>
// Retrieve CIF data using fetch
fetch('https://app.verilink.online/get-cif-data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: 'your_verification_token',
target: 'https://your-server.com/endpoint'
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('CIF Data:', data.cifData);
// Process the retrieved data
} else {
console.error('Error:', data.message);
}
})
.catch(error => {
console.error('Network error:', error);
});
// Success Response if Identity Document details have been sent back
{
"success": true,
"cifData": {
"id_text": {
"id_number": "",
"name": "",
"raw_pdf417": "",
"surname": "",
"timestamp": ""
},
"encoded_face": [],
"geo": {
"latlong": "-0.000,0.000",
"address": ""
}
}
}
// Success Response if Passport details have been sent back
{
"success": true,
"cifData": {
"id_text": {
"birth_yyMMdd": "",
"expiry_yyMMdd": "",
"given_names": "",
"passport_number": "",
"personal_number": "", // Their Identity Number
"surname": "",
"timestamp": ""
},
"encoded_face": [],
"geo": {
"latlong": "-0.000,0.000",
"address": ""
}
}
}
// Error Response
{
"success": false,
"message": "Error description",
"errorType": "error_category"
}
Here are real examples of what you'll receive from the get-cif-data endpoint:
{
"success": true,
"cifData": {
"id_text": {
"given_names": "John Michael",
"passport_number": "A12345678",
"personal_number": "8001015009087",
"surname": "Doe",
"timestamp": "2025-01-15 10:30:00"
},
"encoded_face": [
1875,
0.0427042543888092041015625,
0.063398890197277069091796875
],
"geo": {
"latlong": "-0.5299693,31.2178009",
"address": "123 Main Street, City"
}
}
}
{
"success": true,
"cifData": {
"id_text": {
"id_number": "8001015009087",
"name": "John",
"surname": "Doe",
"timestamp": "2025-01-15 10:30:00"
},
"encoded_face": [
-0.18225237727165222,
0.13458076119422913
],
"geo": {
"latlong": "-0.529952,31.2178194",
"address": "456 Oak Avenue, Town"
}
}
}
encoded_face array contains facial recognition data that can be used for identity verification. The geo object contains location information if the user consented to share it.
method - Invalid HTTP method (only POST allowed)invalid - Missing parameters or invalid formatexpired - Token has expired (24-hour limit)corrupted - Data corruption detecteddatabase - Server database error200 - Success400 - Bad Request (invalid parameters)405 - Method Not Allowed500 - Internal Server ErrorTo test the VeriLink API, please sign up as a company to get access to our testing environment and API credentials.