Hopsim API — documentation
Sell eSIMs from your own systems: catalog with your prices, ordering, delivery and remaining data. All amounts are in USD and are charged to your prepaid balance.
Authentication
Get your key in My eSIMs → Business. Pass it in the header. A test key (hs_test_…) creates stub orders: no charges, fake eSIMs, same response format. A live key (hs_live_…) unlocks after your first top-up. You can restrict access by IP in the dashboard.
curl https://hopsim.co/api/partner/v1/balance \ -H "Authorization: Bearer hs_test_…"
Catalog and prices
All available plans at your wholesale price. Filter by destination: country ISO code (TR) or region (europe, global). The catalog updates daily — cache it and refresh once a day.
GET https://hopsim.co/api/partner/v1/catalog?destination=TR
{
"currency": "USD",
"plans": [
{
"id": "019c9954-5125-7209-a8f4-5cbdf017da17",
"destination": { "key": "TR", "type": "country", "name": "Turkey", "countries": ["TR"] },
"dataGb": 1, "unlimited": false, "dailyHighSpeedGb": null, "throttleKbps": null,
"days": 3, "validityStarts": "first_use", "topupAvailable": true,
"priceUsd": 1.33
}
]
}Order an eSIM
Charges priceUsd × quantity to your balance and issues the eSIMs. Usually the response is immediate with status ready and install data; if delivery is delayed you get 202 and status processing — poll GET /orders/{id} or wait for the webhook. externalId is your order number: repeating a request with the same externalId returns the same order instead of creating a new one. email — if set, we'll email the eSIM to your customer.
POST https://hopsim.co/api/partner/v1/orders
Content-Type: application/json
{ "planId": "019c9954-5125-7209-a8f4-5cbdf017da17", "quantity": 1,
"externalId": "your-order-1042", "email": "client@mail.com" }
200 OK
{
"id": "4uUCx29G3UQ8", "externalId": "your-order-1042", "status": "ready", "test": false,
"planId": "019c9954-…", "destination": "TR", "quantity": 1,
"unitPriceUsd": 1.33, "totalUsd": 1.33, "sentTo": "client@mail.com",
"esims": [{
"iccid": "8901…", "status": "ready",
"installUrl": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$…",
"lpa": "LPA:1$smdp.example$ACTIVATION-CODE",
"smdpAddress": "smdp.example", "activationCode": "ACTIVATION-CODE",
"dataTotalGb": 1, "dataLeftGb": null, "expiresAt": null
}]
}Order status
Add ?qr=1 to get the QR code as an image (data:image/png). installUrl is one-tap install on iPhone (iOS 17.4+); for Android use a QR from lpa or manual entry of smdpAddress and activationCode.
GET https://hopsim.co/api/partner/v1/orders/4uUCx29G3UQ8?qr=1
List orders
GET https://hopsim.co/api/partner/v1/orders?limit=20&before=4uUCx29G3UQ8
{ "orders": [ … ], "next": "Zx81…" }Balance
GET https://hopsim.co/api/partner/v1/balance
{ "mode": "live", "balanceUsd": 118.42, "liveEnabled": true }Webhooks
Set an https URL in the dashboard and we'll POST on order.fulfilled (eSIM issued, data is the full order) and balance.topped_up. The signature is an HMAC SHA-256 of the request body with your secret, in the X-Hopsim-Signature header. If your server doesn't answer 2xx we retry a few times with backoff.
POST https://your-site.com/hopsim-webhook
X-Hopsim-Event: order.fulfilled
X-Hopsim-Signature: sha256=5d41402abc4b2a76…
{ "event": "order.fulfilled", "createdAt": "2026-10-13T12:00:00Z", "data": { …order… } }
// Node.js — проверка подписи / signature check
const crypto = require("crypto");
const ok = req.headers["x-hopsim-signature"] ===
"sha256=" + crypto.createHmac("sha256", process.env.HOPSIM_WEBHOOK_SECRET).update(rawBody).digest("hex");Errors
401 unauthorized | Missing, revoked or invalid key |
403 ip_not_allowed | Request IP is not in your allowlist |
409 insufficient_balance | Not enough balance — top up in the dashboard |
409 plan_gone | The plan no longer exists — refresh the catalog |
400 invalid | Invalid request fields |
429 | Too many requests: catalog 30/min, orders 60/min |
409 Conflict
{ "error": "insufficient_balance" }Top up your balance in USDT (TRC20) in the dashboard, from $10. Refunds for eSIMs that couldn't be issued go back to your balance automatically.