Webhooks let your app receive updates about transactions and bill payments without polling continuously.
Use webhooks together with transaction status queries. A webhook is a notification; your app should still be able to confirm important outcomes with the relevant TSQ service.
Configure your webhook URL
Sign in to the Kuda Business dashboard.
Go to Business API settings.
Open Webhooks.
Enter your public notification URL.
Add webhook authentication details.
Save the configuration.
Do not use your Kuda Business login password as the webhook password.
Webhook handler rules
Your webhook endpoint should:
accept JSON requests
authenticate the request using your configured webhook credentials
store the payload immediately
respond with HTTP
200 OKwithin 10 secondsprocess business logic asynchronously where possible
be safe to receive duplicate notifications
If your server does not respond successfully, Kuda may queue and retry delivery.
Example webhook handler
import express from "express";const router = express.Router();router.post("/webhooks/kuda", async (req, res) => {
const payload = req.body; await saveWebhookPayload({
eventType: payload.eventType,
payload,
receivedAt: new Date().toISOString()
}); res.sendStatus(200); queueWebhookProcessing(payload);
});export default router;
Transaction notification
Transaction notifications can be sent for incoming and outgoing transactions.
Example:
{
"eventType": "Transaction.Notification",
"amount": 36000,
"transactionDate": "2023-12-08T00:00:00",
"transactionReference": "231208609730",
"accountName": "Sample Business",
"accountNumber": "2050000000",
"narrations": "Incoming transfer",
"transactionType": "Credit",
"senderName": "Sample Sender",
"senderAccountNumber": "3000000000",
"recipientName": "Sample Business",
"instrumentNumber": "ITR-123",
"sessionID": null,
"clientRequestRef": "client-ref-001",
"transactionScope": "inward"
}
Important fields:
Field | Meaning |
| Event type, such as |
| Amount in kobo. |
| Kuda transaction reference. |
| Account affected by the transaction. |
|
|
| Internal transaction instrument/reference. |
| Optional client reference. |
| Direction or context, such as |
Bill payment notification
Bill notifications can include bill request and response references plus PIN or token details.
{
"eventType": "Bill.Transaction",
"BillRequestRef": "BILL20260603001",
"BillResponseReference": "mtn12345",
"Pin": {
"Number": "123456789012",
"Serial": "SERIAL123456",
"Instructions": "Use this token on the biller platform."
},
"BillerName": "MTN NG VTU",
"KudaAccountNumber": "2000000000",
"TransactionAmount": "10000",
"CustomerIdentifier": "07030000000",
"BillType": "airtime"
}
Bill payment webhooks can depend on external biller or aggregator services. If a bill webhook is delayed, use BILL_TSQ to confirm the final status.
Idempotency
Your webhook processor should handle duplicates safely.
Use stable identifiers such as:
eventTypetransactionReferenceinstrumentNumberBillRequestRefBillResponseReferenceclientRequestRef
Store processed event identifiers so duplicate deliveries do not double-credit orders or trigger duplicate fulfillment.
Webhooks and TSQ
Use the matching status-query service when a webhook is missing, delayed, or unclear:
Flow | Status-query service |
Single transfer |
|
Bulk payment |
|
Bill payment |
|
Dynamic account collections |
|
Common mistakes
Doing heavy processing before sending
200 OK.Not storing the raw webhook payload.
Assuming webhook delivery will be instant.
Not handling duplicate notifications.
Treating
instrumentNumberas a bank account number.Depending only on webhooks without TSQ fallback.