Verifymy API Integration Guide
Overview
Welcome to the developer documentation for integrating our age assurance solution.
The Verifymy age assurance solution provides users with a range of convenient and privacy-preserving age verification and estimation methods to meet your platform's and its users' individual needs.
This developer documentation will guide you through the implementation steps for both mobile and web.
Before you starting the integration, please ensure you have:
- API Credentials: Contact our Customer Success team to request access to the API credentials needed for integration.
- Redirect URL: Register a valid redirect URL where users will be redirected after completing the verification process. This can be done in the "Developers" menu of your admin dashboard.
Integration Flow
A simplified view of the Verifymy integration:
The integration follows the standard OAuth flow:
- Get a verification URL from Verifymy
- Send your user to complete verification
- Receive the user back with an authorization code
- Exchange the code for an access token
API Integration
This section covers direct integration with the Verifymy RESTful API endpoints. Use this approach when you need maximum flexibility or are working with a programming language not supported by our SDKs.
Environments
Environment | Base URL | Purpose |
---|---|---|
Sandbox | https://sandbox.verifymyage.com | Testing and development |
Production | https://oauth.verifymyage.com | Live data and real-world use |
Each environment requires separate API keys. Do not use the same keys for both environments.
Authentication
All API requests must be authenticated using either:
- HMAC Authentication - For requests that require payload signing
- Basic Authentication - For token exchange
The HMAC header is required for requests with payloads to ensure data integrity.
Authorization: hmac {api_key}:{hmac_signature}
Where hmac_signature
is calculated as:
hmac_signature = HMAC-SHA256(request_body, api_secret)
$api_key = 'YOUR_API_KEY';
$api_secret = 'YOUR_API_SECRET';
$request_body = json_encode($payload);
$hmac_signature = hash_hmac('sha256', $request_body, $api_secret);
$hmac_header_value = 'hmac ' . $api_key . ':' . $hmac_signature;
// Add to your request headers
$headers = [
'Authorization' => $hmac_header_value,
'Content-Type' => 'application/json'
];
Basic Authentication
For token exchange, use Basic Authentication with your API key and secret:
Authorization: Basic {base64_encoded_credentials}
Where base64_encoded_credentials
is the Base64 encoding of {api_key}:{api_secret}
.
$headers = [
'Authorization' => 'Basic ' . base64_encode(
$apiKey . ':' . $apiSecret
)
];
Verification Flow
The verification process consists of 3 steps:
- Generate a verification URL
- Exchange code for access token
- Check verification status
Step 1: Generate Verification URL
This endpoint generates the URL to redirect your user to and starts the verification flow. The stealth parameter should be included as a query parameter, while all other parameters should be in the request body.
POST /v2/auth/start
Content-Type: application/json
Authorization: hmac {api_key}:{hmac_signature}
{
"redirect_url": "https://your-website.com/callback",
"country": "gb"
}
Query Parameters
Parameter | Required | Description |
---|---|---|
stealth | No | When set to true , attempts to verify the user in the background without redirecting them. |
Request Body Parameters
Parameter | Required | Description |
---|---|---|
redirect_url | Yes | URL that the user will be redirected to after verification |
country | Yes | 2-letter ISO country code (gb, de, fr, us) |
method | No | Directs the user to try to verify using this method (more information below) |
business_settings_id | No | ID containing your account configuration including the verification methods which will be made available to your users |
external_user_id | No | Your system's UUID to identify the user |
verification_id | No | UUID to identify a verification |
user_info | No | Contains the users encrypted email address or mobile number if you wish to perform a background age check (more information below) |
Method Parameter
Using the method parameter will direct the user to verify using the method you specify first.
If this parameter isn’t used, the user will be presented with a list of verification methods you have made available to them.
You can use the method
parameter with one of the following values:
Method Name | Description |
---|---|
AgeEstimation | An age estimation method based on a person’s facial features captured in a short selfie video. |
An age estimation method that uses only an email address to accurately determine user age while preserving privacy. | |
IDScan | An age verification method that uses ID scanning to determine a user’s exact age. |
IDScanFaceMatch | An age verification method that uses government-issued IDs to determine a user's age and employs face match technology to verify ID ownership. |
Mobile | An age verification method confirming the phone is in the possession of and authorised for use by a person aged 18+. |
CreditCard | An age verification method using credit card authorisation to confirm age. |
DoubleBlind | The user uploads a scan of their ID and a selfie to match them to their ID via a 3rd party to ensure complete anonymity. |
Example Request with Specific Verification Method
This example shows how to request a specific verification method instead of relying on the default method for a country:
POST /v2/auth/start
Content-Type: application/json
Authorization: hmac {api_key}:{hmac_signature}
{
"redirect_url": "https://your-website.com/callback",
"method": "IDScanFaceMatch",
"external_user_id": "user-12345"
}
Tip
You can specify a method directly without providing a country code. This is useful for global applications where you want to use the same verification method regardless of the user's location.
User Info Parameter
Here you can utilise user data collected during the account creation process or other interactions on your site to perform a background age check.
If using the user_info
parameter, you must set stealth
to true
and provide at least the user's email address or mobile number.
{
"user_info": {
"email": "encrypted_email_address",
"phone": "encrypted_phone_number"
}
}
When using the user_info parameter, you should be prepared to handle two different response formats:
When the background age check succeeds:
{
"verification_id": "682248a4c026ee49c709bf09",
"verification_status": "approved"
}
When the background age check fails or isn't available:
{
"start_verification_url": "https://sandbox.verifymyage.com/start/verification/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"verification_id": "682248a4c026ee49c709bf09",
"verification_status": "started"
}
User Information Encryption Example
This example demonstrates how to encrypt user information sent in the user_info parameter.
clientSecret, true), 0, 32);
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($text, 'AES-256-CFB', $secretHash, OPENSSL_RAW_DATA, $iv);
$ciphertext_base64 = base64_encode($iv . $ciphertext);
return $ciphertext_base64;
}
$clientSecret = 'your_api_secret_key';
// User information to encrypt
$email = '[email protected]';
$phone = '+44111111111';
// Encrypt user information
$encryptedEmail = $this->encrypt($email);
$encryptedPhone = $this->encrypt($phone);
// Create payload with encrypted data
$payload = [
'user_info' => [
'email' => $encryptedEmail,
'phone' => $encryptedPhone
],
'redirect_url' => 'https://your-website.com/callback',
'country' => 'gb',
];
// JSON encode for the request
echo json_encode($payload, JSON_PRETTY_PRINT);
// API endpoint with stealth parameter in query string
$endpoint = '/v2/auth/start?stealth=true';
?>
This Python example requires the cryptography library. Install it with:
pip install cryptography
Ensure you're using the correct API secret from the appropriate environment (sandbox or production). Using the wrong secret will result in encryption that cannot be decrypted by the Verifymy service.
Error Responses
Status Code | Message | Description |
---|---|---|
400 | {"message": "invalid request", "status_code": 400} | The request format is incorrect |
401 | {"message": "unauthorized", "status_code": 401} | Invalid API key or HMAC |
500 | {"message": "Internal Server Error", "status_code": 500} | Server error |
Step 2: Exchange Code for Access Token
After the user completes their verification they will be redirected to your redirect_url. A code
query parameter is added to this url which you will use in this step to request an access token to retrieve the users verification status in the next step.
POST /oauth/token
Content-Type: application/json
Authorization: Basic {base64_encoded_credentials}
{
"code": "CODE-RECEIVED-IN-REDIRECT"
}
Request Parameters
Parameter | Required | Description |
---|---|---|
code | Yes | The code received in the redirect |
Sample Response
{
"access_token": "ACCESS-TOKEN-VALUE"
}
Error Responses
Status Code | Message | Description |
---|---|---|
401 | {"message": "invalid client credentials", "status_code": 401} | Invalid credentials |
401 | {"message": "Unauthorized redirect_url", "status_code": 401} | Redirect URL not allowed |
500 | {"message": "Internal Server Error", "status_code": 500} | Server error |
Step 3: Check Verification Status
Using the access token you received in the previous step you can now retrieve the user's verification status.
GET /users/me?access_token={ACCESS-TOKEN-VALUE}
Response Parameters
Parameter | Description |
---|---|
age_verified | Boolean indicating verification status which will be “true” for a successful verification, or “false” for an unsuccessful verification |
id | Unique identifier for the verification |
threshold | The minimum age your users must be to successfully pass verification (default is set to 18) |
Sample Response
{
"age_verified": true,
"id": "ABC-12345-DEF-64321",
"threshold": 18
}
Error Responses
Status Code | Message | Description |
---|---|---|
400 | {"message": "malformed token", "status_code": 400} | Invalid token format |
500 | {"message": "error trying to save verification", "status_code": 500} | Database error |
500 | {"message": "Internal Server Error", "status_code": 500} | Server error |
SDK Integration
This section covers integration with Verifymy using our dedicated Software Development Kits (SDKs), which provide pre-built components and simplified methods for different programming languages.
Available SDKs
We provide SDKs for multiple languages to simplify integration:
SDK Installation Instructions
PHP
composer require verifymyage/oauth
{
"require": {
"verifymyage/oauth": "^1.0"
}
}
Requirements:
- PHP 7.4 or higher
- Composer
- PHP cURL extension
PHP SDK Example
<?php
use VerifyMyAgeOAuthV2;
use VerifyMyAgeCountries;
use VerifyMyAgeMethods;
// Initialize the OAuth client
$oauth = new OAuthV2(
clientID: 'your-client-id',
clientSecret: 'your-client-secret',
redirectURL: 'https://your-app.com/callback'
);
// Use sandbox for development
$oauth->useSandbox();
// Step 1: Generate verification URL
$verificationUrl = $oauth->getVerificationUrl([
'country' => Countries::GB,
'redirect_url' => 'https://your-website.com/callback'
]);
// Step 2: Exchange code for token (in your callback endpoint)
$accessToken = $oauth->exchangeCodeByToken($_GET['code']);
// Step 3: Check verification status
$user = $oauth->user($accessToken);
if ($user['age_verified']) {
// User is verified, allow access
} else {
// User is not verified, deny access
}
Verifymy on Native Mobile Device
This guide explains how to integrate the Verifymy verification flow within a WebView for iOS and Android applications.
Prerequisites
- Verifymy API credentials:
- API Key
- Secret Key
- Your application's callback URL is registered with Verifymy
General Requirements
- WebView must have JavaScript enabled
- Camera permissions must be requested and granted for ID verification
- Local Storage must be enabled
- HTTPS connections must be allowed
- Redirect handling must be implemented for the callback URL
Example Implementation
Complete Examples Available:
Android:
Download Android Example - Kotlin implementation with WebView integration, camera handling, and verification logic.
iOS:
Download iOS Example - Swift implementation with WKWebView integration and verification support.
Implementation Checklist
Use this checklist to ensure you've completed all necessary steps for a successful integration.
Android Implementation
Setup
- Add your API credentials in Constants.kt:
const val API_KEY = "your_api_key"
const val API_SECRET_KEY = "your_api_secret"
- Configure your callback URL:
const val CALLBACK_URL = "your-app://callback"
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- For callback URL handling -->
<data
android:scheme="your-app"
android:host="callback" />
WebView Configuration
webView.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
mediaPlaybackRequiresUserGesture = false // Important for camera access
databaseEnabled = true
}
// Handle callbacks
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
val url = request.url.toString()
if (url.startsWith(CALLBACK_URL)) {
// Extract verification code
val uri = Uri.parse(url)
val code = uri.getQueryParameter("code")
if (code != null) {
// Call status verification API
verifyStatus(code)
}
return true
}
return false
}
}
iOS Implementation
Setup
Add to Info.plist:
NSCameraUsageDescription
Camera access is required for ID verification
NSMicrophoneUsageDescription
Microphone access may be required for video verification
URL Handling
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url,
url.absoluteString.starts(with: YOUR_CALLBACK_URL) {
// Handle callback URL
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
}
Best Practices
1. Error Handling
- Implement proper error handling for network issues
- Show user-friendly error messages
- Provide retry options when appropriate
2. Security
- Use HTTPS for all network communications
- Never store API credentials in client-side code
- Implement proper HMAC signing for API requests
- Validate callback parameters
3. User Experience
- Show loading indicators during verification
- Handle device rotation appropriately
- Implement proper back button handling
- Provide clear feedback on camera permissions
4. Testing
- Test with different device types and OS versions
- Verify camera functionality
- Test poor network conditions
- Verify callback handling
Common Issues
1. Camera Not Working
- Ensure proper permissions are requested
- Verify WebView settings allow camera access
- Check for HTTPS connection
2. Callback Not Received
- Verify callback URL is registered correctly
- Check URL handling implementation
- Verify network connectivity
3. Session Issues
- Ensure cookies are enabled
- Verify proper handling of redirects
- Check for proper CORS settings
4. Console Warnings
The following warnings may appear in the console:
[Violation] Permissions policy violation: accelerometer is not allowed in this document
The deviceorientation events are blocked by permissions policy. See https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features
The devicemotion events are blocked by permissions policy. See https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features
These warnings can be safely ignored. They do not affect the verification process since they are related to a third-party library.
Troubleshooting
This section provides solutions to common integration issues and helpful debugging tips.
Common Issues
HMAC Authentication Failures
Ensure your API key and secret are correct
Verify that you're using the exact request body for HMAC calculation
Check that your HMAC header format is correct: hmac {api_key}:{hmac_signature}
Tip:
If you're having trouble with HMAC authentication, try using our SDK which handles HMAC calculation for you.
Redirect URL Unauthorized
- Make sure the redirect_url is registered in your allowed redirect URLs
- Check for exact matching including protocol (http/https) and trailing slashes
Common mistake:
https://example.com/callback
and https://example.com/callback/
are considered different URLs. Register both if needed.
Verification Flow Interruptions
- Ensure your redirect_url endpoint is properly handling the code parameter
- Verify that your server can make outbound HTTPS requests
- Check that your server's IP is not blocked by any firewall
Testing tip:
Use our Postman collection to verify each step of the flow independently.
API Error Codes
Common error status codes and their resolutions:
Status | Error | Resolution |
---|---|---|
400 | Bad Request | Check that your request format and parameters are correct |
401 | Unauthorized | Verify API credentials and HMAC signature |
403 | Forbidden | Your credentials are valid but you lack permission for this action |
429 | Too Many Requests | Implement rate limiting in your application |
500 | Server Error | Contact support with your request details and timestamp |