Overview
The Money Transfer API sends funds from your Hyparrow wallet to any Nigerian bank account over the bank network. The flow is always the same: list the supported banks, resolve the recipient’s account name from their account number, initiate the transfer, then poll for the final status. When you initiate a transfer, Hyparrow debits the principal from your wallet before calling the bank network, then books the fee as a separate debit only after the network accepts the transfer. If the network rejects the transfer, the principal debit is automatically reversed, so a rejected transfer never leaves your wallet short. If the network does not answer (a timeout), the transfer is treated as submitted, never reversed on a guess, and its outcome comes by webhook. See Unknown outcome.Base URL:
https://api.hyparrow.cloud/api/v1Auth: every request requires X-API-Key and X-API-Secret headers.Sandbox: point at https://sandbox.hyparrow.cloud/api/v1 and use your
pk_test_ key. Simulate outcomes with magic amounts, an amount ending in .01
is rejected at submission (the send returns 400, the principal is reversed,
no fee is charged and transfer.reversed fires), and .99 stays pending
(accepted, never settles) so you can test status polling. Everything else is
accepted and later settles, firing transfer.settled.The transfer flow
1
List banks
GET /money-transfer/banks returns supported banks. Each entry has a
bankCode, use this exact value for inquiry and send.2
Resolve the account name
POST /money-transfer/account-inquiry (or GET) with the account number and
bank code returns the registered account name. Show it to the user to confirm.3
Send
POST /money-transfer/send debits the wallet (principal first, then fee on
success) and initiates the transfer over the bank network.4
Poll status
GET /money-transfer/status?reference=<transferCode|clientReference> (or POST) returns the
current status until it settles.List banks
List banks
Response
Always use the
bankCode field (the CBN code) for account-inquiry and send.
The separate code field is an internal identifier and is not used for transfers.Resolve the account name
Confirm the recipient before you send. Supply theaccountNumber and the
bankCode from the bank list. This endpoint accepts both GET (query params) and
POST (JSON body).
Account inquiry (GET)
Account inquiry (POST)
Response
accountName you get back is what you pass as recipientName when you send.
Send a transfer
POST /money-transfer/send initiates the transfer. The wallet is checked for the
principal plus the fee up front; the principal is debited before the bank
network is called, and the fee is debited only after the network accepts.
Request body
Idempotency
AclientReference names exactly one transfer, for good. It is never
expired or reused.
A replay returns the transfer as it stands, including
Status: "reversed" if the
first attempt was rejected. To try again after a rejection, send a new
clientReference.
409 Response
Idempotency-Key header, which works across all money
routes. A key is remembered for 24 hours; a repeat with the identical body
replays the first successful response, and a repeat with a different body gets
422 IDEMPOTENCY_KEY_REUSED. Only successful responses are remembered, so a
request refused with a 4xx (for example insufficient balance) can be retried
with the same key once the cause is fixed. For transfers, clientReference is
the stronger guarantee: it never expires and it holds across keys.
Send
Response
Status: "pending" means accepted and not yet settled. The final outcome arrives
on transfer.settled or transfer.failed, normally within about 10 minutes.
Keep data.TransferCode, it is the reference you use to check status. If you
sent a clientReference, you can check status with that instead and do not need
to have received this response at all.
Wallet debit and fees
The total debited is principal + fee:- The wallet must cover the principal and the fee, or the send is rejected before anything is charged.
- The principal is debited first (atomically, with a row lock) so funds can’t leak if the network call partially fails.
- The fee is a flat amount based on your transfer fee class and the amount tier. It is booked as a separate debit and only after the network accepts the transfer, a failed or reversed transfer is never charged a fee.
data.Fee is the fee in kobo, data.FeeClass is the fee class applied, and
data.WalletBalance is your remaining balance after principal + fee.
Fee schedule
GET /money-transfer/fee-class returns the fee ladder for your own account, so
you can quote the fee before sending and reconcile it after.
Fee class
Response
Tiers come back ordered ascending: to price a transfer, convert the principal to
Naira and take the
fee of the first band whose max is null or >= amount.
A ₦5,000 transfer on the response above costs ₦25; a ₦200,000 transfer costs ₦77.
Check status
GET /money-transfer/status?reference=<transferCode> (or POST with a JSON body)
returns both Hyparrow’s local transaction record and the latest network status.
reference accepts either the transferCode from the send response or
the clientReference you sent with the transfer. Both are scoped to the calling
merchant: you can only ever read your own transfers, by either name for them.
Looking up by clientReference is what makes a transfer recoverable when the
send response was lost.
Status
Response
settlementStatus to know where the money is:
status is the ledger row’s own state and reads success from the moment of the
debit, so it does not tell you whether the transfer landed. provider is the
network’s live answer, fetched on each call.
Edge cases
Unknown outcome (202)
If the bank network does not answer (a timeout, a dropped connection, a5xx),
the transfer may or may not have gone through, and refunding on a guess is how a
payout ends up sent twice. So Hyparrow treats it as submitted: the principal and
fee stay debited and you get 202 Accepted with the transferCode.
202 Response
transfer.reversed tells you.
A pending transfer (a
.99 amount in sandbox, or a slow settlement in
production) has been accepted but not yet settled. Poll /money-transfer/status
until settlementStatus moves to delivered, failed or reversed, or wait for
the webhook. The principal stays debited while pending.
