Didit Face Match API
Overview
Compares two facial images to determine if they belong to the same person. Returns a similarity score (0-100).
Key constraints:
- Supported formats: JPEG, PNG, WebP, TIFF
- Maximum file size: 5MB per image
- If multiple faces in an image, the largest face is used for comparison
- Both
user_image and ref_image are required
Capabilities: Similarity scoring, age estimation, gender detection, face bounding boxes, configurable decline threshold, optional image rotation for non-upright faces.
API Reference: https://docs.didit.me/reference/face-match-standalone-api
Authentication
All requests require x-api-key header. Get your key from Didit Business Console → API & Webhooks.
Endpoint
POST https://verification.didit.me/v3/face-match/
Headers
| Header |
Value |
Required |
x-api-key |
Your API key |
Yes |
Content-Type |
multipart/form-data |
Yes |
Request Parameters (multipart/form-data)
| Parameter |
Type |
Required |
Default |
Constraints |
Description |
user_image |
file |
Yes |
— |
JPEG/PNG/WebP/TIFF, max 5MB |
User's face image to verify |
ref_image |
file |
Yes |
— |
Same as above |
Reference image to compare against |
face_match_score_decline_threshold |
integer |
No |
30 |
0-100 |
Scores below this = Declined |
rotate_image |
boolean |
No |
false |
— |
Try 0/90/180/270 degree rotations to find upright face |
save_api_request |
boolean |
No |
true |
— |
Save in Business Console Manual Checks |
vendor_data |
string |
No |
— |
— |
Your identifier for session tracking |
Example
import requests
response = requests.post(
"https://verification.didit.me/v3/face-match/",
headers={"x-api-key": "YOUR_API_KEY"},
files={
"user_image": ("selfie.jpg", open("selfie.jpg", "rb"), "image/jpeg"),
"ref_image": ("id_photo.jpg", open("id_photo.jpg", "rb"), "image/jpeg"),
},
data={"face_match_score_decline_threshold": "50"},
)
const formData = new FormData();
formData.append("user_image", selfieFile);
formData.append("ref_image", referenceFile);
formData.append("face_match_score_decline_threshold", "50");
const response = await fetch("https://verification.didit.me/v3/face-match/", {
method: "POST",
headers: { "x-api-key": "YOUR_API_KEY" },
body: formData,
});
Response (200 OK)
{
"request_id": "a1b2c3d4-...",
"face_match": {
"status": "Approved",
"score": 80,
"user_image": {
"entities": [
{"age": 27.63, "bbox": [40, 40, 100, 100], "confidence": 0.717, "gender": "male"}
],
"best_angle": 0
},
"ref_image": {
"entities": [
{"age": 22.16, "bbox": [156, 234, 679, 898], "confidence": 0.717, "gender": "male"}
],
"best_angle": 0
},
"warnings": []
},
"created_at": "2025-05-01T13:11:07.977806Z"
}
Status Values & Handling
| Status |
Meaning |
Action |
"Approved" |
Score >= threshold |
Faces match — proceed |
"Declined" |
Score < threshold or no face |
Check warnings for details. May need better image |
"In Review" |
Needs manual review |
Wait for review or retrieve via session API |
Error Responses
| Code |
Meaning |
Action |
400 |
Invalid request |
Check file format, size, parameters |
401 |
Invalid API key |
Verify x-api-key header |
403 |
Insufficient credits |
Top up at business.didit.me |
Response Field Reference
| Field |
Type |
Description |
status |
string |
"Approved", "Declined", "In Review" |
score |
integer |
0-100 similarity score (higher = more similar). null if no face found |
entities[].age |
float |
Estimated age |
entities[].bbox |
array |
Face bounding box [x1, y1, x2, y2] |
entities[].confidence |
float |
Face detection confidence (0-1) |
entities[].gender |
string |
"male" or "female" |
best_angle |
integer |
Best rotation angle for the face |
warnings |
array |
{risk, log_type, short_description, long_description} |
Warning Tags
| Tag |
Description |
Auto-Decline |
NO_REFERENCE_IMAGE |
Reference or face image missing |
Yes |
NO_FACE_DETECTED |
No face detected in one or both images |
Yes |
LOW_FACE_MATCH_SIMILARITY |
Score below threshold — potential identity mismatch |
Configurable |
Security best practice: Only store the status and score. Minimize biometric image data on your servers. Image URLs (in workflow mode) expire after 60 minutes.
Score Interpretation
| Score Range |
Interpretation |
Action |
| 90-100 |
Very high confidence — same person |
Auto-approve |
| 70-89 |
High confidence — likely same person |
Approve (default threshold 30) |
| 50-69 |
Moderate — possible match |
Consider manual review |
| 30-49 |
Low — likely different people |
Declined at default threshold |
| 0-29 |
Very low — different people |
Declined |
Utility Scripts
export DIDIT_API_KEY="your_api_key"
python scripts/match_faces.py selfie.jpg id_photo.jpg
python scripts/match_faces.py selfie.jpg id_photo.jpg --threshold 50 --rotate