RADOK

Authentication

Create an API key, send it, and understand scopes, environments, and rotation.

Contents

Creating an API key

Keys are created in the dashboard, never through the API — a key that could mint another key would make every key equivalent to the strongest one.

  1. Go to Developers → API keys.
  2. Use the environment switch in the top bar to choose test or live. A key belongs to exactly one of them.
  3. Choose Secret — keys are for server-side use. Never ship one to a browser, a mobile binary, or a repository.
  4. Tick the scopes the integration actually needs. You can create a narrower key later.
  5. Copy the key. It is shown once: Radok stores only a keyed hash, so there is no way to reveal it again — not for you, and not for us.

Live keys need approved KYB

Creating a live key returns 403 KYB_LIVE_REQUIRED until your business verification is approved. Test keys are available immediately.

Sending the key

Pass the key as a bearer token on every request. There is no other accepted form — no query parameter, no custom header.

Header
Authorization: Bearer sk_test_a1b2c3_YOUR_KEY
curl
curl https://api.radokpay.com/v1/collections \
  -H "Authorization: Bearer $RADOK_SECRET_KEY"
Node.js
const response = await fetch("https://api.radokpay.com/v1/collections", {
  headers: {
    Authorization: `Bearer ${process.env.RADOK_SECRET_KEY}`,
  },
});

const { data, meta } = await response.json();
Python
import os, requests

response = requests.get(
    "https://api.radokpay.com/v1/collections",
    headers={"Authorization": f"Bearer {os.environ['RADOK_SECRET_KEY']}"},
    timeout=30,
)
body = response.json()

Read the key from the environment

Every example here reads the key from an environment variable rather than inlining it. Keys committed to a repository are the single most common way they leak.

Key format

A key encodes what it is, where it works, and which merchant it belongs to. The merchant fragment lets a leaked key be traced back to an account during an incident without a database lookup.

Anatomy
sk_test_a1b2c3_kJ8nQv2xLp...
│  │    │      └── 28 random bytes, base64url
│  │    └───────── 6-character merchant fragment
│  └────────────── environment: test | live
└───────────────── type: sk (secret)

Key types

FieldTypeDescription
sk_secretFull access within its scopes. Server-side only. Never ship one to a browser, a mobile binary, or a repository.

Scopes

A key carries an explicit list of what it may do. A request outside that list is rejected with 403 SCOPE_INSUFFICIENT before any business logic runs.

Available scopes

FieldTypeDescription
collections:readreadList and read collections.
collections:writewriteCreate collections.
virtual_accounts:readreadList and read virtual accounts.
virtual_accounts:writewriteMint a virtual account. Billable in live mode.
payouts:readreadList and read payouts and saved payout accounts.
payouts:writewriteCreate a payout. This moves money — grant it deliberately.
kyc:readreadRead past KYC verifications.
kyc:writewriteRun a BVN or NIN verification. Billable in live mode.

Webhooks are configured in the dashboard

API keys do not manage webhook URLs, signing secrets, or delivery history. Set those under Developers → Webhooks while signed in — separately for test and live — then follow the webhooks guide to verify each delivery your endpoint receives.

Your own role caps the key

A key can never hold more than the person creating it holds. If a Developer requests payouts:write, that scope is silently dropped rather than granted — so a bug in a permission check can never produce a payout-capable key from a Developer session.

Test and live

Everything in Radok — credentials, ledger balances, virtual accounts, collections, payouts, webhook endpoints and their signing secrets — exists twice, once per environment. The two never see each other.

  • test always routes through a stub gateway. No real bank is contacted, no fee is charged, and no money moves.
  • live routes through the real PSP and requires an approved KYB application.

Configure both webhook endpoints

A webhook URL saved in test mode does not exist in live mode. Going live with an unset live endpoint means events are dropped, not queued.

Rotating a key

Rotation creates a new key immediately and lets you choose how long the old one keeps working, so you can deploy without a window where neither key is valid.

  1. On the API keys page, choose Rotate and pick a grace period, up to 24 hours.
  2. Copy the new key. Like creation, it is shown once.
  3. Deploy it everywhere.
  4. The old key stops working when the grace period ends. Choose No overlap instead if the key is already compromised — that revokes it the instant the new one is issued.

Rotating and revoking both require re-entering your password and 2FA code. That is deliberate: a stolen dashboard session should not be enough to lock you out of your own integration.

Rate limits

Limits are counted per key, not per IP — your servers usually share one egress address, so an IP-based limit would either starve real traffic or be meaningless.

Limits by route class

FieldTypeDescription
Reads300 / minuteEvery GET endpoint.
Writes30 / minuteCreating virtual accounts, payouts, KYC checks.
Write burst10 / 10 secondsAn additional short-window cap on the same write endpoints.

Exceeding a limit returns 429 RATE_LIMITED with a Retry-After header in seconds. Wait at least that long — retrying sooner just consumes the next window.

IP allowlist

A key can be restricted to a set of source addresses in CIDR notation. When the list is empty, every address is accepted; when it is non-empty, anything outside it is rejected with 403 IP_NOT_ALLOWED before the key is even considered valid.

Worth setting for live secret keys

If your integration runs from fixed infrastructure, an allowlist turns a leaked key into a key that only works from your own network. Contact support to configure one for a key.

If a key leaks

  1. Revoke it. Not rotate — revoke. Rotation with a grace period leaves the leaked key working for the length of that window.
  2. Create a replacement and deploy it.
  3. Check your webhook deliveries and your payouts for activity you do not recognise.
  4. Payout destinations are safe from a leaked key on their own: adding or changing one is a dashboard action gated behind your password and 2FA, and is not reachable with an API key at all.