Verify Bank Verification Numbers (BVN) to authenticate customer identities and retrieve their registered information from the Nigerian Inter-Bank Settlement System (NIBSS).
BVN verification is essential for KYC compliance in Nigeria and helps verify customer identities against official banking records.
Endpoint
POST /verification/bvn
Name Type Required Description api-keystring Required Your API key Content-Typestring Required Must be application/json
Request Body
11-digit Bank Verification Number to verify BVN must be exactly 11 digits. Leading zeros are significant.
Customer’s first name to match against BVN records (optional but recommended)
Customer’s last name to match against BVN records (optional but recommended)
Customer’s date of birth in YYYY-MM-DD format to match against BVN records
Customer’s phone number to match against BVN records (in international format)
Unique verification reference for tracking purposes
Additional information for the verification request {
"customer_id" : "12345" ,
"verification_type" : "account_opening" ,
"ip_address" : "192.168.1.1" ,
"user_agent" : "Mozilla/5.0..."
}
Example Request
cURL - Basic Verification
cURL - Enhanced Verification
Node.js
PHP
Python
curl -X POST https://api.payvessel.com/verification/bvn \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"bvn": "12345678901",
"reference": "BVN_VER_2024_001"
}'
Response
Request status indicator - "success" or "error"
Human-readable message describing the result
BVN verification data object The verified BVN (partially masked for security)
Customer’s first name from BVN records
Customer’s middle name from BVN records
Customer’s last name from BVN records
Customer’s full name as registered with NIBSS
Customer’s date of birth in YYYY-MM-DD format
Customer’s registered phone number (partially masked)
Customer’s gender - "Male" or "Female"
Customer’s marital status - "Single", "Married", "Divorced", "Widowed"
Customer’s state of origin in Nigeria
Customer’s Local Government Area of origin
Customer’s current state of residence
Customer’s current Local Government Area of residence
Customer’s residential address
Bank where the BVN was originally enrolled
Branch where the BVN was enrolled
Whether the BVN is on any watch list
Base64 encoded passport photograph (if available and requested)
Overall verification status - "verified", "partial", "failed"
Results of data matching against provided information data.match_results.first_name_match
Whether provided first name matches BVN records
data.match_results.last_name_match
Whether provided last name matches BVN records
data.match_results.date_of_birth_match
Whether provided date of birth matches BVN records
data.match_results.phone_number_match
Whether provided phone number matches BVN records
data.match_results.overall_match_score
Overall matching score (0-100)
Your unique verification reference
PayVessel’s internal verification ID
Custom metadata attached to the verification
ISO 8601 timestamp when verification was performed
Example Response
200 Success - Verified
200 Success - Partial Match
400 Bad Request - Invalid BVN
404 Not Found - BVN Not Found
429 Rate Limited
{
"status" : "success" ,
"message" : "BVN verification successful" ,
"data" : {
"bvn" : "1234567****" ,
"first_name" : "JOHN" ,
"middle_name" : "MICHAEL" ,
"last_name" : "DOE" ,
"full_name" : "JOHN MICHAEL DOE" ,
"date_of_birth" : "1990-05-15" ,
"phone_number" : "+2348012***678" ,
"gender" : "Male" ,
"marital_status" : "Single" ,
"nationality" : "Nigerian" ,
"state_of_origin" : "Lagos" ,
"lga_of_origin" : "Lagos Island" ,
"state_of_residence" : "Lagos" ,
"lga_of_residence" : "Victoria Island" ,
"residential_address" : "15 Victoria Island Road, Lagos" ,
"enrollment_bank" : "First Bank of Nigeria" ,
"enrollment_branch" : "Victoria Island" ,
"watch_listed" : false ,
"image" : null ,
"verification_status" : "verified" ,
"match_results" : {
"first_name_match" : true ,
"last_name_match" : true ,
"date_of_birth_match" : true ,
"phone_number_match" : false ,
"overall_match_score" : 85
},
"reference" : "BVN_VER_2024_001" ,
"verification_id" : "VER_bvn_xyz789abc123" ,
"metadata" : {
"customer_id" : "12345" ,
"verification_type" : "loan_application"
},
"created_at" : "2024-01-15T14:30:00Z"
}
}
Verification Status Guide
Complete Verification The BVN exists and all provided data matches the records. Characteristics:
Valid BVN found in NIBSS database
High match score (typically > 80%)
All provided fields match BVN records
Customer identity is confirmed
Use cases:
Account opening approval
Loan application processing
High-value transaction approval
Partial Verification The BVN exists but some provided data doesn’t match the records. Characteristics:
Valid BVN found in NIBSS database
Some fields match, others don’t
Match score between 30-80%
Manual review may be required
Common causes:
Name variations (nicknames, abbreviations)
Updated phone number not reflected in BVN
Data entry errors
Recommendations:
Request customer to provide correct information
Consider additional verification methods
Implement manual review process
Verification Failed The BVN could not be verified or doesn’t exist. Characteristics:
BVN not found in NIBSS database
Technical error during verification
Invalid BVN format
Common causes:
Incorrect BVN provided
BVN deactivated or blocked
System downtime
Next steps:
Ask customer to verify BVN number
Try alternative verification methods
Contact support if issue persists
Match Score Interpretation
The overall_match_score helps you understand verification confidence:
90-100% - Excellent
70-89% - Good
50-69% - Fair
0-49% - Poor
High Confidence Match
All or most provided data matches exactly
Very low fraud risk
Proceed with confidence
Typical scenarios:
Exact name, DOB, and phone matches
Minor variations in address only
High-quality data input
Good Match with Minor Discrepancies
Most important data matches
Some variations in secondary fields
Generally acceptable for most use cases
Common variations:
Shortened names (John vs Jonathan)
Updated phone numbers
Address changes
Moderate Match - Review Recommended
Some key data matches
Significant discrepancies present
Manual review advised
Considerations:
Request additional documentation
Implement step-up verification
Consider risk tolerance
Low Match - High Risk
Major discrepancies in key fields
Potential fraud indicator
Reject or require extensive verification
Red flags:
Name completely different
DOB doesn’t match
Multiple field mismatches
Integration Patterns
Account Opening
Loan Application
Transaction Monitoring
Batch Verification
// KYC verification during account opening
const performKycVerification = async ( customerData ) => {
try {
const bvnVerification = await payvessel . verification . bvn ({
bvn: customerData . bvn ,
first_name: customerData . first_name ,
last_name: customerData . last_name ,
date_of_birth: customerData . date_of_birth ,
phone_number: customerData . phone_number ,
reference: `KYC_ ${ customerData . id } _ ${ Date . now () } ` ,
metadata: {
customer_id: customerData . id ,
verification_type: 'account_opening' ,
ip_address: customerData . ip_address
}
});
const result = bvnVerification . data ;
// Evaluate verification results
if ( result . verification_status === 'verified' && result . match_results . overall_match_score >= 80 ) {
await approveAccount ( customerData . id );
return { status: 'approved' , verification: result };
} else if ( result . verification_status === 'partial' && result . match_results . overall_match_score >= 60 ) {
await flagForManualReview ( customerData . id , result );
return { status: 'review_required' , verification: result };
} else {
await rejectAccount ( customerData . id , 'KYC verification failed' );
return { status: 'rejected' , verification: result };
}
} catch ( error ) {
await handleVerificationError ( customerData . id , error );
throw error ;
}
};
// Enhanced verification for loan applications
const verifyLoanApplicant = async ( loanApplication ) => {
const verification = await payvessel . verification . bvn ({
bvn: loanApplication . bvn ,
first_name: loanApplication . first_name ,
last_name: loanApplication . last_name ,
date_of_birth: loanApplication . date_of_birth ,
reference: `LOAN_ ${ loanApplication . id } _ ${ Date . now () } ` ,
metadata: {
loan_application_id: loanApplication . id ,
loan_amount: loanApplication . amount ,
verification_type: 'loan_application'
}
});
const result = verification . data ;
// Check for watch list status
if ( result . watch_listed ) {
await rejectLoanApplication ( loanApplication . id , 'Applicant on watch list' );
return { status: 'rejected' , reason: 'watch_list' };
}
// Store verified customer data
await updateCustomerProfile ( loanApplication . customer_id , {
bvn_verified: true ,
full_name: result . full_name ,
date_of_birth: result . date_of_birth ,
address: result . residential_address ,
verification_score: result . match_results . overall_match_score
});
return { status: 'verified' , data: result };
};
// BVN verification for suspicious transactions
const verifyHighValueTransaction = async ( transaction ) => {
if ( transaction . amount > 1000000 ) { // > ₦10,000
const customer = await getCustomer ( transaction . customer_id );
if ( ! customer . bvn_verified ) {
const verification = await payvessel . verification . bvn ({
bvn: customer . bvn ,
first_name: customer . first_name ,
last_name: customer . last_name ,
reference: `TXN_VER_ ${ transaction . id } ` ,
metadata: {
transaction_id: transaction . id ,
transaction_amount: transaction . amount ,
verification_trigger: 'high_value_transaction'
}
});
if ( verification . data . verification_status !== 'verified' ) {
await flagTransaction ( transaction . id , 'BVN verification failed' );
await pauseTransaction ( transaction . id );
return false ;
}
await markCustomerAsVerified ( customer . id );
}
}
return true ;
};
// Verify multiple BVNs for compliance
const batchVerifyCustomers = async ( customers ) => {
const results = [];
const batchSize = 10 ; // Process in batches to respect rate limits
for ( let i = 0 ; i < customers . length ; i += batchSize ) {
const batch = customers . slice ( i , i + batchSize );
const batchPromises = batch . map ( async ( customer ) => {
try {
const verification = await payvessel . verification . bvn ({
bvn: customer . bvn ,
first_name: customer . first_name ,
last_name: customer . last_name ,
reference: `BATCH_ ${ customer . id } _ ${ Date . now () } ` ,
metadata: {
customer_id: customer . id ,
batch_verification: true
}
});
return {
customer_id: customer . id ,
status: 'success' ,
verification: verification . data
};
} catch ( error ) {
return {
customer_id: customer . id ,
status: 'error' ,
error: error . message
};
}
});
const batchResults = await Promise . all ( batchPromises );
results . push ( ... batchResults );
// Rate limiting delay between batches
if ( i + batchSize < customers . length ) {
await new Promise ( resolve => setTimeout ( resolve , 2000 ));
}
}
return results ;
};
Compliance & Security
Data Protection PII Masking : Sensitive data like BVN and phone numbers are automatically masked in responses for security
Regulatory Compliance CBN Compliance : Adheres to Central Bank of Nigeria guidelines for BVN usage and data handling
Rate Limiting API Limits : 100 requests per minute to prevent abuse and ensure system stability
Audit Trail Verification Logs : All verifications are logged with timestamps and references for audit purposes
Best Practices
Graceful Error Management
Handle network timeouts gracefully
Implement retry logic for temporary failures
Log errors for debugging
Provide meaningful user feedback
const verifyBvnWithRetry = async ( bvnData , maxRetries = 3 ) => {
for ( let attempt = 1 ; attempt <= maxRetries ; attempt ++ ) {
try {
return await payvessel . verification . bvn ( bvnData );
} catch ( error ) {
if ( attempt === maxRetries || error . status === 400 ) {
throw error ; // Don't retry validation errors
}
await new Promise ( resolve => setTimeout ( resolve , 1000 * attempt ));
}
}
};
NIN Verification Verify National Identity Numbers for enhanced KYC
Face Comparison Compare customer photos with BVN records
Liveness Detection Ensure customer photos are from live subjects
Phone Verification Verify phone numbers via SMS or voice calls
Webhook Events
This endpoint triggers the following webhook events:
verification.bvn.completed - BVN verification completed (success or failure)
verification.bvn.match_found - High confidence match detected
verification.bvn.watchlist_hit - BVN found on watch list
Rate Limits : BVN verification is limited to 100 requests per minute. Exceeding this limit will result in HTTP 429 responses. Plan your verification flows accordingly.