Skip to main content
Rach CaaS is a global money-movement rail. Give your customers non-custodial USDC / USDT wallets, then fund them from local currency, send to anyone in the world by phone number, and cash out back to local fiat — all over WhatsApp, SMS, USSD or email, so it works on a smartphone or a basic feature phone. It’s flexible: use the full fiat → stablecoin → fiat money-movement flow, or treat it as pure stablecoin infrastructure (non-custodial USDC/USDT wallets + on-chain transfers). Wallets are ERC-4337 smart-contract wallets on Polygon (Sepolia in test), keyed by phone number.
CaaS is a separate product with its own base URL and its own API key. Base URL https://api.rach.finance/caas/api/v1/; B2B keys are prefixed rach_sk_test_ / rach_sk_live_ and sent in X-API-Key. A Payments live_sk_/test_sk_ key will not work here. See Get your API keys.

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
The 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
Rates are per-currency (XOF, XAF, NGN, GHS, …) — USDC is the settlement rail underneath.

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:
Rach sweeps the USDC on-chain and disburses local currency to the mobile-money or bank destination. Self-service — someone who received money without belonging to any business cashes out through Rach directly over their channel, after a one-time identity check. No API call on your side.
Compliance gate. Receiving money never requires identity — anyone can be paid — but no payout leaves the system until Rach has screened the recipient against AML and sanctions checks.

Swap USDC ⇄ USDT

Poll GET /v1/swaps/{id} for status. 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 with LINK_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).
After linking, both businesses operate the same wallet independently — each still pays from its own ledger. The original business is never displaced; membership only grows.

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.
Every member receives a 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: a rach_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.
Build and test with rach_sk_test_ (Sepolia, simulated), then switch to rach_sk_live_ — same code, different key.

Keys & webhooks

Generate your CaaS API keys and configure webhook endpoints from your CaaS dashboard (see Get your API keys and Webhooks). Every B2B endpoint is in the CaaS API reference tab.