RADOK

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

A test balance and a live balance are separate accounts. An API key already carries its environment, so a programmatic caller never names one; a dashboard session must pass ?environment=test or ?environment=live.

Read your balance

GET/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
curl https://api.radokpay.com/v1/ledger/balance \
  -H "Authorization: Bearer $RADOK_SECRET_KEY"
200 OK
{
  "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

The endpoint accepts no 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

GET/v1/ledger/entries
Auth
Secret key or dashboard session
Scope
collections:read

Query parameters

FieldTypeDescription
limitinteger1–100. Defaults to the standard page size.
cursorstringThe meta.nextCursor from the previous page.
environment"test" | "live"Required for a dashboard session. Ignored for an API key, which carries its own.
curl
curl "https://api.radokpay.com/v1/ledger/entries?limit=2" \
  -H "Authorization: Bearer $RADOK_SECRET_KEY"
200 OK
{
  "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

A ledger entry carries a direction, an amount, and the balance that resulted. It carries no description, no reference, and no type. It is deliberately the raw double-entry record, and on its own it will not tell a human what a debit was for.

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:

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.

  1. Go to Overview in the dashboard. If no funding account exists yet, the card offers to generate one.
  2. Copy the bank name, account number, and account name shown under Funding account.
  3. Transfer to it from your corporate bank account.
  4. Watch for wallet.funding.success, or poll GET /v1/ledger/balance.
GET/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.

200 OK
{
  "data": {
    "reference": "va_9f31c0d7b4e2a685",
    "bankName": "Providus Bank",
    "accountNumber": "9901234567",
    "accountName": "RADOK/ACME LTD"
  }
}

An API key cannot read this

Calling /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

FieldTypeDescription
AUTH_REQUIRED401No credential, or a secret key on a dashboard-only route such as /v1/wallet/funding-account.
SCOPE_INSUFFICIENT403The key exists but lacks collections:read. Add the scope by rotating the key — scopes are fixed at creation.
VALIDATION_ERROR422A dashboard session that omitted environment, or a limit outside 1–100.