Getting Started

API Key Authentication

Every server-to-server call to Infinity Africa is authenticated with an API key — a long-lived credential scoped to your merchant account. There's no OAuth dance, no token refresh: generate a key once, send it on every request.

Two ways to authenticate

API key — for your backend

Send Authorization: Bearer <INFINITY_API_KEY> (or the equivalent X-API-Key: <key> header) on any request originating from your own server (a website checkout, a mobile app's backend, an ecommerce platform's order webhook). This is what these docs cover.

Dashboard session — for the Infinity Africa portal only

The merchant dashboard itself authenticates with a Supabase Auth session token, also sent as Authorization: Bearer <access_token> — Infinity Africa tells the two apart by prefix, not by header. You won't use this in your own integration — it's only relevant if you're embedding the Infinity Africa dashboard itself.

Generating a key

Full API credentials are only ever generated inside the authenticated Merchant Portal — sign in at Merchant Portal, go to API Keys, choose Sandbox or Live, name the key, and check the scopes it needs (least privilege — a checkout integration only needs collections:write, for example). There is no public endpoint to generate a key — only POST /v1/merchant/api-keys, which requires a signed-in dashboard session:

POST/v1/merchant/api-keys

Create an API key for your own merchant — the plaintext key is shown once, in the response.

MERCHANT_ADMIN, DEVELOPER (dashboard session)
json — request
{
  "name": "Production checkout server",
  "environment": "live",
  "scopes": ["collections:write", "payment_links:read"],
  "ip_whitelist_enabled": false,
  "continue_without_ip_whitelist": true
}
json — response
{
  "success": true,
  "data": {
    "id": "8f14e...",
    "name": "Production checkout server",
    "environment": "live",
    "key_prefix": "inf_live_9f2a1c3b",
    "key_last4": "d8e7",
    "scopes": ["collections:write", "payment_links:read"],
    "ip_whitelist_enabled": false,
    "continue_without_ip_whitelist": true,
    "plaintext_key": "inf_live_9f2a1c3bd8e7...",
    "status": "active",
    "created_at": "2026-08-14T09:00:00Z"
  }
}
warning

Copy the plaintext key now — it won't be shown again

plaintext_key is only ever returned once, on creation. Infinity Africa stores only a SHA-256 hash — never the plaintext, never a recoverable/encrypted form — so there is no “reveal” button anywhere, including for Infinity Africa staff. If you lose a key, there's exactly one fix: rotate it (see below).

Scopes

Every key is issued with an explicit set of scopes — it can only call the endpoints those scopes cover. A request with a key missing the required scope gets a 403, not a partial success.

ScopeGrants
collections:writePush USSD/STK/Selcom Pesa collections, generate Dynamic QR codes.
collections:readRead back collection status (dashboard-scoped listing).
payment_links:writeCreate and cancel payment links.
payment_links:readFetch a payment link by ID.
invoices:writeCreate, edit, send, and cancel invoices.
invoices:readFetch an invoice by ID.
transactions:readLook up a transaction by reference.
webhooks:manageConfigure the webhook URL, events, and secret.

Sandbox vs. Live

Every key is scoped to an environment. Sandbox keys (prefix inf_sandbox_...) run against a fully simulated provider — nothing settles for real, so you can build and test your entire integration risk-free. Live keys (inf_live_...) move real money. Sandbox keys never expire on their own; both can be revoked at any time.

Both are self-service — creating a Sandbox key never requires approval. A Live key is also created directly from the dashboard, the moment your business account is approved, KYC-verified, and has pricing assigned; there is no separate “request production access” step or waiting on Infinity Africa staff. Before that, creating a Live key returns:

json — 403 response
{
  "success": false,
  "error": {
    "code": "production_access_restricted",
    "message": "Production API keys are available after your business account is approved."
  }
}

Using your key

Attach it as a header on every request — never as a query parameter or in the request body, where it's more likely to end up logged somewhere:

http
GET /v1/transactions/TXN-4821AB HTTP/1.1
Host: api.infinityafrica.net
Authorization: Bearer inf_live_9f2a1c3bd8e7...

IP whitelisting (optional)

Every key makes a choice, at creation, between two options — there is no default forced on you:

  • Continue without IP whitelisting (the default) — the key authenticates from any server IP. Simpler, and fine for most integrations.
  • Enable IP whitelisting — requests only succeed from IPs you explicitly approve. Add them from the Merchant Portal's IP Allowlist page (label, IP or CIDR, environment); each starts pending until a Super Admin approves it. A request from an unapproved IP gets a 403, and the attempt is logged.
info

Enforced for live traffic only

Sandbox requests are never IP-restricted, regardless of this setting — there's nothing real to protect there. For production, enabling IP whitelisting is recommended for stronger security, especially if your backend runs on a small, fixed set of server IPs.

Revoking or rotating a key

PATCH/v1/merchant/api-keys/{key_id}/revoke

Revoke a key immediately — any request using it afterward gets 401.

MERCHANT_ADMIN, DEVELOPER (dashboard session)
POST/v1/merchant/api-keys/{key_id}/rotate

Revoke a key and create its replacement (same name/environment/scopes/IP-whitelist choice) in one call. The new plaintext key is returned once, same as creation.

MERCHANT_ADMIN, DEVELOPER (dashboard session)

Rotate keys periodically from the Merchant Portal, revoke any key that may have leaked (committed to a public repo, shared in a support ticket, etc.) immediately rather than waiting for a scheduled rotation — and if you simply lose a key before copying it down, rotate is also how you recover: there is no way to view a key's secret again after creation, by design.

Keep it secret, keep it server-side

warning

Never ship an API key to a browser, mobile app bundle, or public repo

A key embedded in client-side JavaScript, a mobile app binary, or committed source code can be extracted by anyone. Keep API keys on your server; have your website, ecommerce platform, or mobile app call your own backend, which then calls Infinity Africa — never call Infinity Africa directly from code that ships to a customer's device or browser.