The mental model
The single most important idea: a wallet belongs to the person, not the business that created it. A wallet is keyed by phone number and holds real, non-custodial USDC on Polygon. What each business keeps privately is its own USDC ledger — the balance it pre-funds with Rach and draws down when acting for its customers.Money-in is open
Anyone can fund a wallet or send to a phone number — even one that has never been
registered. The cost is always paid from the sender’s own ledger.
Money-out is gated
Only a member of a wallet may originate a transfer, withdraw to cash, or change its
phone number. Membership starts at provisioning and grows only with the customer’s consent.
Identity is portable
The address is derived from a permanent identity salt, not the phone number. Change the
SIM, keep the wallet, balance and history intact.
Reach
Rach meets customers on whatever channel they have — WhatsApp, SMS, USSD (where supported) and email. Every notification and self-service flow works the same whether the customer has a smartphone or a basic feature phone, so no one is left unable to claim or move their money.The flow, end to end
1
Pre-fund your ledger (once)
Top up your USDC ledger with Rach from your dashboard — request a locked rate, wire
the local currency, Rach confirms receipt and credits your spendable balance.
2
Provision the customer
Create their wallet by phone number (offline, gasless).
3
Fund the wallet
Move USDC/USDT from your ledger to the customer wallet on-chain.
4
Send or cash out
Send to any phone worldwide, or off-ramp back to local fiat.
Why the ledger and the wallet are separate: your ledger is keyed to your business and
the wallet is keyed to the person. Funding a customer who also uses another Rach partner
simply debits your balance and tops up the shared wallet — the other business is
unaffected.
Provision a user
Provisioning derives the smart-contract wallet address offline (no gas, no on-chain transaction) and records you as the wallet’s first member.Response
status tells you what you can do next:
Read balances
Response
Fund a customer (on-ramp)
Move stablecoins from your ledger to a customer wallet. Rach atomically debits your ledger before touching the chain — insufficient balance is refused cleanly with no on-chain effect — then settles as a gasless UserOperation.Send to any phone (or wallet)
Send USDC/USDT to any phone number in the world — instant and final on-chain within seconds. The recipient does not need to be your customer, or provisioned at all: if the phone has never been seen, Rach creates a wallet on the fly and notifies the recipient on their channel (WhatsApp / SMS / USSD / email) with how to claim and cash out — no app required.sender_phone and recipient_phone each accept either an E.164 phone number
(+2250700000001) or a 0x SCW wallet address — the format is auto-detected. Convert
fiat first with an FX quote if needed, and always pass an idempotency_key.
Money-in is open, money-out is gated. The sender must be a member of a wallet you
operate — knowing a phone number is never enough to move someone’s money (it’s rejected with
a clear permission error). The recipient can be anyone. If the recipient belongs to
another business, that business receives a
transfer.received webhook;
if they’re unregistered, Rach notifies them directly to claim.FX conversion
Quote fiat → stablecoin (locked for a short window) before you fund or send.Response
Cash out (off-ramp)
Two routes get money back to a local bank or mobile-money account. Business-initiated — you off-ramp your own customer:Swap USDC ⇄ USDT
GET /v1/swaps/{id} for status.
Multi-business wallets (consent)
A person can be a customer of several Rach partners at once — one wallet, one address everywhere. A second business gaining the right to act on that wallet requires the customer’s explicit consent. Provisioning a phone that already belongs to another business returns the address withLINK_REQUIRED and no operating rights; run the consent flow:
1
Request to link
POST /v1/users/link/request — Rach sends a one-time code to the customer by WhatsApp/SMS.2
Customer approves
The customer shares the code with you — possession of the phone is the consent.
3
Confirm the link
POST /v1/users/link/confirm with the code — you become a member (existing members get a
user.linked webhook).Changing a phone number
Because the phone number is the shared lookup key, changing it is consent-gated: a code is sent to the new number (proving SIM control), and the address, balance and history are preserved.1
Request the change
POST /v1/users/phone-change/request (old + new number).2
Confirm with the code
POST /v1/users/phone-change/confirm — the lookup key is re-pointed.user.phone_changed webhook so no one is left pointing at a stale key.
Status lifecycles
What you can build
The same primitives compose into very different products:Neobank / wallet app
Provision each customer, pre-fund your ledger, fund wallets on demand. Customers send to
each other and to anyone else instantly, in-app.
Cross-border remittance
Pay funds to any recipient by phone number; registered users are notified in-app,
unregistered ones cash out via USSD after an identity check.
Mobile-money operator
Bring wallets to feature phones — balance, send and cash-out over USSD / WhatsApp / SMS,
gaslessly.
Marketplace / gig payouts
Disburse to workers and sellers by phone number even before they’ve signed up — wallets
are created on the fly and the recipient is guided to their money.
Trust model
- Non-custodial wallets — funds sit in the customer’s own smart-contract wallet on Polygon, with per-transaction limits and timelocked recovery.
- Phone numbers are never stored in the clear — lookups use a keyed blind index; the address is derived from a permanent identity salt.
- Consent is cryptographic possession — gaining rights or re-keying a phone always requires a one-time code delivered to that phone.
- Money-out is member-only and compliance runs before any payout.
- Signed webhooks — every event is HMAC-signed (
X-Rach-Signature) so you can trust its origin.
Sandbox vs live
The key prefix decides the environment: arach_sk_test_ key runs in sandbox — every
B2B call returns an immediate SANDBOX_SIMULATED success without touching the blockchain,
moving your ledger, or changing the shared registry. A rach_sk_live_ key executes for real
on Polygon mainnet.

