Most Kuda Business API operations use the same HTTP endpoint and request envelope. You choose the operation by setting serviceType.
Base URLs
Use UAT for testing and production only after your workflow has been validated.
Environment | Base URL |
UAT | |
Production |
Bank codes, bill catalogs, and test data can differ between environments. Always test and fetch reference data in the same environment where you will submit the request.
Request envelope
A standard request has three top-level fields:
Field | Type | Description |
| string | The operation you want to run. |
| string | Your unique reference for tracking and reconciliation. |
| object | The operation-specific payload. |
Example:
curl -X POST "https://kuda-openapi-uat.kudabank.com/v2.1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"serviceType": "BANK_LIST",
"requestRef": "BANK001",
"data": {}
}'
serviceType rules
Use uppercase serviceType values.
Examples:
BANK_LISTNAME_ENQUIRYSINGLE_FUND_TRANSFERTRANSACTION_STATUS_QUERYGET_BILLERS_BY_TYPEADMIN_PURCHASE_BILLBILL_TSQADMIN_CREATE_DYNAMIC_COLLECTION_ACCOUNT
requestRef rules
Your requestRef is important. It helps you:
identify the request in your own logs
reconcile pending transactions
run status queries
prevent accidental duplicate submissions
support customer or operations investigations
Use a short, unique reference. Avoid very long references, UUID-style values, or descriptive strings with many special characters for money movement calls.
Good examples:
TRF20260603001 BILL20260603001 BULK20260603001 DVA20260603001
Keep the original requestRef after every money movement request. You may need it for a status query.
Envelope exceptions
Most operations send data as an object. A few operations are different:
Operation | Exception |
|
|
| The request can be sent without a |
Example BULK_NAME_ENQUIRY:
{
"serviceType": "BULK_NAME_ENQUIRY",
"requestRef": "BNE001",
"data": [
{
"accountNumber": "2000000000",
"bankCode": "999129"
}
]
}
Example BULK_PAYMENT_TSQ:
{
"serviceType": "BULK_PAYMENT_TSQ",
"requestRef": "BULK20260603001"
}
Server-side example
Keep this code on your backend.
type KudaEnv = "uat" | "production";const baseUrls: Record<KudaEnv, string> = {
uat: "https://kuda-openapi-uat.kudabank.com/v2.1",
production: "https://kuda-openapi.kuda.com/v2.1"
};function activeEnv(): KudaEnv {
return process.env.KUDA_ENV === "production" ? "production" : "uat";
}function makeRequestRef(prefix: string) {
return `${prefix}${Date.now()}`;
}export async function kudaRequest(serviceType: string, data: unknown) {
const response = await fetch(baseUrls[activeEnv()], {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.KUDA_ACCESS_TOKEN}`
},
body: JSON.stringify({
serviceType: serviceType.toUpperCase(),
requestRef: makeRequestRef(serviceType.slice(0, 4)),
data
})
}); const text = await response.text();
const payload = text ? JSON.parse(text) : null; if (!response.ok) {
throw new Error(`Kuda request failed with HTTP ${response.status}`);
} return payload;
}
Testing checklist
Before going live:
Confirm your app is using the UAT URL during testing.
Confirm secrets are stored server-side only.
Call
BANK_LISTsuccessfully.Call
NAME_ENQUIRYsuccessfully with UAT bank codes.Confirm you are logging
requestReffor every operation.Confirm status-query handling exists before enabling money movement.
Switch to production only after production credentials and production reference data are configured.