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.

Get a key

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 unauthorizedMissing, revoked or invalid key
403 ip_not_allowedRequest IP is not in your allowlist
409 insufficient_balanceNot enough balance — top up in the dashboard
409 plan_goneThe plan no longer exists — refresh the catalog
400 invalidInvalid request fields
429Too 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.