Developers

Mola API

Everything the dashboard does, over REST: fund your account, watch the balance, and deliver meticais to M‑Pesa — from your own backend. Money moves exactly as in the app: deposits credit 1:1, the FX rate locks when a transfer is created, and delivery is proven by the M‑Pesa code.

Base URL https://sendmola.com/api/v1 · create keys at Account → API keys

Authentication

Send your key in the Authorization header on every request. Keys grant full account access — keep them server-side.

curl https://sendmola.com/api/v1/balance \
  -H "Authorization: Bearer mola_YOUR_KEY"

Errors always share one shape: { "error": { "code": "...", "message": "..." } }

Endpoints

GET/balance

Your current USD balance (sum of the ledger).

{ "balance_usd": "250.00", "balance_usd_cents": 25000 }
GET/deposit-addresses

Your permanent deposit addresses, one per network, with the tokens each accepts. Fund the account by sending USDC/USDT to them — that's the whole funding flow.

{
  "addresses": [
    { "chain": "ethereum", "network": "Ethereum", "address": "0x…", "tokens": ["USDC", "USDT"] },
    { "chain": "tron",     "network": "Tron",     "address": "T…",  "tokens": ["USDT"] },
    { "chain": "solana",   "network": "Solana",   "address": "…",   "tokens": ["USDC", "USDT"] }
  ]
}
POST/deposits

Trigger a scan of your addresses on every network and credit anything new. Rate-limited to one call per 15 seconds; new funds appear in balance_usd in the response.

{ "new_deposits": 1, "credited_usd_cents": 25000, "balance_usd": "250.00", … }
GET/deposits

Your deposit history (last 100), with transaction hashes.

GET/rate

The live rate. offered_rate equals fx_rate — we pass on the mid-market rate with no markup and charge no fee.

{ "fx_rate": "63.850000", "offered_rate": "63.850000",
  "min_transfer_usd_cents": 10000, "currency": "MZN", … }
POST/transfers

Create a transfer. Debits the balance and locks the rate immediately; returns 201 with the transfer, or 402 with code insufficient_funds. Always pass an Idempotency-Key header — a retried request with the same key returns the original transfer (200) instead of paying twice. Optional source_chain (ethereum · tron · solana, default ethereum) names the deposit wallet this transfer settles from — only that network is touched.

curl -X POST https://sendmola.com/api/v1/transfers \
  -H "Authorization: Bearer mola_YOUR_KEY" \
  -H "Idempotency-Key: order-8412" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usd": "150.00",
    "recipient_first_name": "Ana",
    "recipient_last_name": "Machava",
    "recipient_phone": "+258841234567",
    "source_chain": "ethereum"
  }'
{
  "transfer": {
    "id": "6b6b…", "status": "pending",
    "amount_usd": "150.00", "amount_mzn": "9577.50",
    "fx_rate": "63.850000", "source_chain": "ethereum",
    "recipient": { "first_name": "Ana", "last_name": "Machava", "phone": "+258841234567" },
    "mpesa_code": null, "created_at": "2026-08-09T12:00:00.000Z"
  },
  "idempotent_replay": false
}
GET/transfers

Your transfer history (last 100).

GET/transfers/:id

One transfer. Poll it after creation: when status becomes completed, mpesa_code carries Vodacom's confirmation code — the proof of delivery.

A complete integration, in short

  1. Fetch /deposit-addresses once; fund with USDC/USDT.
  2. After funding, POST /deposits and read the new balance.
  3. POST /transfers with an Idempotency-Key.
  4. Poll GET /transfers/:id until completed — store the mpesa_code.

Questions or higher-volume needs? support@sendmola.com