Introduction

What Acute Infra is, and the mental model that makes everything else obvious: wallets, the ledger, and references.

Acute Infra is a Banking-as-a-Service API for Nigeria. You get wallets to hold money, a double-entry ledger that records every movement, and the rails to collect and disburse naira, all behind one typed HTTP API. You are not becoming a bank. You are renting ours.

If you read nothing else, read this page. Three ideas (wallets, the ledger, and references) explain the entire surface.

A wallet is an account that holds a balance in a single currency (NGN, for now). There are two flavours:

KindHoldsTypical use
settlementyour platform's moneycollections settle here, fees are debited here
end_usera customer's moneyper-user balances inside your app

A wallet has a status (active, frozen, closed), a KYC tier (none or tier1), and a balance you can read at any time. The balance is never a guess: it is the sum of the ledger.

available == ledger

Acute has no separate "available" vs "pending" balance and no opaque holds. What the ledger says is what you can spend. One number, always reconcilable.

Every time money moves, Acute writes a double-entry transaction: equal and opposite legs that sum to zero. Money is debited from one account and credited to another. It is never created or destroyed, only moved.

When a payment settles into a wallet, three legs fire at once:

payment settle (the real legs)
text
DEBIT   inbound_suspense   base + fee
CREDIT  wallet             base
CREDIT  acute_fees         fee

The suspense account is debited for the full amount that arrived; your wallet is credited the base; Acute keeps its fee. The three legs balance to zero. This is why your balance is always exactly right: there is no separate "apply the fee later" step that can drift.

This is the differentiator

Most BaaS APIs hand you a balance and ask you to trust it. Acute hands you the ledger. Every naira is traceable to the leg that moved it.

Every resource Acute creates gets a reference: a single, lowercase, separator-free string you can store, log, and quote back to support:

text
acuinf{12 digits}{domain}

Twelve random digits, wrapped by the acuinf prefix and a short domain suffix that names the resource. So acuinf938174026551pay is a payment, and …wlt is a wallet. Paste one in below to see it pulled apart:

This is a Payment (suffix pay).Decoded: a Payment. Prefix acuinf, body 9 3 8 1 7 4 0 2 6 5 5 1, suffix pay.
Try:
SuffixResource
wltwallet
paypayment
trftransfer
wthwithdrawal
pyopayout
rfdrefund
evtwebhook event

One reference, everywhere: it is the id you store, the value the bank rail echoes back, and the string in the webhook. The UI may uppercase it for display, but the canonical form is lowercase. The full decoder + suffix map covers every domain.

Money is always an integer number of kobo (1 naira = 100 kobo), carried as a plain JSON integer. There are no floats anywhere in the API: ₦1,500.00 is 150000. This is not negotiable; floating-point money is how you end up off by a kobo at scale.