One URL. Zero integration.
The simplest way to get paid in crypto: link to MFW with the recipient and amount pre-filled. The user lands inside their MFW wallet on a confirm-and-send screen. They tap pay; money arrives in seconds. No API key, no SDK, no backend code.
Pay Link — works in any HTML, email, QR or button
Construct the URL with the recipient code, amount, and token. Drop it into a button, email, invoice, QR code, or social bio. Anyone with an MFW account can pay you instantly.
style="background:#22c55e;color:#000;padding:12px 24px;border-radius:10px;
font-weight:700;text-decoration:none">Pay 25 USDC with MFW</a>
Three ways to integrate
Start with the Pay Link above — it covers most use cases. Layer in the public read API for richer experiences. Use partner endpoints for deeper integrations once OAuth ships.
Read API
Resolve usernames, look up prices, read balances on 25+ chains, list supported chains, generate payment links — all without an API key. Server-side calls only.
Server-side Payment Links
Programmatically generate pre-filled payment links and QR codes from a logged-in user's account — for invoicing, checkout, and request flows.
Direct Send
Execute gasless transfers on a user's behalf. Requires the user's PIN per send today; OAuth flow lands soon to make this safe for third-party apps.
From zero to sending in 3 minutes
Drop in the Pay Link (no code, no auth)
One HTML link, one MFW code, one amount. That's the whole integration for most apps. Skip to step 2 only if you need richer UX.
Add the public read API (still no auth, server-side)
Resolve recipient names + avatars before showing the pay button. Look up token prices. Read on-chain balances on 25+ chains. All free, all server-side.
Register for an API key (when you need partner endpoints)
Takes 30 seconds. Key is shown once — save it securely. Required for /v1/partner/* endpoints (server-side payment links, transaction history).
// ── 1. THE PAY LINK — zero integration ────────────────────────────── // Just an HTML link. Anyone clicking lands inside their MFW wallet // on a pre-filled send screen. Tap, confirm, done. <a href="https://app.myfriendlywallet.io/?to=MFW-SARAH&amount=25&action=send"> Pay 25 USDC </a> // ── 2. PUBLIC READ API — no key, no auth, server-side ─────────────── const base = 'https://mfw-api.sebjornstad.workers.dev'; // Resolve a username → wallet addresses on every chain const { code, name, avatar, addresses } = await fetch(base + '/v1/resolve/MFW-SARAH').then(r => r.json()); // addresses.polygon.address, addresses.bitcoin.address, ... (~70 chains) // Get USD prices for any token (free oracle) const { prices } = await fetch(base + '/v1/prices').then(r => r.json()); // prices.ETH, prices.USDC, prices.SOL, ... (~100 tokens) // Read a wallet's balance on any of 25+ chains (CORS proxied) const bal = await fetch(base + '/v1/polygon/balance/0x742d...').then(r => r.json()); // ── 3. PARTNER API — needs your key + user bearer ─────────────────── // Generate a server-side payment link from a user's account const { pay_link, qr_code } = await fetch( base + '/v1/partner/request', { method: 'POST', headers: { 'X-MFW-Partner-Key': 'mfw_xxxxxxxxxxxx', // from /v1/developer/register 'Authorization': 'Bearer xxxxxxxxxxxx', // user's MFW session 'Content-Type': 'application/json', }, body: JSON.stringify({ to_code: 'MFW-CLIENT', amount: '500', token: 'USDC', invoice_number: 'INV-042', }), }).then(r => r.json());
Endpoints
The HTTP API only accepts cross-origin browser requests from myfriendlywallet.io, www.myfriendlywallet.io and app.myfriendlywallet.io. Third-party browser apps will be blocked by CORS — call from your server (Node, Python, Cloudflare Worker, edge function, etc.) instead. Server-side calls are unrestricted. The Pay Link below is the exception: it's a deep link to the MFW PWA, so it works from any HTML, anywhere.
Pay Link (deep URL)
MFW-SARAH.send (open the send screen), add (open the add-contact screen), or invoice_request (open the invoice flow). Default: shows a choice modal.25 or 25.50.USDC, USDT, EURC.mfw_abc12345) — NOT your full key. MFW looks up your registered partner_fee_bps + partner_fee_address and applies your fee on the send, on top of MFW's base fee. Cap: 200 bps (2%). Invalid prefixes silently degrade — the payer's send never fails because of partner-side issues. Auto-embedded in URLs returned by /v1/partner/request. See Fee Model for the full scope of what's supported today.https://app.myfriendlywallet.io/?to=MFW-SARAH&amount=25&action=send · https://app.myfriendlywallet.io/?to=MFW-SARAH&action=addUser lookup
MFW-SARAH. Case-insensitive. Do NOT include the @ prefix — invalid characters return 400.{ code, name, avatar, addresses } where addresses is a chain-keyed map: { polygon: {address, label}, bitcoin: {address, label}, solana: {...}, ethereum: {...}, base: {...}, ... ~70 chains }. Not every user has a wallet on every chain — check for the chain key before reading .address.400 invalid code format (must match MFW-[A-Z0-9]{3,20}) · 404 code not found · 403 user has not verified their email yet (anti-scam protection — these users cannot receive payments via the Pay Link either).exists flag. Drop the @ prefix or it silently returns {exists:false}.{ exists: true, code, display_name, avatar, pay_link }. Returns when missing: { exists: false }.Utility (chains, prices, balances) — public, server-side
[{ id, chainId, name, symbol, icon, color }, ...]. The id field is the same key used in /v1/resolve's addresses map./v1/verify.{ available: true|false, code }.{ prices: { ETH: 2422.07, BTC: 77253, USDC: 0.999913, ... } }. Free price oracle — no key, no signup.{ symbols: ["ETH","SOL","DOGE"] }. Returns the same shape as /v1/prices but filtered to your list./v1/prices. Use when you want an alternate path to the aggregated price data.{chain} = ethereum, polygon, base, solana, etc. {address} = the token contract address.Multi-chain balance proxy — public, server-side
{chain} values: ethereum, polygon, base, arbitrum, optimism, bsc, zksync, linea, scroll, opbnb, ronin, mantapacific, vechain, xrp, polkadot, stellar, decred, filecoin, near, tezos, hyperliquid, multiversx, sui, aptos, cardano.
Each chain returns a normalized
{ balance, decimals } shape. For Solana, see the dedicated section below.
• BCH — uses
/v1/bch/utxo/{address} (returns UTXOs, no scalar balance endpoint).
• Cosmos ecosystem — uses
/v1/cosmos/balance/{chainId}/{address}. Supported chainIds: cosmos, osmosis, injective, sei, celestia, dydx, akash, kava.
• Cardano UTXOs — in addition to the standard balance endpoint, UTXOs are at
/v1/cardano/utxos/{address}.
• Decred UTXOs — in addition to balance, UTXOs are at
/v1/decred/utxos/{address}.
Solana proxy — public, server-side
{ tx: "<base64-signed-tx>" }./v1/solana/account/{address}, /v1/solana/usdt-balance/{address}
Token discovery — public, server-side
{chain} values: ethereum, polygon, base, arbitrum, optimism, bsc, zksync, linea, scroll, opbnb, ronin, mantapacific (plus other EVM chains).
For multi-chain discovery across every EVM chain in one call, use
/v1/token-detect/portfolio/{address} below.
/v1/ton/tokens/{address}
System
{ status: "ok", version, websocket, embedded_wallet, push_notifications, ... }.Partner endpoints — your API key required
409.200 (2%) — higher returns 400.partner_fee_bps > 0 — otherwise returns 400.{ success: true, message, api_key, api_key_prefix, partner_fee_bps, docs }. The api_key is shown once — only its hash is stored server-side./v1/partner/request for third-party use.X-MFW-Partner-Key + Authorization: Bearer + body.pin
MFW-SARAH. Case-insensitive.{ success: true, tx_hash, amount_sent, token, mfw_fee, partner_fee, recipient_code, msg }.pay_link automatically embeds &partner=<your_key_prefix> so your configured partner fee (if any) is applied when the payer pays.{ pay_link, qr_code, from_code, to_code, amount, token }/v1/{chain}/balance/{address} endpoints documented above.{ user_code, evm_address, wallets: { polygon: "0x...", bitcoin: "bc1...", solana: "...", ... } }.Transparent, stacked fees
MFW takes its fee first, always. Your fee stacks on top. The recipient always receives exactly what's left. Everything is logged and auditable on-chain.
Partner fees are capped at 200 bps (2%) to protect users. Your fee address receives its cut atomically in the same transaction — no separate payout needed. Partner fees apply on any Pay Link that carries &partner=<your_key_prefix>, which is auto-embedded by /v1/partner/request or can be added manually to Pay Links you generate yourself.
Partner fees are applied on the gasless USDC/EURC send path (Base/Polygon) when the payer has an MFW embedded wallet. That's the path used by virtually all MFW users who sign up via the app — the default flow.
Your key can never move funds alone
The architecture is designed so that a compromised partner key is harmless without the user's active consent.
Two-factor API access
Every transactional endpoint requires both your partner key AND the user's valid session token. A stolen partner key alone cannot execute any send.
Keys never leave MFW
Private keys live in MFW's encrypted vault. You never touch them. You cannot drain a user's wallet even with full API access — user consent is always required.
Full audit log
Every API call is logged with developer ID, user ID, endpoint, and timestamp. MFW can revoke any partner key instantly if misuse is detected.
Fee cap protection
Partner fees are hard-capped at 2% in the worker code. You cannot overcharge users by misconfiguring your fee parameter — the cap is enforced server-side.
Build together, learn together
Join fellow developers building on MFW. Get help with widget integration, share what you've built, and help others solve real problems — from simple embeds to custom payment flows.
MFW Developer Community
Ask questions, share code snippets, show off what you've built, and help others — from a first widget embed to full custom payment flows. All skill levels welcome.
Register for an API key
Free for all developers. Your key is shown once — save it immediately.