API Reference
Query wallet data from your own app or server using a personal API key. All requests are made over HTTPS to the base URL below.
Authentication
Every request needs two headers: X-Public-Key identifies you as a known API caller, and the Authorization bearer token is your secret key that authorizes access to your account's data. Both come from the Developer tab in your dashboard and must belong to the same account.
X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx
Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxxX-Public-Key and it's not just rejected. Your IP gets blocked from calling this API for 30 minutes, so check that header first before you look anywhere else.Errors
| Status | Meaning |
|---|---|
400 | Missing or unrecognized public key. Your IP is temporarily blocked |
401 | Missing, invalid, or revoked secret key |
403 | Account below Tier 1 verification |
404 | Unknown endpoint, or payment reference not found |
405 | Wrong HTTP method for this endpoint |
429 | Too many requests, slow down and retry |
502 | The payment provider rejected the request, try again |
Rate limits
60 requests per minute per IP address. Requests over the limit get a 429 with a short cooldown message.
Get wallet balance
/v1/balance
Returns the current wallet balance for the account that owns the key.
curl https://api.kavopaywalletz.com/v1/balance \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx"const res = await fetch("https://api.kavopaywalletz.com/v1/balance", {
headers: {
"X-Public-Key": "kavo_pub_xxxxxxxxxxxxxxxx",
Authorization: "Bearer kavo_live_xxxxxxxxxxxxxxxx"
}
});
const data = await res.json();
console.log(data.balance);const https = require("https");
https.get("https://api.kavopaywalletz.com/v1/balance", {
headers: {
"X-Public-Key": "kavo_pub_xxxxxxxxxxxxxxxx",
Authorization: "Bearer kavo_live_xxxxxxxxxxxxxxxx"
}
}, res => {
let body = "";
res.on("data", chunk => body += chunk);
res.on("end", () => console.log(JSON.parse(body)));
});Response
HTTP/1.1 200 OK
{
"ok": true,
"balance": 42500.00,
"currency": "NGN"
}Initiate a payment
/v1/payments
Starts a payment. Once it's paid, the amount is credited straight to your Kavopay wallet, same as it always has, withdrawable anytime from the Kavopay app or website. Currency is always NGN, that's the only currency Kavopay wallets hold.
| Field | Required | Notes |
|---|---|---|
amount | Always | Minimum ₦100. No upper limit, that only applies to transfers out of your wallet, not deposits into it |
method | Always | card, opay, ussd, or bank_transfer |
redirect_url | card, opay only | Where your customer lands after paying |
bank_code | ussd only | See supported banks below |
Card
Returns a Flutterwave-hosted checkout link. Your customer enters card details there, never on your own server, keeps you out of PCI-DSS scope entirely.
curl -X POST https://api.kavopaywalletz.com/v1/payments \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount":5000,"method":"card","redirect_url":"https://yoursite.com/paid"}'{
"ok": true,
"method": "card",
"reference": "KAVO-CARD-A1B2C3D4-1736500000000",
"payment_link": "https://checkout.flutterwave.com/v3/hosted/pay/xxxxxxxxx"
}OPay
Same shape as card, a redirect link, this time to OPay's own checkout.
curl -X POST https://api.kavopaywalletz.com/v1/payments \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount":5000,"method":"opay","redirect_url":"https://yoursite.com/paid"}'{
"ok": true,
"method": "opay",
"reference": "KAVO-OPAY-A1B2C3D4-1736500000000",
"payment_link": "https://checkout.flutterwave.com/opay/xxxxxxxxx"
}USSD
Returns a USSD code your customer dials on their phone to complete payment, no internet needed on their end. Needs a bank_code from the supported list:
| Bank | Code |
|---|---|
| Access Bank | 044 |
| GTBank | 058 |
| UBA | 033 |
| Zenith Bank | 057 |
| First Bank | 011 |
| Fidelity | 070 |
| Sterling | 232 |
| Union Bank | 032 |
| Polaris | 076 |
| Keystone | 082 |
curl -X POST https://api.kavopaywalletz.com/v1/payments \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount":5000,"method":"ussd","bank_code":"058"}'{
"ok": true,
"method": "ussd",
"reference": "KAVO-USSD-A1B2C3D4-1736500000000",
"ussd_code": "*737*000*5000#",
"payment_code": "000000",
"bank_code": "058"
}Bank transfer
Returns your account's permanent virtual account number, the same one every time. Any transfer into it credits your wallet automatically, no reference, no verify support for this method, just watch for the webhook or check your balance.
curl -X POST https://api.kavopaywalletz.com/v1/payments \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"amount":5000,"method":"bank_transfer"}'{
"ok": true,
"method": "bank_transfer",
"account_number": "8012345678",
"bank_name": "Wema Bank",
"account_name": "Your Registered Name",
"currency": "NGN",
"note": "This is your permanent account number, reused for every deposit."
}Verify a payment
/v1/payments/:reference
Re-checks a card, OPay, or USSD payment's status. This never credits your wallet itself, it only reports what's true, your wallet is always credited by Kavopay's own systems, this just tells you where things stand.
curl https://api.kavopaywalletz.com/v1/payments/KAVO-CARD-A1B2C3D4-1736500000000 \
-H "X-Public-Key: kavo_pub_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer kavo_live_xxxxxxxxxxxxxxxx"{
"ok": true,
"reference": "KAVO-CARD-A1B2C3D4-1736500000000",
"method": "card",
"amount": 5000,
"status": "successful"
}| Status | Meaning |
|---|---|
pending | Customer hasn't completed payment yet |
processing | Payment confirmed, wallet credit is finalizing |
successful | Credited to your wallet |
failed | Payment failed or was cancelled |
Webhooks
Set a webhook URL from the Developer tab in your dashboard, and every successful API-initiated payment posts here automatically, no polling needed.
{
"event": "payment.successful",
"reference": "KAVO-CARD-A1B2C3D4-1736500000000",
"amount": 5000,
"currency": "NGN",
"method": "card",
"status": "successful",
"timestamp": "2026-09-10T18:53:00.000Z"
}Every request carries an X-Kavopay-Signature header, an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret. Recompute it yourself and compare before trusting the payload.