Skip to main content
Paying the wrong account is expensive and usually irreversible. Account validation lets you check a destination before you commit to it. This page covers how to read a result and what to do about it. For request and response fields, use the endpoint references, which are generated from the API itself and always current:

Validate mobile money

Phone numbers, paybills and tills

Validate bank account

Account number and bank code

Two levels

There are two levels, and which you get depends on your account: Both come from the same endpoints, with the same request shape. Without the entitlement you get the format check and nameLookupStatus: "NOT_ENABLED"; with it, the response also carries the resolved name. The request is identical either way, so you don’t need to change your integration when it’s switched on. Name resolution is enabled per account from our side — talk to your account manager. Paybill and till validation depends on it, because a shortcode is just digits: whether it exists is exactly what the lookup answers, and there is no useful format check for one.

You don’t need to send the network

For mobile money, the network is resolved from the phone number’s own prefix. The response tells you which rail the lookup used and which operator the number belongs to. Send it yourself only if the number has been ported, or if a response tells you the network couldn’t be determined.

Which field answers which question

Four fields look similar and answer different questions. The reference describes each one; what matters is how they relate: isValid starts from the number format, and is overridden to false when a lookup proves the destination unusable — either nothing is there, or what’s there can’t receive money. That’s stronger evidence than any format check. When the lookup couldn’t complete, isValid keeps reporting the format result, so read nameLookupStatus to see why.
A name mismatch does not make isValid false. A real account that belongs to someone other than the name you sent is still a valid account — and usually the more urgent problem. Check nameMatch.matched as well as isValid before paying out.

What to do about each outcome

Every non-matching nameLookupStatus comes with a nameLookupReason carrying the network’s own wording. Read the reason, not just the status — it’s the difference between “the account is closed” and “the system is busy”. The three that get confused are NOT_FOUND, ACCOUNT_UNAVAILABLE and ERROR. NOT_FOUND is an answer — the account isn’t there. ACCOUNT_UNAVAILABLE is also an answer, but a different one: sending your customer back to re-type a number that was correct all along just wastes their time. ERROR is not an answer at all, so treating it as a bad account turns a momentary outage into a lost payment.
ACCOUNT_UNAVAILABLE means we couldn’t resolve a name at all. If we did resolve one and the account is merely restricted, you get MATCHED plus an accountStatus — the same warning, with the name attached.

Confirming the recipient is who you expect

Send the name you’re expecting and the response scores it against the real one. Names are compared token by token rather than as exact strings, because real account names rarely come back in the format you sent them. Jane M Doe, Doe Jane Mary and Jane Mary Doe all match JANE MARY DOE; Robert Doe does not. The score is compared against a threshold configured for your account.
When the response marks the name as masked, the provider returned only part of it, so the match is based on the visible portion alone. Treat that as “not contradicted” rather than confirmed.

Blocking payouts on a name mismatch

If you’d rather not check every recipient yourself, we can enforce it for you: your bank payouts get name-checked before dispatch, and any payout whose recipient name doesn’t match is failed instead of sent. This is off by default and configured per account, including how close the match has to be. Talk to your account manager if you want it enabled.

Trying it out

Sandbox has reserved test values that resolve to frozen accounts, unresolvable accounts, mismatched names and provider timeouts, so you can build against the failure cases directly.