Skip to main content
Two lookups belong before every payout: which institution to route to, and who actually holds the account. Both need the identity:enquiry scope, and neither writes anything.

Why the code matters

destination_provider_name is a display name. It is stored on the payout and shown back to you, and it is never used to route money. destination_provider_code is the machine code the processor routes on — a bank code for BANK_ACCOUNT, a mobile money code for MOBILE_MONEY. It is required for both, and a payout without it is rejected at validation.
Do not hardcode codes, and do not derive them from a bank’s name. They are set by the upstream institution directory, differ in format between countries, and can change without a version bump on our side. Read them from GET /v1/banks and cache them for hours, not months.

List payable institutions

Rows come back sorted by name, and every row is guaranteed to carry a usable code — entries the upstream directory returns without one are dropped rather than handed to you to fail on at dispatch.
Banks and mobile money providers are never mixed in one response, even though they come from the same upstream directory. Ask for the type you intend to pay. Requesting a directory for CRYPTO_WALLET is a 400 — chains have no institutions.
The list is cached for about six hours and is identical for every merchant. An empty result is never cached, so an unconfigured corridor or a bad upstream day does not look like “this country has no banks” for the rest of the day.

Confirm the account holder

Name enquiry, so you find out about a wrong account number before money moves.
The request and response fields are named exactly as the payout request expects them, so the normal flow is: resolve, then spread the result into your payout body along with the confirmed name.
Use the returned name as destination_account_name, not what your user typed. It is what the institution holds, and it is what a dispute or a reconciliation will be judged against.

Why this is a POST

It reads rather than writes, but the account number is PII and has no business sitting in a query string that gets written to every access log between you and us. For the same reason it carries no Idempotency-Key requirement — there is nothing to make idempotent.

Caching

Results are cached about five minutes per account. Name enquiry APIs are rate-limited upstream and the same account often appears across several payouts in a session, so a tight loop over the same beneficiary costs one upstream call rather than many.

Errors

An institution that returns a blank name is treated as INVALID_DESTINATION_ACCOUNT rather than handed back as an empty name — a blank destination_account_name written onto a payout would fail at dispatch for a much less obvious reason. A 503 is transient; retry with backoff. Note that a Redis outage does not surface as an error here — the cache is a latency optimisation, and a failed cache read falls through to a direct upstream call.
Resolving is not yet enforced as a pre-flight on payout creation, so a payout with an unverifiable account number is currently accepted and fails later at dispatch instead. Calling /v1/banks/resolve yourself is what turns that late, confusing failure into an immediate, actionable one — treat it as required even though we do not yet reject without it.

Crypto destinations

CRYPTO_WALLET payouts have neither a directory nor a name to confirm — chains have no account names. Omit destination_provider_code and destination_account_name entirely, and validate the address yourself before creating the payout. There is no recovery from a wrong address.