Validate BVN
Overview
The Validate BVN API validates a Bank Verification Number (BVN) and retrieves the holder's verified details from the core banking provider. This operation performs real-time BVN verification and returns comprehensive information about the BVN holder including personal details, contact information, and biometric verification status.
Command Details
Command Name: ValidateBVN
Operation Type: Query (Read Operation)
Authorization Required: None (Public API for onboarding)
Use Cases
- Customer Onboarding: Verify customer identity during account opening
- KYC Compliance: Validate BVN for Know Your Customer (KYC) requirements
- Identity Verification: Confirm customer details match BVN records
- Fraud Prevention: Verify BVN authenticity before processing transactions
- Customer Data Validation: Cross-check customer-provided information with BVN database
- Account Linking: Link existing BVN to new accounts or services
- Regulatory Compliance: Meet CBN requirements for BVN validation
API Endpoint
POST /api/bpm/cmd
Content-Type: application/json
Authorization: Bearer {access_token}
Or using BankLingo functions:
var result = doCmd('ValidateBVN', { bvn: '12345678901' });
Request Structure
Request Body
{
"commandName": "ValidateBVN",
"data": {
"bvn": "string",
"provider": 1
}
}
Request Fields
| Field Name | Type | Mandatory | Description |
|---|---|---|---|
bvn | String | Yes | 11-digit Bank Verification Number |
provider | Integer | No | Core banking provider (1 = BankOne_EmpireTrust, default) |
BVN Format Requirements
- Length: Must be exactly 11 digits
- Format: Numeric only (no letters or special characters)
- Example:
12345678901
Core Banking Providers
| Provider Code | Provider Name | Description |
|---|---|---|
1 | BankOne_EmpireTrust | Default provider (Empire Trust BankOne) |
2 | Mono | Alternative provider |
Sample Requests
1. Basic BVN Validation
{
"commandName": "ValidateBVN",
"data": {
"bvn": "12345678901"
}
}
2. BVN Validation with Specific Provider
{
"commandName": "ValidateBVN",
"data": {
"bvn": "22163699922",
"provider": 1
}
}
3. Using BankLingo Functions
// Basic validation
var result = doCmd('ValidateBVN', {
bvn: '12345678901'
});
if (result.isSuccessful) {
console.log('BVN is valid!');
console.log('Name: ' + result.data.fullName);
console.log('Phone: ' + result.data.phoneNumber);
} else {
console.error('BVN validation failed: ' + result.message);
}
4. Validation with Provider Selection
// Validate using specific provider
var result = doCmd('ValidateBVN', {
bvn: '22163699922',
provider: 1 // BankOne_EmpireTrust
});
if (result.isSuccessful) {
var bvnData = result.data;
// Use validated data for onboarding
var firstName = bvnData.firstName;
var lastName = bvnData.lastName;
var phoneNumber = bvnData.phoneNumber;
var dateOfBirth = bvnData.dateOfBirth;
}
Response Structure
Success Response
{
"isSuccessful": true,
"message": "BVN validated successfully.",
"data": {
"isValid": true,
"bvn": "12345678901",
"firstName": "John",
"lastName": "Doe",
"otherNames": "Michael",
"dateOfBirth": "1990-05-15",
"phoneNumber": "08012345678",
"fullName": "John Michael Doe",
"validatedAt": "2026-01-08T10:30:00Z"
}
}
Response Fields
| Field Name | Type | Description |
|---|---|---|
isSuccessful | Boolean | Whether the validation was successful |
message | String | Descriptive message about the validation result |
data | Object | BVN holder details (null if validation failed) |
data.isValid | Boolean | Whether the BVN is valid |
data.bvn | String | The validated BVN number |
data.firstName | String | BVN holder's first name |
data.lastName | String | BVN holder's last name |
data.otherNames | String | Middle names or other names |
data.dateOfBirth | String | Date of birth (YYYY-MM-DD or DD-MM-YYYY format) |
data.phoneNumber | String | Phone number registered with BVN |
data.fullName | String | Complete formatted name |
data.validatedAt | DateTime | Timestamp of validation |
Error Response
{
"isSuccessful": false,
"message": "The BVN number is not valid.",
"statusCode": "INVALID_BVN"
}
Error Codes
| Error Code | HTTP Status | Description | Resolution |
|---|---|---|---|
BAD_REQUEST | 400 | Invalid BVN format | Ensure BVN is 11 digits and numeric only |
INVALID_BVN | 404 | BVN not found in registry | Verify the BVN number is correct |
SERVICE_UNAVAILABLE | 503 | BVN validation service down | Retry after a few minutes |
INVALID_RESPONSE | 500 | Service returned invalid data | Contact support |
INTERNAL_SERVER_ERROR | 500 | Unexpected error occurred | Check logs and contact support |
Testing & Mock Data
For testing and development purposes, the API supports mock BVN numbers that return predefined data:
Mock BVN Numbers
| BVN Number | Description | Mock Data |
|---|---|---|
00000000000 | Test BVN (zeros) | Returns success with mock data for "John Doe" |
99999999999 | Test BVN (nines) | Returns success with mock data for "Jane Smith" |
Mock Data Examples
BVN: 00000000000
{
"isSuccessful": true,
"message": "BVN validated successfully. (MOCK DATA)",
"data": {
"isValid": true,
"bvn": "00000000000",
"firstName": "John",
"lastName": "Doe",
"otherNames": "Michael",
"dateOfBirth": "01-01-1990",
"phoneNumber": "08012345678",
"fullName": "John Michael Doe",
"validatedAt": "2026-01-08T10:30:00Z"
}
}
BVN: 99999999999
{
"isSuccessful": true,
"message": "BVN validated successfully. (MOCK DATA)",
"data": {
"isValid": true,
"bvn": "99999999999",
"firstName": "Jane",
"lastName": "Smith",
"otherNames": "Elizabeth",
"dateOfBirth": "15-06-1995",
"phoneNumber": "08098765432",
"fullName": "Jane Elizabeth Smith",
"validatedAt": "2026-01-08T10:30:00Z"
}
}
Complete Integration Example
Customer Onboarding with BVN Validation
// Step 1: Validate BVN
var bvnResult = doCmd('ValidateBVN', {
bvn: context.bvn
});
if (!bvnResult.isSuccessful) {
return {
error: true,
message: 'BVN validation failed: ' + bvnResult.message
};
}
var bvnData = bvnResult.data;
// Step 2: Compare user-provided data with BVN data
var userFirstName = context.firstName.toLowerCase();
var bvnFirstName = bvnData.firstName.toLowerCase();
if (userFirstName !== bvnFirstName) {
return {
error: true,
message: 'Name mismatch: Provided name does not match BVN records'
};
}
// Step 3: Validate phone number
var userPhone = context.phoneNumber.replace(/\D/g, ''); // Remove non-digits
var bvnPhone = bvnData.phoneNumber.replace(/\D/g, '');
if (!bvnPhone.endsWith(userPhone.slice(-7))) {
return {
error: true,
message: 'Phone number must match BVN records'
};
}
// Step 4: Proceed with customer creation
var createResult = doCmd('CreateContactCommand', {
firstName: bvnData.firstName,
lastName: bvnData.lastName,
middleName: bvnData.otherNames,
dateOfBirth: bvnData.dateOfBirth,
phoneNumber: bvnData.phoneNumber,
emailAddress: context.emailAddress,
biometricsId: context.bvn,
// ... other fields
});
return {
success: true,
message: 'Customer onboarded successfully',
customerId: createResult.data.id,
bvnValidated: true
};
BVN Validation with Caching
// Cache BVN results to reduce API calls
var cacheKey = 'bvn_' + context.bvn;
// Check if BVN was recently validated
var cachedResult = $.cache.get(cacheKey);
if (cachedResult) {
console.log('Using cached BVN data');
return cachedResult;
}
// Validate BVN
var bvnResult = doCmd('ValidateBVN', {
bvn: context.bvn
});
if (bvnResult.isSuccessful) {
// Cache for 1 hour (3600 seconds)
$.cache.set(cacheKey, bvnResult, 3600);
}
return bvnResult;
Best Practices
1. Input Validation
Always validate BVN format before calling the API:
function isValidBVN(bvn) {
// Check length
if (!bvn || bvn.length !== 11) return false;
// Check if numeric
return /^\d{11}$/.test(bvn);
}
if (!isValidBVN(context.bvn)) {
return { error: true, message: 'Invalid BVN format' };
}
2. Error Handling
Always handle errors gracefully:
try {
var result = doCmd('ValidateBVN', { bvn: context.bvn });
if (!result.isSuccessful) {
// Log error for investigation
console.error('BVN validation failed:', result.message);
// Return user-friendly message
return {
error: true,
message: 'We could not validate your BVN. Please check and try again.'
};
}
return result;
} catch (error) {
console.error('BVN validation exception:', error);
return {
error: true,
message: 'An error occurred during BVN validation'
};
}
3. Data Comparison
Use case-insensitive comparison for name matching:
function namesMatch(name1, name2) {
return name1.trim().toLowerCase() === name2.trim().toLowerCase();
}
if (!namesMatch(context.firstName, bvnData.firstName)) {
return { error: true, message: 'Name does not match BVN records' };
}
4. Phone Number Validation
Compare last 7 digits for phone number matching:
function phoneNumbersMatch(userPhone, bvnPhone) {
var cleanUser = userPhone.replace(/\D/g, '');
var cleanBvn = bvnPhone.replace(/\D/g, '');
// Compare last 7 digits
return cleanBvn.endsWith(cleanUser.slice(-7));
}
5. Caching Strategy
Cache validated BVN data to reduce API calls:
// Cache for 1 hour during onboarding session
var cacheExpiry = 3600; // 1 hour
var cachedBvn = $.cache.get('bvn_' + context.bvn);
if (!cachedBvn) {
cachedBvn = doCmd('ValidateBVN', { bvn: context.bvn });
if (cachedBvn.isSuccessful) {
$.cache.set('bvn_' + context.bvn, cachedBvn, cacheExpiry);
}
}
6. Security Considerations
- Never log or store full BVN in plain text
- Mask BVN in logs:
123****8901 - Use HTTPS for all API calls
- Implement rate limiting for BVN validation requests
// Mask BVN for logging
function maskBVN(bvn) {
if (bvn.length !== 11) return 'INVALID';
return bvn.substring(0, 3) + '****' + bvn.substring(7);
}
console.log('Validating BVN: ' + maskBVN(context.bvn));
Integration with Onboarding Flow
The ValidateBVN command is typically used as part of the customer onboarding process:
- Customer provides BVN → Validate format
- Call ValidateBVN → Verify BVN authenticity
- Compare details → Match name, phone with user input
- Check existing customer → Use BVN to find existing accounts
- Create/Link customer → Proceed with account creation or linking
// Complete onboarding flow
var onboardCustomer = function(customerData) {
// Step 1: Validate BVN format
if (!/^\d{11}$/.test(customerData.bvn)) {
return { error: 'Invalid BVN format' };
}
// Step 2: Validate BVN
var bvnResult = doCmd('ValidateBVN', {
bvn: customerData.bvn
});
if (!bvnResult.isSuccessful) {
return { error: 'BVN validation failed: ' + bvnResult.message };
}
// Step 3: Verify customer details match BVN
var bvn = bvnResult.data;
if (bvn.firstName.toLowerCase() !== customerData.firstName.toLowerCase()) {
return { error: 'Name mismatch with BVN records' };
}
// Step 4: Check if customer already exists
var existingCustomer = doCmd('RetrieveContactByBVN', {
bvn: customerData.bvn
});
if (existingCustomer.isSuccessful && existingCustomer.data) {
return {
success: true,
isExisting: true,
customerId: existingCustomer.data.id,
message: 'Existing customer found'
};
}
// Step 5: Create new customer
var createResult = doCmd('OnboardIndividualRegistration', {
firstName: bvn.firstName,
lastName: bvn.lastName,
middleName: bvn.otherNames,
biometricsId: customerData.bvn,
dateOfBirth: bvn.dateOfBirth,
phoneNumber: bvn.phoneNumber,
emailAddress: customerData.emailAddress
});
return {
success: true,
isExisting: false,
customerId: createResult.data.id,
message: 'New customer created successfully'
};
};
Performance Considerations
- Response Time: Typically 2-5 seconds
- Rate Limits: Recommended max 10 requests/minute per BVN
- Caching: Cache valid BVN data for 1 hour during onboarding
- Retry Logic: Implement exponential backoff for service unavailable errors
Regulatory Compliance
This API complies with:
- CBN Guidelines on BVN usage and validation
- NDPR (Nigeria Data Protection Regulation) for data handling
- KYC Requirements for customer identity verification
Related APIs
OnboardIndividualRegistration- Customer onboarding with BVNCreateContactCommand- Create customer contactUpdateClientBVNDetails- Update customer BVN informationRetrieveContactByBVN- Find customer by BVN
Support
For issues or questions about BVN validation:
- Check error codes and messages
- Verify BVN format is correct (11 digits)
- Ensure core banking provider is properly configured
- Review logs for detailed error information
- Contact support team for persistent issues