Wallets

The two wallet kinds, the status lifecycle, KYC tiers (none vs tier1), the limits tier1 unlocks, and the response shape.

A wallet is an account in the ledger that holds a balance in one currency (NGN, today). It is the unit you collect into, transfer between, and disburse from. Two kinds, a small status lifecycle, and a KYC tier: that's the whole model.

KindHoldsUse it for
settlementyour platform's moneycollections settle here; fees debit here
end_usera customer's moneyper-user balances inside your app

A settlement wallet is your house account: collections land in it, fees come out of it. You don't create it; it is provisioned for you (a test settlement wallet on signup, a live one once your KYB is approved). An end_user wallet is one you open per customer via the API, so each user has their own balance you can pay into and disburse from. The public POST /wallets endpoint creates end_user wallets only; it does not mint settlement wallets. Same ledger underneath; the kind is just intent.

A balance is ledger truth: the live sum of every credit and debit on the wallet. There is no separate bank account you own behind it; Acute holds the funds on the bank rail centrally, and your balance is what the ledger says it is.

A wallet's status is one of:

  • active: the normal state; money moves freely.
  • frozen: money movement is paused (compliance, dispute, your own hold). The wallet still exists and reads still work.
  • closed: terminal. The wallet is retired and won't accept new movement.

A wallet's kycStatus is none or tier1. KYC governs how much an end_user wallet may hold and move.

TierWhat it isLimits
nonethe default (no identity on file)reads only; can't hold to tier1 levels
tier1identity submitted via POST /wallets/:id/kycbalance ≤ ₦300,000; ≤ ₦50,000 per transaction

The tier1 limits are exact:

  • TIER1_MAX_BALANCE = 30_000_000 kobo = ₦300,000
  • TIER1_MAX_PER_TRANSACTION = 5_000_000 kobo = ₦50,000

Exceeding either returns WALLET_TIER1_LIMIT_EXCEEDED. Reading the balance of a wallet that hasn't reached tier1 returns WALLET_KYC_REQUIRED, so KYC is a precondition for the balance read on end-user wallets.

KYC here is stored, not verified

POST /wallets/:id/kyc records the customer's details and flips the wallet to tier1. Acute does not independently verify them. You, the merchant, are liable for their accuracy (this is distinct from your own KYB, which a human does review). The BVN must be 11 digits; country defaults to NG.

bvn (11 digits), dateOfBirth (YYYY-MM-DD), gender (male/female/other), phone, addressLine1, city, state, plus optional addressLine2, country (defaults NG), and postalCode.

WalletResponseData, returned on create/get/list:

a wallet
json
{
  "id": "acuinf472095183640wlt",
  "kind": "settlement",
  "email": "ops@yourco.com",
  "fullName": null,
  "phone": null,
  "externalReference": null,
  "kycStatus": "none",
  "status": "active",
  "currency": "NGN",
  "createdAt": "2026-06-26T09:14:22.118Z"
}

externalReference is your own id for the wallet: attach a user id from your system and look the wallet up by it later. The balance is not on this shape; you read it separately:

GET /wallets/:id/balance → WalletBalanceData
json
{
  "walletId": "acuinf472095183640wlt",
  "balance": 500000,
  "currency": "NGN"
}

balance is in kobo; 500000 is ₦5,000.00. It is the live sum of every credit and debit on the wallet, never a cached guess. There is no separate "available" vs "pending" balance, so the number is always exactly right.