eSimfly Logo
DEVELOPER GUIDE · ARCHITECTURE TO PRODUCTION

eSIM API Integration Guide

Everything an engineering team needs to plan and ship an eSIM integration: the four building blocks every eSIM API shares, how signed authentication works, the sync-vs-webhook provisioning split, what to evaluate before picking a provider, and the pitfalls that only show up in production.

1. The four building blocks

Every eSIM API integration — whichever provider you choose — decomposes into the same four blocks. Scope your build against them:

Catalog

The packages you can sell, with your wholesale prices. Cache it — but refresh periodically, because carrier rates change. Filter by country to build destination pages.

Ordering & delivery

One authenticated POST turns a package code into a provisioned eSIM, debited from your account balance. The response carries the full install payload: QR code image, Apple one-tap universal link, and the raw LPA string.

Lifecycle

Usage queries ("80% used — top up?"), top-up packages and orders, status, suspend/cancel, and network events. This block turns a one-shot storefront into a product with retention.

Account & security

Signed requests, balance queries, webhook management, and rate limits. Boring until it isn't — most production incidents live here (see pitfalls below).

2. Authentication: signed requests, not bare keys

An eSIM order spends real money from your balance, so serious APIs sign every request instead of trusting a static key header. The eSIMfly scheme is HMAC-SHA256: four headers — access code, unique request ID, millisecond timestamp, and a signature over timestamp + requestId + accessCode + requestBody. Requests older than 5 minutes are rejected, which kills replay attacks.

const BASE_URL = 'https://esimfly.net';
const ACCESS_CODE = process.env.ESIMFLY_ACCESS_CODE; // esf_...
const SECRET_KEY = process.env.ESIMFLY_SECRET_KEY;   // sk_...

function hmacHeaders(requestBody = '') {
  const timestamp = Date.now().toString();
  const requestId = uuidv4();

  // signData = Timestamp + RequestID + AccessCode + RequestBody
  const signData = timestamp + requestId + ACCESS_CODE + requestBody;

  const signature = crypto
    .createHmac('sha256', SECRET_KEY)
    .update(signData)
    .digest('hex')
    .toUpperCase();

  return {
    'RT-AccessCode': ACCESS_CODE,
    'RT-RequestID': requestId,
    'RT-Timestamp': timestamp,
    'RT-Signature': signature,
    'Content-Type': 'application/json'
  };
}

Credentials come from Business Dashboard → Settings → API Keys. Keep the secret key server-side only — never ship it in a mobile app or browser bundle.

3. The integration path

The minimal happy path is two calls — catalog, then order. A prototype that sells a real eSIM and displays its QR code is a one-day build:

// The minimal happy path — two calls from catalog to installed eSIM

// 1. What can I sell, and at what wholesale price?
const catalog = await fetch(
  BASE_URL + '/api/v1/business/esims/packages?country=TR',
  { headers: hmacHeaders() }
).then(r => r.json());

// 2. Buy one — returns the full installation payload
const order = await fetch(BASE_URL + '/api/v1/business/esims/order', {
  method: 'POST',
  headers: hmacHeaders(body),
  body // { packageCode, quantity: 1 }
}).then(r => r.json());

// order.data: { orderReference, iccid, qrCodeUrl,
//   lpaString, appleInstallUrl, newBalance, ... }

The important architectural decision is sync vs async provisioning. Most eSIMfly providers provision synchronously — the order response already contains the eSIM. A minority (KDDI Japan, for example) return pending_details and deliver the eSIM via a signed webhook a few minutes later. Design your order flow as "show the eSIM if it's in the response, otherwise show a 'preparing' state and finish from the webhook" and both cases are covered.

For the full working build — catalog UI, ordering, QR delivery — follow the Node.js storefront tutorial (~30 min) and then top-ups, usage tracking & webhooks.

4. Choosing a provider: the evaluation checklist

Questions worth asking of any eSIM API vendor before you commit volume — with eSIMfly's answers for transparency:

Coverage — countries and networks

Not just how many countries, but which local networks per country and whether plans multi-network switch. eSIMfly: 200 countries, 450+ networks.

