Skip to content

Bank account lookup

Confirm an account number exists and read back the name on it — the standard guard before a first payout to a new beneficiary.

check Country Required fields Price
bank_account_ke Kenya account_no, bank_id 55
bank_account_ng Nigeria number, bank_code 25

Both bank_id and bank_code come from a published list — see Bank codes.

Kenya takes a numeric bank_id from FinoQ’s own list, not a SWIFT or clearing code.

Terminal window
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/bank_account_ke" \
-u "$PH_API_USERNAME:$PH_API_PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"account_no": "2096844395",
"bank_id": "34"
}'
200 OK
{
"lookup_id": "b83f0c2ad95e4711a6de3f40",
"check": "bank_account_ke",
"category": "bank_account",
"country": "KE",
"actor_type": "I",
"subject_name": "JANE WANJIRU DOE",
"status": "verified",
"verification_status": "VERIFIED",
"source": "prembly",
"charged_amount": 55,
"charge_currency": "KES",
"charge_status": "charged"
}
ID Bank ID Bank ID Bank
1 KCB 15 Consolidated Bank 29 SBM
2 Standard Chartered Bank 16 Credit Bank 30 Housing Finance
3 Absa Bank 17 Access Bank 31 Diamond Trust Bank
4 Bank of India 18 Stanbic Bank 32 Mayfair Bank
5 Bank of Baroda 19 ABC Bank 33 Sidian Bank
6 NCBA 20 Eco Bank 34 Equity Bank
7 Prime Bank 21 SPIRE Bank 35 Family Bank
8 Co-operative Bank 22 Paramount Bank 36 Gulf African Bank
9 National Bank 23 Kingdom Bank 37 First Community Bank
10 M-Oriental 24 Guaranty Trust Bank 38 DIB Bank
11 Citi Bank 25 Victoria Bank 39 UBA Bank
12 Habib Bank AG Zurich 26 Guardian Bank 40 KWFT
13 Middle East Bank 27 I&M Bank 41 Faulu Bank
14 Bank of Africa 28 Development Bank 42 Post Bank

Both checks take a bank from a fixed list, so neither code should be typed by hand. Fetch the directory and render it as a select:

Terminal window
curl "$PH_CONNECT_URL/api/v1/kyc/banks/NG" \
-u "$PH_API_USERNAME:$PH_API_PASSWORD"
200 OK
{
"country": "NG",
"label": "Nigeria",
"field": "bank_code",
"check": "bank_account_ng",
"banks": [
{ "value": "404", "label": "Abbey Mortgage Bank" },
{ "value": "044", "label": "Access Bank Nigeria Plc" },
{ "value": "058", "label": "Guaranty Trust Bank Plc" }
]
}

field names the request field the chosen value belongs in — bank_code for Nigeria, bank_id for Kenya — so one piece of UI can drive either check.

Drop the country to get every directory at once:

Terminal window
curl "$PH_CONNECT_URL/api/v1/kyc/banks" \
-u "$PH_API_USERNAME:$PH_API_PASSWORD"

Nigeria lists 61 banks by CBN code, Kenya 42. The same list is embedded in the options array of the relevant field in GET /api/v1/kyc/checks, so a form built from the catalogue already renders a select without a second call.

Nigeria takes the standard three-digit CBN bank_code:

Terminal window
curl -X POST "$PH_CONNECT_URL/api/v1/kyc/verify/bank_account_ng" \
-u "$PH_API_USERNAME:$PH_API_PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"number": "0123456789",
"bank_code": "058"
}'

The check returns the name on the account. It does not compare that name to whatever you were expecting — comparing “JANE W DOE” against “Jane Doe” is a judgement call about how much divergence you will tolerate, and it belongs in your code, not in the API.

const onAccount = check.subject_name ?? ''
const expected = beneficiary.name
const normalise = (s: string) =>
s.toUpperCase().replace(/[^A-Z ]/g, '').split(/\s+/).filter(Boolean).sort().join(' ')
if (normalise(onAccount) !== normalise(expected)) {
// Surface for review rather than failing outright — middle names,
// initials and married names all diverge legitimately.
}