Skip to main content

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​

FieldTypeRequiredDescription
document_typestringYesnational_id, passport, drivers_license, or voter_id
countrystringYesISO 3166-1 alpha-2 code (e.g. ET, NG, GH)
image_frontstringYesBase64-encoded front image of the document
image_backstringNoBase64-encoded back image (required for some IDs)
image_selfiestringNoBase64 selfie to enable face match + liveness
customer_infoobjectNoDeclared data to cross-check against the document
registry_checkstringNoGovernment registry to validate against: bvn, fayda, ghana_card
callback_urlstringNoWebhook 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​

StatusMeaning
verifiedDocument authentic and all checks passed
pendingProcessing or awaiting manual review
rejectedFailed authenticity, face match, or liveness checks
expiredDocument 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_back for documents that carry an MRZ or data on the reverse.
  • Pass customer_info so 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_check for high-assurance KYC (BVN, Fayda, Ghana Card) where government validation is required.

⚠️ Error Handling​

CodeHTTPDescription
INVALID_DOCUMENT_TYPE400Unsupported document_type for the given country
IMAGE_QUALITY_LOW422Image too blurry, dark, or cropped to process
DOCUMENT_EXPIRED422Document is past its expiry date
FACE_MISMATCH422Selfie does not match the document photo
REGISTRY_UNAVAILABLE503Government registry temporarily unreachable

See the error code reference for the full list.


Last Updated: May 2026 | Need help? [email protected]