Face Liveness & Match
Passive liveness detection and face comparison against the BVN photo in one call, via NIBSS N-Face.
Runs passive liveness detection on a selfie and, when you pass a BVN, compares the face with the photo on the BVN record, through NIBSS N-Face. One call, two scores.
- Availability
- Sandbox and live
- Indicative price
- ₦150.00 per completed check
- Consent
- The live selfie is the consent (
in_person_selfie). - MCP tool
face_match(image by https URL)
Body parameters
imagestringrequiredSelfie as base64 JPEG/PNG, or an https URL when image_type is url. At least 20 characters.
image_typestringOne of:
base64,url. Defaults tobase64.bvnstringCompare the selfie against the photo on this BVN. Omit for liveness only. Format: 11 digits.
liveness_thresholdnumberBetween 0 and 1. Defaults to
0.6.face_match_thresholdnumberBetween 0 and 1. Defaults to
0.9.orderstringLiveness first, comparison first, or both in parallel. One of:
pl_fc_serial,fc_pl_serial,fc_pl_parallel. Defaults topl_fc_serial.os_typestringOne of:
ios,android,desktop,unknown. Defaults tounknown.reasonstringrequiredPurpose of the check. One of the 38 NIMC purpose codes. See the purpose code list.
- Omit
bvnfor liveness only (methodface_liveness); include it for liveness and match (face_liveness_match). - With
image_type: "url",imagemust be a public https URL. matchistruewhen liveness passes and, if a BVN was supplied, the face comparison passes too.- To capture the selfie with an active liveness check inside your iOS, Android, React Native or Flutter app, see Mobile apps.
Send an Idempotency-Key header so a retried request is never billed twice. See Idempotency.
curl -X POST http://localhost:4000/v1/verify/face \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"image": "<base64 selfie>",
"bvn": "22222222221",
"reason": "financialProducts"
}'A completed check returns 200 with a verification object. status is verified or not_found. If the provider has not answered in time you get 202 with status: "pending"; retrieve it later or wait for the verification.completed webhook.
{
"reference_id": "spm_8171f3a87cbe221341f7185f",
"object": "verification",
"product": "face",
"method": "face_liveness_match",
"status": "verified",
"match": true,
"field_matches": null,
"field_confidence": null,
"mode": "sandbox",
"reason": "financialProducts",
"subject": "*******2221",
"summary": {
"liveness_passed": true,
"liveness_confidence": 0.885,
"liveness_quality": 0.885,
"face_match_passed": true,
"face_match_confidence": 0.988,
"face_match_quality": 0.902,
"session_code": "11b004ce-9f2f-43df-858e-79eacf50af07",
"thresholds": {
"liveness": 0.6,
"face_match": 0.9
}
},
"consent": {
"mechanism": "in_person_selfie",
"consent_id": null,
"timestamp": "2026-10-19T09:41:07.512Z"
},
"source": "api",
"error": null,
"billing": {
"amount_kobo": 0,
"currency": "NGN"
},
"latency_ms": 1180,
"created_at": "2026-10-19T09:41:07.512Z",
"updated_at": "2026-10-19T09:41:07.874Z"
}summary
liveness_passedbooleanLiveness confidence reached
liveness_threshold.liveness_confidencenumberLiveness confidence, 0 to 1.
liveness_qualitynumberImage quality score for liveness, 0 to 1.
face_match_passedboolean | nullFace comparison reached
face_match_threshold.nullwithout a BVN.face_match_confidencenumber | nullSimilarity to the BVN photo, 0 to 1.
face_match_qualitynumber | nullImage quality score for the comparison.
session_codestringN-Face session identifier, also returned as
provider_reference.thresholdsobjectThe
livenessandface_matchthresholds that were applied.
Full-tier accounts calling the REST API also receive provider, provider_reference and data, the normalized record. MCP, webhooks, lists and bulk results never include it. See Response shaping.
{
"provider": "sandbox",
"provider_reference": "SBX6CB753DB2C",
"data": {
"liveness_passed": true,
"liveness_confidence": 0.885,
"liveness_quality": 0.885,
"face_match_passed": true,
"face_match_confidence": 0.988,
"face_match_quality": 0.902,
"session_code": "11b004ce-9f2f-43df-858e-79eacf50af07",
"thresholds": {
"liveness": 0.6,
"face_match": 0.9
}
}
}Send these bodies with a sandbox key. More outcome triggers are on the Sandbox page.
{
"image": "data-LIVE-selfie-0001",
"bvn": "22222222221",
"reason": "financialProducts"
}{
"image": "data-SPOOF-photo-of-photo",
"reason": "financialProducts"
}{
"image": "data-MISMATCH-selfie",
"bvn": "22222222221",
"reason": "financialProducts"
}| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | The body failed validation. details lists each field. |
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Live only: wallet balance is below the check price. |
403 | not_entitled | Your workspace is not enabled for this product or method. |
409 | idempotency_key_reused | The Idempotency-Key was used with a different body. |
422 | provider_rejected_request | The upstream registry rejected the request. |
503 | verification_unavailable | Temporary failure. Retry, with the same or a new Idempotency-Key. |
All errors share one shape. See Errors for the full list.
Questions? Email developers@speedmap.ng. This page is also available as Markdown.