Wallet and balance
Read your balance, read the ledger behind it, and fund it.
Contents
Your balance is a ledger, not a number
Every naira Radok holds for you sits in a double-entry ledger. A collection credits your account; a payout debits it, along with its fee, in the same atomic transaction. What the balance endpoint returns is not a running total someone increments — it is the current position of your merchant_liability account, and it is the same number the payout endpoint checks before it lets money leave.
That matters for one practical reason: you cannot overspend by racing yourself. Two concurrent payouts against the same balance are serialised inside one ledger transaction, so the second one gets INSUFFICIENT_BALANCE rather than both succeeding.
Balances are per environment and per currency
?environment=test or ?environment=live.Read your balance
/v1/ledger/balance- Auth
- Secret key or dashboard session
- Scope
- collections:read
Gated on collections:read rather than a payouts scope — seeing your balance is the same trust level as seeing the collections that produced it.
curl https://api.radokpay.com/v1/ledger/balance \
-H "Authorization: Bearer $RADOK_SECRET_KEY"{
"data": {
"value": 4850000,
"currency": "NGN"
}
}value is in kobo, like every other amount in the API — 4850000 is ₦48,500.00. Divide by 100 for display and never store it as a float.
NGN only, for now
currency parameter. Anything you pass is ignored and the NGN balance is returned. When a second currency ships, this endpoint gains a parameter rather than changing its default.Read your ledger entries
/v1/ledger/entries- Auth
- Secret key or dashboard session
- Scope
- collections:read
Query parameters
| Field | Type | Description |
|---|---|---|
| limit | integer | 1–100. Defaults to the standard page size. |
| cursor | string | The meta.nextCursor from the previous page. |
| environment | "test" | "live" | Required for a dashboard session. Ignored for an API key, which carries its own. |
curl "https://api.radokpay.com/v1/ledger/entries?limit=2" \
-H "Authorization: Bearer $RADOK_SECRET_KEY"{
"data": [
{
"_id": "6712f0c8a1b2c3d4e5f60718",
"transactionId": "6712f0c8a1b2c3d4e5f60717",
"accountId": "66f1a2b3c4d5e6f708192a3b",
"direction": "debit",
"amount": { "value": 250000, "currency": "NGN" },
"balanceAfter": { "value": 4850000, "currency": "NGN" },
"environment": "live",
"createdAt": "2026-08-30T09:14:22.481Z"
},
{
"_id": "6712efb0a1b2c3d4e5f60712",
"transactionId": "6712efb0a1b2c3d4e5f60711",
"accountId": "66f1a2b3c4d5e6f708192a3b",
"direction": "credit",
"amount": { "value": 495000, "currency": "NGN" },
"balanceAfter": { "value": 5100000, "currency": "NGN" },
"environment": "live",
"createdAt": "2026-08-30T08:02:10.093Z"
}
],
"meta": { "nextCursor": "6712efb0a1b2c3d4e5f60712", "hasMore": true }
}These are accounting legs, not a statement
If what you actually want is a readable transaction history — “₦2,500 paid out to GTBank ***4471” — build it from the resources that carry those facts and merge them by timestamp:
GET /v1/collectionsfor money in, with the customer, the reference, and the fee.GET /v1/payoutsfor money out, with the destination and the status.
Use /v1/ledger/entries alongside those when you need balanceAfter for a running-balance column, or when you are reconciling and want the ledger’s own view rather than the resource view.
Funding your wallet
Payouts spend your Radok balance, so the balance has to get there first. Every merchant has one permanent virtual account — the funding account — that exists for exactly this. Send money to it from your own bank and it is credited to your balance, and Radok fires a wallet.funding.success webhook when it lands.
Unlike the collection virtual accounts you mint per customer, the funding account is not amount-specific and does not close after a payment. It is yours, it is reusable, and it is per environment.
- Go to Overview in the dashboard. If no funding account exists yet, the card offers to generate one.
- Copy the bank name, account number, and account name shown under Funding account.
- Transfer to it from your corporate bank account.
- Watch for
wallet.funding.success, or pollGET /v1/ledger/balance.
/v1/wallet/funding-account- Auth
- Dashboard session
- Scope
- collections:read
Dashboard-only. There is no API-key equivalent — a programmatic integration should read these details once from the dashboard and hold them in configuration.
{
"data": {
"reference": "va_9f31c0d7b4e2a685",
"bankName": "Providus Bank",
"accountNumber": "9901234567",
"accountName": "RADOK/ACME LTD"
}
}An API key cannot read this
/v1/wallet/funding-account with a secret key returns 401 AUTH_REQUIRED. The details are static once issued, so the intended pattern is to copy them into your own configuration rather than fetch them on every boot. If your server needs to display them, store them yourself.What can go wrong
Errors
| Field | Type | Description |
|---|---|---|
| AUTH_REQUIRED | 401 | No credential, or a secret key on a dashboard-only route such as /v1/wallet/funding-account. |
| SCOPE_INSUFFICIENT | 403 | The key exists but lacks collections:read. Add the scope by rotating the key — scopes are fixed at creation. |
| VALIDATION_ERROR | 422 | A dashboard session that omitted environment, or a limit outside 1–100. |