Cypher eSIM for AI agents
AI assistants can buy a Cypher eSIM on your behalf. Connect our MCP server, ask for "an eSIM for Japan, 10 GB", and the agent finds the plan, creates a crypto invoice, and hands you the QR code after payment.
No API key, no account, no name, email or phone. The agent goes through the same checkout as a person on the site: same plans, same prices in USD, same 8 coins.
MCP server
- Endpoint: https://cypheresim.com/mcp
- Transport: Streamable HTTP (stateless, JSON responses). No authentication.
- Works with Claude Desktop, Claude Code, Cursor, MCP Inspector and any client that speaks the Model Context Protocol.
Claude Desktop
Settings → Connectors → Add custom connector, and paste the endpoint URL. Or, for older versions, add this to claude_desktop_config.json:
{
"mcpServers": {
"cypher-esim": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://cypheresim.com/mcp"]
}
}
}
Cursor
Add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"cypher-esim": {
"url": "https://cypheresim.com/mcp"
}
}
}
Claude Code
claude mcp add --transport http cypher-esim https://cypheresim.com/mcp
MCP Inspector
npx @modelcontextprotocol/inspector --cli https://cypheresim.com/mcp --transport http --method tools/list
Tools
- search_destinations(query): find a country, region or "world" and its destination code.
- list_plans(destination, type): plans for a destination, cheapest first. type is "data" (data only) or "number" (with a phone number, calls and SMS).
- get_plan(plan_id): full plan details, covered countries, install rules and notes.
- list_payment_coins(): accepted coins and networks.
- create_order(plan_id, coin, network): crypto invoice with the exact amount, address and expiry. Returns order_id and a secret order_token.
- get_order(order_id, order_token): status, and after payment the QR code, LPA activation code, ICCID and one-tap iOS/Android install links.
- cancel_order(order_id, order_token): cancel an unpaid invoice.
- list_topups(iccid) and create_topup(iccid, plan_id, coin, network): add data to an eSIM you already have.
What the agent must tell you before payment
- Data plans: validity starts on first connection at the destination, so you can install before the trip.
- Plans with a phone number: validity starts when the eSIM is installed. Europe plans give a French +33 number.
- The UK plan with a number must be installed only after you land in the UK. Installing it earlier blocks the eSIM.
- Send the exact amount on the exact network shown in the invoice, before it expires. The exact amount is how the payment is matched to the order.
REST API
Base URL: https://cypheresim.com/api/public/v1. JSON, no key, CORS open. The MCP tools call the same functions.
- GET /destinations?q=japan
- GET /plans?destination=JP&type=data (or type=number)
- GET /plans/{plan_id}
- GET /coins
- POST /orders {"plan_id", "coin", "network", "ref"?}
- GET /orders/{order_id}?token={order_token}
- POST /orders/{order_id}/cancel?token={order_token}
- GET /topups?iccid={iccid}
- POST /topups {"iccid", "plan_id", "coin", "network"}
Example
curl "https://cypheresim.com/api/public/v1/plans?destination=ES&type=number"
curl -X POST https://cypheresim.com/api/public/v1/orders \
-H "Content-Type: application/json" \
-d '{"plan_id":"<plan_id>","coin":"USDT","network":"tron"}'
curl "https://cypheresim.com/api/public/v1/orders/<order_id>?token=<order_token>"
For resellers
Resellers get an API key. Send it in the X-API-Key header on any REST request or on /mcp. An unknown or revoked key returns 401 invalid_api_key.
With a key, price_usd in GET /plans, /plans/{plan_id} and /destinations is your wholesale price. retail_price_usd shows the retail price for comparison.
To get a key, write to us in Telegram: @cypheresim_bot.
Orders
- POST /orders {"plan_id", "coin", "network"?, "quantity"?, "client_ref"?}: quantity from 1 to 50 (plans with a phone number: 1). One invoice covers the whole quantity. Without a key, quantity above 1 returns 400 quantity_requires_key.
- The response adds quantity, unit_price_usd and retail_price_usd (per eSIM) and client_ref: your own reference, up to 64 characters, returned in every response and webhook.
- GET /orders/{order_id} with your key needs no order_token. GET /orders?status=&limit= lists your orders (limit up to 100).
- When the order is delivered, esims[] holds one entry per eSIM: iccid, lpa, qr_png_url, ios_install_url, android_install_url. qr_png_url opens with your key.
- White label: if it is on for your account, order_url leads to an install page without our brand (/i/{order_id}?brand=none).
curl -X POST https://cypheresim.com/api/public/v1/orders \
-H "X-API-Key: rs_live_…" \
-H "Content-Type: application/json" \
-d '{"plan_id":"<plan_id>","coin":"USDT","network":"tron","quantity":10,"client_ref":"batch-42"}'
curl -H "X-API-Key: rs_live_…" \
"https://cypheresim.com/api/public/v1/orders?status=delivered&limit=20"
Limits
Each key has two limits, agreed when we issue it: unpaid orders at the same time, and orders per 24 hours. Over a limit the API returns HTTP 429 with too_many_pending or daily_limit.
Webhooks
- We POST JSON to your webhook URL: {"id": "evt_…", "type", "created_at", "data"}. type is order.paid, order.delivered or order.failed; data is the same object as GET /orders/{order_id}.
- Headers: X-Cypher-Event (the type), X-Cypher-Delivery (the event id), X-Cypher-Timestamp (unix seconds) and X-Cypher-Signature: sha256= followed by the hex HMAC-SHA256 of "<timestamp>.<raw body>" with your webhook secret.
- Answer with any 2xx within 10 seconds. Otherwise we retry after 1 min, 5 min, 15 min, 1 h, 3 h, 6 h and 12 h (8 attempts in total). Use the event id to skip duplicates.
- order.failed means the payment did not match the invoice, or issuing did not succeed within 15 minutes. Support then issues the eSIMs or refunds, so order.delivered can still follow.
const crypto = require('crypto');
// rawBody: the request body exactly as received, before JSON.parse
function isFromCypher(rawBody, headers, secret) {
const ts = headers['x-cypher-timestamp'];
const header = headers['x-cypher-signature'] || '';
const sig = crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
const a = Buffer.from('sha256=' + sig);
const b = Buffer.from(header);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Limits and privacy
- Up to 5 unpaid invoices per client per hour. Pay one, cancel unused ones, or wait for them to expire.
- Order status: at most one request every 5 seconds per order. Faster polling gets HTTP 429 with Retry-After.
- General limit: 120 requests per minute per IP.
- order_token is the only key to the QR code. Without it the order returns "not found". Keep it private.
- We do not ask for or store a name, email or phone number. Partner codes go in the optional "ref" field.
Frequently asked questions
Do I need an API key?
No. The MCP server and the REST API are public. Limits are per IP, so normal personal use never hits them.
Can the agent pay by itself?
Only if it controls a crypto wallet. Usually the agent shows you the invoice (amount, coin, network, address) and you pay from your own wallet, then it fetches the QR code.
Are prices different for agents?
No. Agents see the same plans and the same USD prices as the site. The crypto amount is fixed when the invoice is created.
What if the eSIM is not delivered after payment?
Status "paid" means issuing is in progress. If it stays there, contact support in Telegram with the order id.