How to verify a Nigerian bank account programmatically
A developer's guide to validating Nigerian bank accounts — NUBAN checksum, account name resolution, and the APIs that power it.
Verifying a Nigerian bank account before sending money is one of the most common requirements in African fintech. "Verification" can mean two different things, though, and conflating them causes a lot of confusion. This guide breaks down both, shows you what you can do for free, and what requires a licensed provider.
Two kinds of verification
There are two distinct checks, and you often want both:
1. Format validation (NUBAN checksum)
Confirms the account number is structurally valid for the selected bank — before you make any network call. This is free, instant, and runs on a public CBN algorithm. It catches typos and mismatched bank/account combinations.
2. Name resolution (NIBSS Name Enquiry)
Confirms the account actually exists and returns the account holder's name. This requires a CBN-licensed provider connected to NIBSS — you cannot do it client-side. Providers like Paystack, NubAPI, Dojah, and Mono offer this.
Step 1: Validate NUBAN format (free)
The NUBAN checksum is computed from the bank code and first 9 digits. The Mansa API exposes it as a free endpoint:
curl "https://mansaapi.com/api/v1/identity/nuban/validate?account=0044563185&bank_code=058" \
-H "Authorization: Bearer YOUR_API_KEY"{
"success": true,
"data": {
"account": "0044563185",
"bank_code": "058",
"valid": true,
"check_digit_expected": 5,
"check_digit_provided": 5
}
}If valid is false, the account number is structurally wrong — reject it before spending money on a name lookup.
Step 2: Resolve the bank from the code
Confirm the bank code maps to a real institution and surface the bank name in your UI:
import { MansaAPI } from "mansaapi";
const mansa = new MansaAPI({ apiKey: process.env.MANSA_API_KEY });
const { data: bank } = await mansa.identity.getBank("058");
console.log(bank.name); // "Guaranty Trust Bank (GTBank)"Step 3: Name resolution (licensed provider)
For the final step — confirming the account holder's name — you need a NIBSS-connected provider. The flow with any of them is the same:
async function verifyAccount(accountNumber, bankCode) {
// 1. Free format check (Mansa API)
const { data: check } = await mansa.identity.validateNuban(accountNumber, bankCode);
if (!check.valid) {
return { ok: false, reason: "invalid_format" };
}
// 2. Confirm bank exists (Mansa API)
const { data: bank } = await mansa.identity.getBank(bankCode);
// 3. Name resolution (licensed aggregator — Paystack, NubAPI, etc.)
const name = await resolveAccountName(accountNumber, bankCode);
return { ok: true, bank: bank.name, accountName: name };
}Why not scrape it?
Some developers try to scrape name resolution through unofficial proxies. Don't. The CBN and EFCC tightened enforcement significantly in 2025 — over 12,000 individuals were implicated in BVN/NIN data-resale cases. Name resolution data is identical regardless of provider, so there's no competitive advantage in obtaining it illicitly — only legal risk. Use a licensed aggregator.
Free tools
Test NUBAN validation without code using the free NUBAN validator, or look up any bank code with the bank code finder.