Face Matching
Compare two face images — typically a live selfie against the photo on an ID document — and receive a similarity score and match decision. AfriRoute's model is trained on a large, ethnically diverse dataset and is optimized for African skin tones, occlusions (glasses, hijab, beard), and age progression of up to ±10 years.
🚀 Quick Start
curl -X POST https://api.afriroute.ai/api/v1/identity/face-match \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image_1": "<base64-id-photo>",
"image_2": "<base64-selfie>",
"liveness_check": true
}'
📡 Endpoint
Compare Faces
POST /v1/identity/face-match
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
image_1 | string | Yes | Base64-encoded reference face (e.g. ID photo) |
image_2 | string | Yes | Base64-encoded probe face (e.g. live selfie) |
liveness_check | boolean | No | Run passive liveness on image_2 (default false) |
min_confidence | number | No | Minimum confidence (0–100) for a match (default 90) |
💻 Code Samples
Node.js
const fs = require('fs');
const res = await fetch('https://api.afriroute.ai/api/v1/identity/face-match', {
method: 'POST',
headers: { 'Authorization': 'Bearer $AFRIROUTE_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
image_1: fs.readFileSync('id-photo.jpg', 'base64'),
image_2: fs.readFileSync('selfie.jpg', 'base64'),
liveness_check: true
})
});
const data = await res.json();
console.log(`match=${data.match} confidence=${data.confidence}`);
Python
import base64, requests
def b64(path):
with open(path, 'rb') as f:
return base64.b64encode(f.read()).decode()
res = requests.post(
'https://api.afriroute.ai/api/v1/identity/face-match',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'image_1': b64('id-photo.jpg'),
'image_2': b64('selfie.jpg'),
'liveness_check': True
}
)
print(res.json())
📊 Response
{
"match": true,
"confidence": 97.8,
"similarity_score": 0.978,
"liveness": { "passed": true, "confidence": 96.5 },
"face_quality": {
"image_1_quality": "high",
"image_2_quality": "high",
"blur_detected": false,
"low_light": false
}
}
Interpreting the Score
confidence | Recommendation |
|---|---|
| ≥ 95 | Strong match — auto-approve |
| 90–94 | Likely match — approve, optionally review |
| 75–89 | Inconclusive — request a new selfie or manual review |
| < 75 | No match — reject |
💡 Best Practices
- Use a frontal, neutral selfie with a single clearly visible face.
- Avoid heavy backlighting — check
face_quality.low_lightbefore trusting a low score. - Pair with liveness (
liveness_check: true) to defeat printed-photo and screen-replay attacks. - Tune
min_confidenceto your risk appetite — higher for financial onboarding, lower for low-risk flows. - Reject images with
blur_detected: truerather than passing a low-quality probe to the matcher.
⚠️ Error Handling
| Code | HTTP | Description |
|---|---|---|
NO_FACE_DETECTED | 422 | No face found in one of the images |
MULTIPLE_FACES | 422 | More than one face detected in a probe image |
IMAGE_QUALITY_LOW | 422 | Image too blurry or dark to compare |
FACE_MISMATCH | 422 | Faces do not match above min_confidence |
See the error code reference for the full list.
📚 Related Resources
Last Updated: May 2026 | Need help? [email protected]