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 |
Kenya takes a numeric bank_id from PayHero’s own list, not a SWIFT or
clearing code.
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" }'const res = await fetch(`${process.env.PH_CONNECT_URL}/api/v1/kyc/verify/bank_account_ke`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Basic ' + Buffer.from( `${process.env.PH_API_USERNAME}:${process.env.PH_API_PASSWORD}`, ).toString('base64'), }, body: JSON.stringify({ account_no: '2096844395', bank_id: '34' }),})
const check = await res.json()
if (check.status !== 'verified') { throw new Error('Account could not be resolved')}
console.log(check.subject_name) // the name on the accountimport os, requests
res = requests.post( f"{os.environ['PH_CONNECT_URL']}/api/v1/kyc/verify/bank_account_ke", auth=(os.environ["PH_API_USERNAME"], os.environ["PH_API_PASSWORD"]), json={"account_no": "2096844395", "bank_id": "34"},)check = res.json()
if check["status"] != "verified": raise RuntimeError("Account could not be resolved")
print(check["subject_name"]){ "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"}Kenyan bank IDs
Section titled “Kenyan bank IDs”| 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 |
Nigeria
Section titled “Nigeria”Nigeria takes the standard three-digit bank_code:
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" }'Name matching is yours to do
Section titled “Name matching is yours to do”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.}
