Stages 3 to 6 repeat per currency. KYC data is submitted once and reused, but activation is per-onboarding: adding a second currency to an existing user means calling
POST /kyc/activate again before that rail’s start-* endpoint.1. Create the user
Register the person with BMONI and keep the id you get back.Prerequisite
A partner API key, sent as
x-api-key on every request.You call
POST /v1/usersResult
A
bmoniUserId. Every user-scoped endpoint takes it as a path parameter.Watch out
Persist it. Creating a new user on each launch forks the wallet history.
2. Provision the smart wallet
The wallet comes before KYC. The user’s device generates the owner key, proves ownership by signing a challenge, and the proxy deploys the smart wallet against that owner address.Prerequisite
A
bmoniUserId, and bmoni_embedded_sdk initialised on-device.You call
POST /smart-wallets/owner-proof-challenges → sign with the SDK → POST /smart-wallets/create-managedResult
A
SmartWallet (address, chain, currency, status).Watch out
Smart-wallet calls take the stablecoin code, not the fiat one:
USDB, CNGN, CADC, EURe, GBPe, MEXe.3. Verify identity (KYC)
One submission, reused across every currency the user later adds. The submit order is fixed.Prerequisite
A
bmoniUserId. Check GET /onboarding/status first — the currency may already be active.You call
GET /kyc/options → document uploads → PATCH /kyc → GET /kyc/readiness → POST /kyc/activateResult
An activated KYC profile, ready for a rail.
Watch out
Requirements differ by region, and so does activation: USD, EUR, and Mexico need a biometric selfie and a
sumsubLevelName; Canada and Nigeria must omit it.4. Activate the rail
A wallet exists after stage 2, but it cannot receive or send until its local rail is switched on. That is one call per currency.Prerequisite
KYC activated, plus the smart wallet for that currency. USD additionally gates on
GET /kyc/usd-readiness.You call
POST /onboarding/start-usa, start-canada, start-monerium, start-nigeria, or for Mexico POST /latam/mx/kyc/activateResult
GET /onboarding/status reports the currency as active.Watch out
Nigeria needs a
bvn; Mexico needs the Etherfuse agreements signed (GET /latam/mx/kyc/launch/agreements) before its KYC can approve — the CLABE is provisioned automatically. The body carries currency-prefixed wallet fields.5. Fund the wallet
How money arrives depends on the rail you activated.Prerequisite
An active rail for that currency.
You call
GET /vba/usd, POST /vba/eu, POST /vba/ngn for virtual bank accounts; POST /deposit/wallet for a crypto top-up address; a SPEI transfer to the user’s MXN CLABE (GET /bank-accounts/deposit-accounts/MXN) onramps automatically; POST /latam/cash/orders/fund for cash pay-in.Result
A balance on
GET /smart-wallets/account/balances.Watch out
A USD virtual account is issued asynchronously. Poll
GET /vba/usd until status is active.6. Move money
Swap between currencies and send money out of the wallet.Prerequisite
A funded wallet.
You call
POST /exchange/convert to swap; offramp/nigeria, /latam/mx/orders, /eu/orders/prepare → sign → /eu/orders/complete, or /latam/cash/orders/send to pay out.Result
Funds swapped, or sent to a bank account or cash pickup.
Watch out
SEPA payouts are a three-call handshake: prepare, sign on-device, complete.
Closing the account
Deleting a user deactivates the account rather than erasing it, and it only succeeds once every wallet is empty. For 90 days the deletion can be undone with a single call; after that only support can restore it. See Deleting & reactivating an account.Where to go next
Start from a goal
Pick what you are building and see which of the six stages it needs.
Full call order
Every endpoint, in sequence, with request bodies and gotchas.
No app of your own?
Invite users into the BMONI app and read their accounts over the API.
Build the client
Wire the Flutter packages: wallet, PIN, and first signature.

