eSIM
Provision and manage eSIM profiles through the gateway.
The eSIM product lets you browse a catalog of data plans, buy them, and manage the resulting eSIM profiles — installation instructions, live data usage, and top‑ups — through the same gateway you already use.
All eSIM endpoints are /v1/esim/* requests authenticated with your key id and secret — see Authentication. A key needs esim:read to read and esim:write to make changes; see Permissions.
Responses, pagination, errors and retry behaviour follow the shared Conventions, Errors and Idempotency rules — this page covers only what is specific to eSIM.
Every endpoint, with its full request and response schema, is in the eSIM API Reference.
A typical flow
Browse the catalog
Plans are returned at your selling prices. Browse them directly, or start from countries and regions:
await api('GET', '/v1/esim/plans', { query: { region: 'Global', currency: 'USD' } });
await api('GET', '/v1/esim/countries');Each plan's id (24‑hex) is the planId you buy with.
Buy a plan
await api('POST', '/v1/esim/purchases', {
body: { planId: '69f1fd87f32cd1cae4cb6099', email: 'user@example.com' },
});Funds are reserved and captured, and the call returns 202 with an orderId — delivery completes asynchronously. Send an Idempotency-Key header so a retry can't double‑charge.
Fetch the eSIM and its install instructions
Once the order is delivered, read the eSIMs attached to it:
await api('GET', `/v1/esim/orders/${orderId}/esims`);
await api('GET', `/v1/esim/orders/${orderId}/esims/${iccid}/instructions`);Instructions are localized — pass Accept-Language.
Track usage and top up
await api('GET', `/v1/esim/orders/${orderId}/esims/${iccid}/usage`);
await api('GET', `/v1/esim/esims/${iccid}/topups`);
await api('POST', `/v1/esim/esims/${iccid}/topup`, { body: { packageId } });Usage and top‑ups depend on the provider behind the plan; providers that don't support them return 501.
Refunds
Refunds are reviewed, not automatic. A client opens a request with POST /v1/esim/refund (with a required reason); an admin then approves or rejects it, and money moves only on approval.
Errors follow the standard gateway error format. The codes each endpoint can return are listed on that endpoint in the API Reference.
Order statuses
| Status | Meaning | What to do |
|---|---|---|
pending | Accepted, not yet being provisioned. | Poll. |
processing | Being provisioned. | Poll. |
delivered | Every eSIM is ready; installation details are on the order. | Install. |
partially_delivered | Some eSIMs were delivered, some failed. | Check the esims array. |
failed | Nothing was delivered. | You were not charged for undelivered items. Retry or contact support. |
refund_pending | A refund is under review. | Wait for the decision. |
refunded | The charge was returned. | Nothing. |
cancelled | A scheduled order was cancelled before it ran. | Nothing. |
requires_review | The order needs a human. | Contact support with the orderId. |
Refund request statuses
Separate from order statuses, because a refund request is a review record rather than a
state of the order: pending · approved · refunded · rejected · cancelled.
Refunds are reviewed, not automatic — opening a request does not move money.
When things go wrong
| You see | Meaning | Do |
|---|---|---|
400 VALIDATION_ERROR | A field is wrong; fields says which. | Fix it. |
409 PRODUCT_UNAVAILABLE | The plan cannot be sold right now. | Choose another, or retry later. |
409 INSUFFICIENT_BALANCE | Not enough balance. | Top up, then retry with the same idempotency key. |
409 CONFLICT | The order is not in a state that allows this — already cancelled, or not refundable. | Check actions on the order first. |
404 NOT_FOUND | No such order or eSIM — or not yours. | Check the id. |
actions.canRequestRefund already accounts for our eligibility rules, so read it rather
than guessing from the status.
Full schemas are in the eSIM API Reference.