Skip to main content

Transfers API

Settlement initiates an outbound bank transfer from a virtual account's ledger balance to any Nigerian bank account.

Before initiating any transfer, always look up the destination account number to confirm the name matches who you intend to pay. Sending to a wrong account number is irreversible once Nomba processes the transfer.


Initiate settlement

POST /v1/accounts/:accountRef/settle

Initiates an outbound bank transfer from a virtual account's confirmed ledger balance.

Settlement flow:

  1. Kanall verifies the account's ledger balance is sufficient
  2. A settlement job is created and a provisional debit entry is posted atomically
  3. A background worker submits the transfer to Nomba and polls for confirmation
  4. On success the debit is confirmed. On failure after 5 attempts the debit is reversed and the balance restored

Request body:

FieldTypeRequiredDescription
amountstringYesAmount in naira — decimal string, e.g. "5000.00"
bankCodestringYesNigerian bank code, e.g. "044" for Access Bank
accountNumberstringYesDestination 10-digit account number
narrationstringNoTransfer description
curl -X POST https://kanall.onrender.com/v1/accounts/bokku-ikeja/settle \
-H "X-API-Key: ten_sk_..." \
-H "Content-Type: application/json" \
-d '{
"amount": "5000.00",
"bankCode": "044",
"accountNumber": "0123456789",
"narration": "Supplier payment - Adebayo Foods"
}'

Response: 202 Accepted

{
"merchantTxRef": "knl_1751500000_abc12345",
"status": "pending",
"amount": "5000.00",
"currency": "NGN",
"accountRef": "bokku-ikeja"
}

merchantTxRef is generated by Kanall — you do not provide it. Store it immediately; it is the only way to track this transfer.

The transfer is queued — status: "pending" does not mean it has succeeded. Use GET /v1/transfers/:merchantTxRef to track it.

Error responses:

StatusErrorReason
400insufficient fundsLedger balance is less than the requested amount
400invalid amountAmount is zero, negative, or not a valid decimal string
404account not foundaccountRef does not exist or belongs to another tenant

Get transfer status

GET /v1/transfers/:merchantTxRef

Returns the current status of a settlement by its reference.

curl https://kanall.onrender.com/v1/transfers/knl_1751500000_abc12345 \
-H "X-API-Key: ten_sk_..."

Response: 200 OK

{
"merchantTxRef": "knl_1751500000_abc12345",
"status": "success",
"amount": "5000.00",
"bankCode": "044",
"accountNumber": "0123456789",
"attemptCount": 1,
"createdAt": "2026-07-01T12:00:00Z",
"updatedAt": "2026-07-01T12:00:04Z"
}

Transfer status values:

StatusMeaning
pendingQueued, not yet submitted to Nomba
processingSubmitted to Nomba, awaiting confirmation
successNomba confirmed the transfer. Ledger debit is confirmed.
failedAll retry attempts exhausted. Debit has been reversed.
refundedNomba accepted then reversed the transfer (rare). Debit reversed.

Lookup bank account

POST /v1/transfers/lookup

Resolves a bank account number to an account name before initiating a settlement. Always call this first — confirm the name matches who you intend to pay before sending funds.

Request body:

FieldTypeRequiredDescription
accountNumberstringYes10-digit account number
bankCodestringYesNigerian bank code
curl -X POST https://kanall.onrender.com/v1/transfers/lookup \
-H "X-API-Key: ten_sk_..." \
-H "Content-Type: application/json" \
-d '{"accountNumber": "0123456789", "bankCode": "044"}'

Response: 200 OK

{
"AccountNumber": "0123456789",
"AccountName": "ADEBAYO FOODS LTD"
}

List supported banks

GET /v1/transfers/banks

Returns all Nigerian banks and their codes. Bank codes are required for settlement and lookup requests.

curl https://kanall.onrender.com/v1/transfers/banks \
-H "X-API-Key: ten_sk_..."

Response: 200 OK

{
"banks": [
{ "Code": "044", "Name": "Access Bank" },
{ "Code": "058", "Name": "GTBank" },
{ "Code": "011", "Name": "First Bank" }
]
}