VeriLink API Documentation

Integrate facial recognition and identity verification into your applications

Overview

The VeriLink API provides secure, scalable identity verification services powered by advanced Facial Verification technology.

Secure by Design

End-to-end encryption, GDPR compliance, and SOC 2 Type II certified infrastructure.

High Performance

99.9% uptime SLA, sub-second response times, and global CDN distribution.

Authentication & Licensing

All API requests require valid authentication using your VeriLink API key and license key.

API Authentication

To use the VeriLink API, you must provide two required authentication fields with every request:

Required Fields
  • ApiKey - Your unique VeriLink API key
  • LicKey - Your VeriLink license key
Where to Get Them
  • API Key: Available in your VeriLink dashboard
  • License Key: Provided when you purchase a VeriLink license
License Validation: Your credentials are validated against our xCrypt licensing system to ensure your account is active and has sufficient permissions.
Security Features

The authentication system provides several security benefits:

Request Security
  • All requests are validated against your license
  • Rate limiting per API key
  • Request logging and monitoring
Access Control
  • Company-specific data isolation
  • Usage tracking and billing
  • Automatic license expiration handling
Important: Never expose your API key or license key in client-side code or public repositories. Always keep these credentials secure.
Common Authentication Errors

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
Testing: Use the API Testing section below to verify your authentication credentials before implementing in production.

API Endpoints

Base URL: https://app.verilink.online/authenticate

POST
Identity Verification
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.

Authentication Required: You must provide a valid API key and license key for authentication. These are validated against our xCrypt licensing system.
Unique ID: You can now provide your own unique identifier for each verification request. This field must not contain any spaces and will be used to track and identify your specific verification requests.
Data Object Structure
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
    }
}
Required Fields
Mandatory Fields
  • Company - Your company name
  • TrgEmail - 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 key
  • LicKey - Your VeriLink license key
Optional Fields
  • ImageUrl - URL to user's image for verification
  • ReturnUrl - Your callback endpoint
  • ReturnIdentifier - Your company token
PHP cURL Example
// 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);
Response Codes
New Response Format: The API now returns structured responses with success status, message, and error codes for better error handling.
Success Response
{
    "success": true,
    "message": "Data received and sent to user."
}
Error Response
{
    "success": false,
    "message": "Error description",
    "code": 10
}
Error Codes Reference
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
License Validation: Your API key and license key are validated against our xCrypt licensing system. Invalid credentials will result in error code 14.
Expected Return Example
// 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);
Important: VeriLink will send the verification results back to your return URL as a JSON-encoded POST request. Ensure your endpoint is configured to handle JSON data and parse the response accordingly.
Available Options
Verify Options
  • Face - Perform facial recognition verification
  • Liveliness - Check if the person is live (not a photo)
NeededInfo Options
  • IdNumber - Return the user's ID number
  • Location - Return location data
  • FaceEncodings - Return face encoding data
Note: Face and ID verification are conducted during user onboarding to the VeriLink app. This service enables companies to confirm a person's identity by verifying facial features and/or liveliness. If required, additional data—such as ID number, location, or facial encodings—can be returned to the company for further validation.
Image URL: The optional ImageUrl field allows you to provide a direct link to the user's image for verification. This can be useful for pre-verification or when you have existing user images.
POST
CIF Data Transfer
Your Server URL (configurable)

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

Data Transfer: When a user completes verification in the VeriLink app and chooses to share data with your server, the app will automatically send the requested information to your configured endpoint.
Data Structure Sent to Your Server
{
  "endpoint": "https://app.verilink.online/get-cif-data",
  "token": "generated_verification_token",
  "target": "your_server_url_or_email"
}
Important: This is NOT the actual user data. This is a request object that your server must use to retrieve the actual CIF data from our endpoint.
What Your Server Needs to Do

When you receive this payload, your server must:

  1. Extract the endpoint, token, and target values
  2. Make a POST request to https://app.verilink.online/get-cif-data
  3. Send the token and target to retrieve the actual user data
  4. Process the returned CIF data
Complete PHP Implementation Example
<?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"]);
?>
Expected Response from Your Server

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)
Note: Your server must make the request to VeriLink to get the actual user data. The initial payload only contains the request parameters.
Potential Error Responses

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"
}
Error Handling: Always check the success field and handle the errorType appropriately in your application. The message field provides human-readable error descriptions.
Data Flow Summary
  1. Step 1: VeriLink app sends request object to your server
  2. Step 2: Your server extracts token and target from the request
  3. Step 3: Your server makes POST request to https://app.verilink.online/get-cif-data
  4. Step 4: VeriLink returns the actual CIF data
  5. Step 5: Your server processes the user data
Important: The data sent to your server is based on what the user has agreed to share via the app.
Security Note: The verification token is unique for each data transfer and can be used to validate the specific verification request - the data is available for 24 hours.
POST
CIF Data Retrieval
https://app.verilink.online/get-cif-data

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

Data Retrieval: You can access their shared CIF data by providing the token you received and the server URL where the data was sent.
Request Structure
{
  "token": "verification_token",
  "target": "server_url_or_email"
}
PHP cURL Example
<?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;
}
?>
JavaScript Fetch Example
// 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);
});
Response Structure
// 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"
}
Complete Response Examples

Here are real examples of what you'll receive from the get-cif-data endpoint:

Passport Response
{
    "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"
        }
    }
}
Identity Document Response
{
    "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"
        }
    }
}
Note: The 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.
Error Types
Common Error Types
  • method - Invalid HTTP method (only POST allowed)
  • invalid - Missing parameters or invalid format
  • expired - Token has expired (24-hour limit)
  • corrupted - Data corruption detected
  • database - Server database error
HTTP Status Codes
  • 200 - Success
  • 400 - Bad Request (invalid parameters)
  • 405 - Method Not Allowed
  • 500 - Internal Server Error
Important: CIF data links are only valid for 24 hours for security reasons. After expiration, the data is automatically deleted from the system.
Note: The target parameter should match exactly what was used when the data was originally sent via the CIF Data Transfer endpoint.

Test the API

To test the VeriLink API, please sign up as a company to get access to our testing environment and API credentials.

API Testing