Share of synchronous provisioning

Every async carrier adds webhook complexity to your flow. eSIMfly: most providers synchronous; async ones (e.g. KDDI) delivered via signed webhook.

Delivery payload completeness

You want QR code + Apple universal link + raw LPA string in one response — anything less degrades your install UX. eSIMfly: all three.

Lifecycle endpoints

Usage query, top-up catalog per ICCID, suspend/cancel, network events. Without usage data you can't build top-up revenue.

Auth model & rate limits

Signed requests (HMAC) beat static keys for an API that spends money. eSIMfly: HMAC-SHA256, 1,000 req/hour, 5-minute timestamp window.

Docs with runnable code

If the docs don't include copy-paste examples in your language, integration time doubles. eSIMfly: Node.js, Python and PHP examples plus an interactive playground.

5. Production pitfalls (learn them here, not in prod)

Clock skew silently breaks auth

Signed timestamps older than 5 minutes are rejected. A server with a drifting clock produces intermittent 401s that look like random failures. Run NTP; alert on auth-failure rate.

Losing the install payload

Users delete emails and switch phones. Persist orderReference, ICCID, QR and LPA string on your side so you can re-deliver the eSIM later — re-ordering costs money, re-displaying is free.

Balance runs dry mid-flow

Orders debit your prepaid balance and fail cleanly when it's insufficient — which is still a failed customer checkout. Watch the newBalance field on every order and alert well before empty.

Treating the catalog as static

Wholesale prices move with carrier rates. A stale cached catalog means selling at yesterday's cost. Cache, but refresh on a schedule and before large campaigns.

Polling where a webhook belongs

Usage-polling every eSIM every minute burns your 1,000 req/hour budget fast at scale. Poll on user-open, schedule background checks sparsely, and let webhooks carry async events.

eSIM API integration FAQ

What does an eSIM API integration involve?

Four building blocks: a package catalog (what you can sell, with wholesale prices), an ordering endpoint (turns a package code into a provisioned eSIM), delivery UX (QR code, one-tap install links, and the raw LPA string), and lifecycle management (usage queries, top-ups, suspend/cancel, webhooks). A minimal storefront needs only the first three and can be built in a day; lifecycle features make it a real product.

How long does it take to integrate an eSIM API?

A working prototype — authenticate, pull the catalog, create an order, show the QR code — is typically a one-day build (the eSIMfly Node.js tutorial does it in ~30 minutes without an SDK). Production hardening (webhooks, balance monitoring, re-delivery of stored eSIMs, error handling) usually adds a few days.

How does eSIM API authentication usually work?

Serious eSIM APIs use signed requests rather than a bare API key. eSIMfly uses HMAC-SHA256: each request carries an access code, a unique request ID, a timestamp, and a signature computed over timestamp + request ID + access code + body with your secret key. Requests older than 5 minutes are rejected, which blocks replay attacks.

Do I need webhooks, or can I just poll?

Most eSIMfly providers provision synchronously — the order response already contains the QR code, so no webhook is needed for the core flow. Webhooks matter for the minority of carriers that provision asynchronously (KDDI Japan takes a few minutes) and for avoiding usage-polling loops at scale. Good rule: launch with the synchronous flow, add webhooks before you scale.

What should I compare when choosing an eSIM API provider?

Coverage (countries AND which local networks), wholesale pricing model and top-up support, what share of orders provision synchronously, delivery payload completeness (QR + Apple universal link + raw LPA), auth security, rate limits, usage/lifecycle endpoints, and whether documentation includes runnable examples. Test the sandbox with your real use case before committing volume.

How do I get access to the eSIMfly API?

Create an eSIMfly business account, then generate API credentials (access code + secret key) from Business Dashboard → Settings → API Keys. Coverage spans 200 countries across 450+ networks, with rate limits of 1,000 requests/hour. Wholesale tiers depend on volume — contact sales for rates.

Start integrating

Full endpoint reference, Python and PHP examples, and an interactive playground in the documentation — or start from the API overview and get your keys.