ID Document Verification
Verify government-issued identity documents across 54 African countries. AfriRoute extracts data with AI-powered OCR, validates document authenticity, and optionally matches the document photo against a live selfie in a single API call.
Supported documents include national IDs, passports, driver's licenses, and voter IDs, plus country-specific registries such as Nigeria's BVN, Ethiopia's Fayda, and the Ghana Card.
🚀 Quick Start
curl -X POST https://api.afriroute.ai/api/v1/identity/verify-id \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_type": "national_id",
"country": "ET",
"image_front": "<base64-encoded-image>",
"image_selfie": "<base64-encoded-selfie>",
"customer_info": {
"full_name": "Abebe Kebede",
"id_number": "ET123456789"
},
"callback_url": "https://yourapp.com/identity/callback"
}'
📡 Endpoints
Verify ID Document
POST /v1/identity/verify-id
Performs OCR extraction, authenticity detection, and — when a selfie is supplied — face matching and liveness in one request.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
document_type | string | Yes | national_id, passport, drivers_license, or voter_id |
country | string | Yes | ISO 3166-1 alpha-2 code (e.g. ET, NG, GH) |
image_front | string | Yes | Base64-encoded front image of the document |
image_back | string | No | Base64-encoded back image (required for some IDs) |
image_selfie | string | No | Base64 selfie to enable face match + liveness |
customer_info | object | No | Declared data to cross-check against the document |
registry_check | string | No | Government registry to validate against: bvn, fayda, ghana_card |
callback_url | string | No | Webhook URL for the verification.completed event |
Get Verification
GET /v1/identity/verification/:verification_id
Retrieve the full result of a previously submitted verification.
💻 Code Samples
Node.js
const fs = require('fs');
const idFront = fs.readFileSync('national-id-front.jpg', 'base64');
const selfie = fs.readFileSync('customer-selfie.jpg', 'base64');
const res = await fetch('https://api.afriroute.ai/api/v1/identity/verify-id', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
document_type: 'national_id',
country: 'ET',
image_front: idFront,
image_selfie: selfie,
customer_info: { full_name: 'Abebe Kebede', id_number: 'ET123456789' }
})
});
const data = await res.json();
console.log(data.status, data.confidence);
Python
import base64, requests
with open('national-id-front.jpg', 'rb') as f:
id_front = base64.b64encode(f.read()).decode()
with open('customer-selfie.jpg', 'rb') as f:
selfie = base64.b64encode(f.read()).decode()
res = requests.post(
'https://api.afriroute.ai/api/v1/identity/verify-id',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'document_type': 'national_id',
'country': 'ET',
'image_front': id_front,
'image_selfie': selfie,
'customer_info': {'full_name': 'Abebe Kebede', 'id_number': 'ET123456789'}
}
)
print(res.json()['status'])
📊 Response
{
"verification_id": "ver_abc123xyz",
"status": "verified",
"confidence": 98.2,
"document": {
"type": "national_id",
"country": "ET",
"number": "ET123456789",
"full_name": "ABEBE KEBEDE",
"date_of_birth": "1990-05-15",
"expiry_date": "2030-01-10",
"authentic": true,
"expired": false
},
"face_match": { "match": true, "confidence": 97.8 },
"liveness": { "passed": true, "confidence": 96.5 },
"risk_assessment": { "risk_level": "low", "risk_score": 3, "flags": [] },
"verification_time": "2026-05-10T14:30:00Z"
}
Verification Statuses
| Status | Meaning |
|---|---|
verified | Document authentic and all checks passed |
pending | Processing or awaiting manual review |
rejected | Failed authenticity, face match, or liveness checks |
expired | Document is past its expiry date |
💡 Best Practices
- Capture sharp, well-lit images — blur and glare are the top causes of low confidence scores.
- Always send
image_backfor documents that carry an MRZ or data on the reverse. - Pass
customer_infoso AfriRoute can cross-check declared data against extracted fields. - Handle the webhook, not just the synchronous response, in production — verification can take several seconds.
- Use
registry_checkfor high-assurance KYC (BVN, Fayda, Ghana Card) where government validation is required.
⚠️ Error Handling
| Code | HTTP | Description |
|---|---|---|
INVALID_DOCUMENT_TYPE | 400 | Unsupported document_type for the given country |
IMAGE_QUALITY_LOW | 422 | Image too blurry, dark, or cropped to process |
DOCUMENT_EXPIRED | 422 | Document is past its expiry date |
FACE_MISMATCH | 422 | Selfie does not match the document photo |
REGISTRY_UNAVAILABLE | 503 | Government registry temporarily unreachable |
See the error code reference for the full list.
📚 Related Resources
- Document Scanning (OCR)
- Face Matching
- Liveness Detection
- Identity API Reference
- ID Verification Tutorial
Last Updated: May 2026 | Need help? [email protected]