Real-world checkout for AI agents.
An AI agent cannot open a bank account, hold a card or file a chargeback. IoMarkets Topup is a merchant built for that buyer: it sells mobile airtime & data top-ups and travel eSIMs in 150+ countries, paid per order in USDC on Algorand through x402. No account, no API key, no card.
Money settles on-chain first, goods ship second, anything that fails is refunded on-chain automatically, and every order carries a signed receipt anyone can verify.
A shop where the customer is a program.
What it is
A merchant, not a payments API. Every order buys a real thing from a licensed supplier — an eSIM, phone credit, a prepaid bill, a bank or mobile-money payment — and delivers it to a phone number or account. The agent pays the exact quoted amount in USDC, per order, from its own wallet.
Live today: mobile airtime & data top-ups and travel eSIMs.
Why it exists
Human commerce runs on reversibility: chargebacks, disputes, small claims. An agent paying in stablecoins has none of that — it gets one shot and cannot read the terms. So the product is a settlement discipline that makes a stranger's promise checkable: settle first, deliver second, refund on-chain, sign every receipt, publish the ledger — including the number that makes us look worst.
Who it is for
Agent builders — OpenClaw, Hermes, Claude Code, Codex, any MCP client. Give the agent a wallet; it can buy.
Businesses paying people — paste a spreadsheet into the payout console, approve once, get a receipt for every row.
Anyone with an assistant — top up a relative's phone in Lagos, land in Tokyo with data already on.
Browse what an agent would buy, then watch the four calls.
The offers and prices below come from the real supplier catalogue on this server, right now. The purchase on the right is a simulation — nothing is signed and no USDC moves. To pay for real, use the console or the agent docs.
Loading the catalogue…
Four HTTP calls. No SDK, no signup.
Discover
Look up a phone number for its operator and offers, list eSIM destinations, or page the catalogue. All free.
Quote
Lock an exact USDC price for one purchase. Free, ten minutes, pays exactly once. If the float cannot fill it, you get a 503 now — not a refund later.
Pay with x402
The first POST answers 402 with the amount. The wallet signs an Algorand USDC transfer and retries. The order exists only after settlement.
Poll and keep the receipt
Delivered, or refunded on-chain to the paying address. Either way, an ed25519-signed receipt naming both transactions.
Point your agent at one file.
Works with OpenClaw, Hermes, Claude Code, Codex and any MCP client. Hosted MCP at /mcp, a shared skill in the repo, and a plain-HTTP flow that needs nothing installed. Need USDC on Algorand? How to fund an agent. No wallet at all? Create a pay link and your human pays from their own Pera wallet — and tag orders with ref to earn a share.
Read /agent.md Fund a wallet Public ledger JSON
Show the full agent instructions inline
# IoMarkets Topup — real-world checkout for AI agents (x402 on Algorand)
Buy real-world goods for your principal in 150+ countries.
No account, no API key, no card. Pay per order in USDC on Algorand (mainnet) using x402.
**Live right now: mobile airtime & data top-ups and travel eSIMs.** This list is what the wired suppliers can actually fulfil today, not a
roadmap — `GET https://iomarkets.app/v1/catalog?type=<type>` returns an empty list for anything not on it, and a quote
for one is refused rather than accepted and then failed. Other types may return later; re-read this file.
Base URL: https://iomarkets.app
## Flow (4 calls)
1. Discover
- GET https://iomarkets.app/v1/lookup?phone=%2B919876543210 → operator + top-up offers for that number
- GET https://iomarkets.app/v1/countries?type=esim → every destination this product reaches
(enumerable:false means the supplier will not list them, NOT that there are none)
- GET https://iomarkets.app/v1/catalog?type=topup&country=NG → offers (types live today: topup|esim)
Paged: &limit=100&offset=0 (limit=0 for everything). The response carries total and,
while there is more, next_offset. The eSIM catalogue is thousands of offers — ask for a
country, or a page.
- GET https://iomarkets.app/v1/fx?to=INR&amount=5000&type=payout → indicative USDC↔local rate + estimate (quote is binding)
2. Quote (free, locks the price for 10 minutes)
- POST https://iomarkets.app/v1/quote
{ "type": "topup", "offerId": "<offerId>", "recipient": { "phone": "+919876543210" }, "amount": 299 }
{ "type": "esim", "offerId": "<offerId>" }
{ "type": "payout", "offerId": "<offerId>", "amount": 50000, "recipient": { "fields": { "account_number": "…", "bank_code": "…", "full_name": "…" } },
"sender": { "name": "<principal's legal name>", "country": "GB", "reference": "<partner KYC id, required above $100/day>" }, "payer": "<your Algorand address>" }
→ { "quoteId": "q_…", "price_usdc": "3.900000", "delivers": "INR 299 · Jio …", "pay": { "endpoint": "…/v1/orders", "body": { "quoteId": "q_…" } } }
3. Pay (x402)
- POST https://iomarkets.app/v1/orders with JSON body { "quoteId": "q_…" }
First call returns 402 + PAYMENT-REQUIRED (exact USDC amount = the quote). Sign the Algorand USDC payment,
retry with the PAYMENT-SIGNATURE header. Response 202 → { "orderId": "ord_…", "status": "paid", "status_url": "…" }
4. Poll
- GET https://iomarkets.app/v1/orders/<orderId> every 3 s until "terminal": true
status: delivered (confirmation + signed receipt) | refunded (refund_txid + signed receipt) | refund_failed (contact support)
## Guarantees
- Money moves first, goods second: an order exists only after the facilitator settles your USDC payment on-chain.
- If the operator/supplier fails, the full amount is refunded to the paying address on-chain automatically.
- Every terminal order carries an ed25519-signed receipt over {order, amounts, payer, settlement txid, refund txid}.
Public key: c65e5bdaf5115c370f9ba76dcb4daaa310bb489c112126b4b2052d3cb103a0de — GET https://iomarkets.app/v1/pubkey.
- Check one yourself, free, without trusting us or installing anything:
- POST https://iomarkets.app/v1/verify with the receipt (or the whole order response) as the body
→ signature, whether the signer is this server, and both txids confirmed against an Algorand indexer.
Add ?online=0 to skip the chain lookup. It verifies receipts from ANY server that uses the format.
- Public ledger: GET https://iomarkets.app/v1/ledger (orders, delivered/refunded %, volume, by country).
## No wallet? Hand the human a pay link
- POST https://iomarkets.app/v1/links { "type": "esim", "offerId": "<offerId>", "note": "Data for your Tokyo trip" }
{ "type": "topup", "offerId": "<offerId>", "recipient": { "phone": "+234…" }, "amount": 1000 }
→ { "url": "https://iomarkets.app/l/pl_…", "indicative_price_usdc": "…", "share": { "x": "…" } }
The human opens the url, sees the exact price, and approves it in their own Pera wallet — the key never
leaves their wallet and you never hold one. An eSIM's activation QR appears on the page; a top-up link
can be paid by anyone (a "top up my phone" request) and credits only the number on the link.
Top-up links are single-use by default; eSIM links are reusable until expiry (max_uses, ttl_hours).
- GET https://iomarkets.app/v1/links/<linkId> → state: open | paid | expired
- POST https://iomarkets.app/v1/links/<linkId>/quote → a fresh quote for that link, payable over x402 like any other
## Earn: referral share, paid on-chain
- Add "ref": "<your Algorand address>" to POST /v1/quote or POST /v1/links.
- On every DELIVERED order you referred, you earn a share of our net margin (never of the price), sent to that
address in USDC on-chain, batched. Refunded orders and self-referrals earn nothing. The address must be
opted in to USDC. Terms and leaderboard: GET https://iomarkets.app/v1/referrals · your numbers: GET https://iomarkets.app/v1/referrals/<address>
- Humans: https://iomarkets.app/earn
## Proof of delivery, shareable
- Every goods order has a public page at https://iomarkets.app/p/<settlement_txid> (also `proof_url` on /v1/ledger rows):
what was bought, the price, the delivery time, the on-chain settlement and a server-checked receipt signature.
It never shows the order id — that id is the capability that reads the deliverable. Keep it private.
## Limits
- Goods: max per order $50. International payments: max per payment $200, verified sender (partner KYC reference)
required once a payer's payouts exceed $100 in a UTC day. Max per payer per UTC day $200 overall. Sanctioned destinations refused.
- International payments are executed by a licensed payout partner; we never hold or move fiat ourselves.
- Quotes expire after 10 minutes and can be paid exactly once.
## Errors
- 400 invalid input · 403 quote unusable / limit reached / destination not supported · 404 unknown · 429 slow down · 502/503 supplier problem (no charge)
# 1. discover GET https://iomarkets.app/v1/lookup?phone=%2B447700900123 GET https://iomarkets.app/v1/catalog?type=esim&country=JP # 2. quote (free, 10-minute lock) POST https://iomarkets.app/v1/quote { "type": "esim", "offerId": "ea-…" } → { "quoteId": "q_…", "price_usdc": "2.330000" } # 3. pay (x402) POST https://iomarkets.app/v1/orders { "quoteId": "q_…" } ← 402 PAYMENT-REQUIRED: exact USDC amount POST …/v1/orders + PAYMENT-SIGNATURE → 202 { "orderId": "ord_…", "status": "paid" } # 4. poll until terminal GET https://iomarkets.app/v1/orders/ord_… → { "status": "delivered", "receipt": { "sig": "…" } }
Pay a list of people from one wallet, with a receipt for each.
The batch payout console takes a pasted spreadsheet, validates every row, prices it, and settles each payment individually after a single approval from your own wallet — Pera or Defly. Failures refund themselves. Export the signed receipts as CSV for finance.
Walk through the demo Open the console Verify a receipt
International bank, mobile-money and UPI payouts are built and waiting on a licensed partner; the demo runs entirely in your browser with no wallet.
What the console does
| Step | What happens |
|---|---|
| 1 Recipients | Pick a corridor, paste or drop rows; each is validated inline. |
| 2 Review | Lock prices for ten minutes; see the batch total in USDC. |
| 3 Pay | Approve once. Rows settle one by one with a live tally. |
| 4 Receipts | Signed proof per row, on-chain txids, CSV export. |
Every order, in public.
| When | What | USDC | Status | Settlement | Proof |
|---|
Recipients are hashed. Volume is small and honest: the service went live on mainnet in late August 2026.
Every claim comes with a way to check it.
| Claim | How you check it |
|---|---|
| You were charged exactly the quoted amount | The 402 challenge carries the exact USDC amount; your wallet signs nothing else. |
| No order without a settled payment | Every order names its Algorand settlement txid — open it in the explorer. |
| Failed deliveries are refunded | The refund is an on-chain USDC transfer to the paying address, noted with the order id. |
| Receipts are not forgeable | ed25519 signature over the canonical payload; public key c65e5bdaf5115c370f9ba76dcb4daaa310bb489c112126b4b2052d3cb103a0de. Check one yourself — it works on receipts from any service using the format. |
| Nothing is hidden | /v1/ledger is public: every order, its outcome and its txids. Including stranded — orders we could neither deliver nor refund. We publish that number rather than making you ask. |
| Every delivery can be shown to anyone | Each goods order has a public proof page at /p/<settlement txid>: what was bought, the price, the delivery time, the on-chain payment and a checked signature. It never shows the order id, which is what unlocks the goods. Linked from every row of the ledger above. |
IoMarkets Topup is the agent-commerce product of IoMarkets®.
IoMarkets® is an AI-native financial technology ecosystem: integrated services across public and private capital markets, asset management, artificial intelligence, digital assets, digital money and financial news. This site is its payments-for-agents line — the place where an AI agent turns stablecoins into things in the physical world. Read more at iomarkets.org/about.