BVN Verification
Validate a Bank Verification Number through NIBSS: boolean match without PII, or the full record with subject consent.
Checks a Bank Verification Number through NIBSS. Use boolean for the common bank flow: you collect the customer's details, send them with the BVN, and get back which ones are correct, without receiving any personal data. Use core only when you need the full BVN record; it requires the customer's consent through the NIBSS Consent Hub.
- Availability
- Sandbox and live
- Indicative price
- ₦100.00 per completed check
- Consent
- MCP tool
verify_bvn(boolean method only)
Choose a method with the method field. Each one has its own required fields and consent mechanism.
| method | Description | Required fields |
|---|---|---|
boolean | Match / no-match against the BVN record. Returns no PII. The cheapest BVN check. | bvn, reason, consent, match |
core | Full BVN record. Requires a consent granted by the subject through POST /v1/consents. | bvn, reason, consent_id |
Body parameters · method
Match / no-match against the BVN record. Returns no PII. The cheapest BVN check.
methodstringrequiredAlways
boolean.bvnstringrequiredFormat: 11 digits.
reasonstringrequiredPurpose of the check. One of the 38 NIMC purpose codes. See the purpose code list.
consentobjectrequiredYour attestation that you obtained the data subject's consent for this purpose.
consent.obtainedbooleanrequiredAlways
true.matchobjectrequiredOptional values to compare against the record. Each comparison is returned in field_matches; match is true only if all of them agree.
match.first_namestringMust not be empty.
match.middle_namestringMust not be empty.
match.last_namestringMust not be empty.
match.date_of_birthstringFormat: date,
YYYY-MM-DD.
Full BVN record. Requires a consent granted by the subject through POST /v1/consents.
methodstringrequiredAlways
core.bvnstringrequiredFormat: 11 digits.
reasonstringrequiredPurpose of the check. One of the 38 NIMC purpose codes. See the purpose code list.
consent_idstringrequiredFormat: starts_with.
matchobjectOptional values to compare against the record. Each comparison is returned in field_matches; match is true only if all of them agree.
match.first_namestringMust not be empty.
match.middle_namestringMust not be empty.
match.last_namestringMust not be empty.
match.date_of_birthstringFormat: date,
YYYY-MM-DD.
booleanneeds at least one field inmatch. You can send up to six:first_name,middle_name,last_name,date_of_birth,phoneandgender. Sending all six gives the strongest check.- Each field you send comes back in
field_matchesastrueorfalse, so you can see exactly what was wrong (often a misspelt middle name).matchistrueonly if all of them agree. coreneeds aconsent_idfromPOST /v1/consentswhose status isgranted, for the same BVN, within 24 hours of the grant.
Send an Idempotency-Key header so a retried request is never billed twice. See Idempotency.
curl -X POST http://localhost:4000/v1/verify/bvn \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"method": "boolean",
"bvn": "22222222221",
"reason": "financialProducts",
"consent": {
"obtained": true
},
"match": {
"first_name": "Clarke",
"last_name": "Griffin",
"date_of_birth": "1992-04-18"
}
}'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": "bvn",
"method": "bvn_boolean",
"status": "verified",
"match": true,
"field_matches": {
"first_name": true,
"last_name": true,
"date_of_birth": true,
"phone": true
},
"field_confidence": null,
"mode": "sandbox",
"reason": "financialProducts",
"subject": "*******2221",
"summary": {
"match": true
},
"consent": {
"mechanism": "client_attested",
"consent_id": null,
"timestamp": "2026-10-19T09:41:07.512Z"
},
"source": "api",
"error": null,
"billing": {
"amount_kobo": 0,
"currency": "NGN"
},
"latency_ms": 268,
"created_at": "2026-10-19T09:41:07.512Z",
"updated_at": "2026-10-19T09:41:07.874Z"
}summary
matchbooleanbooleanmethod: whether every supplied field matched the BVN record. The per-field answers are infield_matcheson the verification.first_namestringcoremethod: masked first name.last_namestringcoremethod: masked last name.watchlistedbooleancoremethod: whether the BVN is on the industry watchlist.
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": {
"match": true,
"field_matches": {
"first_name": true,
"last_name": true,
"date_of_birth": true,
"phone": true
}
}
}Send these bodies with a sandbox key. More outcome triggers are on the Sandbox page.
{
"method": "boolean",
"bvn": "22222222221",
"reason": "financialProducts",
"consent": {
"obtained": true
},
"match": {
"first_name": "Clarke",
"last_name": "Griffin"
}
}{
"method": "boolean",
"bvn": "22222222222",
"reason": "financialProducts",
"consent": {
"obtained": true
},
"match": {
"last_name": "Smith"
}
}{
"method": "boolean",
"bvn": "22222222225",
"reason": "creditBackgroundCheck",
"consent": {
"obtained": true
},
"match": {
"last_name": "Murphy"
}
}| 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. |
404 | consent_not_found | No consent with that consent_id in this mode. |
412 | consent_not_granted | The consent is pending, denied, expired or revoked. |
412 | consent_expired | The grant is older than 24 hours. Request a new consent. |
412 | consent_subject_mismatch | The consent was granted for a different BVN. |
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.