eSIM orders
This page is about travel eSIMs. Selling gift cards instead? See Gift card orders.
Place an order, wait for it, read the install details, show the QR.
Place an order
| Field | Type | Required | Meaning |
|---|---|---|---|
| plan_id | integer | yes | The plan to buy, from the catalogue. One plan per order. |
| quantity | integer | yes | 1 to 30. Each unit is one eSIM, for one phone. |
| balance | string | yes | "MVR" or "USD": the balance to charge, at that currency's price. |
| reference | string | yes | Your own unique id for this purchase. Up to 64 characters: letters, digits and . _ : - |
| days | integer | daily plans | How many days to buy, from the plan's min_days to its max_days. Required for a daily plan, ignored for a fixed plan. |
curl -s https://api.novacodes.app/v1/esim/orders \
-H "Authorization: Bearer $NOVACODES_KEY" \
-H "Content-Type: application/json" \
-d '{"plan_id": 43, "quantity": 2, "balance": "MVR", "reference": "trip-8841"}'{"data": {
"number": "NC-22748", "reference": "trip-8841", "kind": "esim", "status": "completed",
"plan_id": 43, "plan": "1 GB · 7 days", "destination": "Maldives", "days": 7,
"quantity": 2, "delivered": 2, "processing": 0, "refunded_units": 0,
"currency": "MVR", "unit_price": 18000, "total": 36000, "refunded": 0, "charged": 36000,
"created_at": "2026-09-21T21:18:48+00:00",
"esims": [
{"iccid": "8985224628000101", "order": "NC-22748", "plan_id": 43, "destination": "Maldives",
"state": "ready", "data_total_mb": 1024, "data_used_mb": 0, "usage_at": null,
"expires_at": "2027-03-18T10:00:00+00:00", "installed_at": null, "top_up": true, "cancellable": true,
"install": {
"lpa": "LPA:1$rsp.test$MATCH-1",
"smdp_address": "rsp.test",
"activation_code": "MATCH-1",
"qr_svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" …>…</svg>",
"ios_install_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA%3A1%24rsp.test%24MATCH-1"
}},
{"iccid": "8985224628000102", "order": "NC-22748", "plan_id": 43, "destination": "Maldives",
"state": "ready", "data_total_mb": 1024, "data_used_mb": 0, "usage_at": null,
"expires_at": "2027-03-18T10:00:00+00:00", "installed_at": null, "top_up": true, "cancellable": true,
"install": {
"lpa": "LPA:1$rsp.test$MATCH-2",
"smdp_address": "rsp.test",
"activation_code": "MATCH-2",
"qr_svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" …>…</svg>",
"ios_install_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA%3A1%24rsp.test%24MATCH-2"
}}
]}}Amounts are in minor units, laari and cents: see Balances & amounts.
| Order field | Meaning |
|---|---|
| number, reference | Our order number and your reference. Either one reads the order later. |
| kind | esim: new eSIMs. topup: data added to an eSIM you already have (see Manage an eSIM). |
| status | See Order status below. |
| plan_id, plan, destination, days | What was bought: the plan, a short description of it, the destination’s name, and the days it lasts. |
| quantity | The eSIMs you ordered. |
| delivered, processing, refunded_units | How many of them are ready, still being prepared, and refunded. |
| currency, unit_price, total | The balance charged, the price of one eSIM and the price of the order. |
| refunded, charged | What came back to your balance, and what the order cost you in the end: total minus refunded. |
| esims | One entry per eSIM that is ready. See The install details below. |
Retrying safely
The reference makes an order safe to repeat. If the same reference arrives again, for any reason, you get the first order back with status 200: no second order, no second charge, and the same eSIMs.
409 reference_in_use.Order status
| Status | Meaning | What to do |
|---|---|---|
| completed | Every eSIM is ready. esims has them all. | Done. |
| processing | Paid, and some eSIMs are still being prepared. esims has the ones that are ready, if any. | Poll GET /esim/orders/{reference} every few seconds. |
| partial_refunded | Some eSIMs are ready (they are in esims). The purchase of the others was refused, and their price is back in the same balance. | Order the rest again with a new reference. |
| refunded | The purchase was refused. The full amount is back in your balance. | Try again later with a new reference. |
Waiting for a processing order
The supplier prepares an eSIM in a few seconds. The order call waits up to about 20 seconds; after that it answers processing and you poll. Give your HTTP client a timeout well above 20 seconds.
{"data": {
"number": "NC-22749", "reference": "trip-8842", "kind": "esim", "status": "processing",
"plan_id": 43, "plan": "1 GB · 7 days", "destination": "Maldives", "days": 7,
"quantity": 1, "delivered": 0, "processing": 1, "refunded_units": 0,
"currency": "MVR", "unit_price": 18000, "total": 18000, "refunded": 0, "charged": 18000,
"created_at": "2026-09-21T21:18:48+00:00",
"esims": []}}curl -s https://api.novacodes.app/v1/esim/orders/trip-8842 \ -H "Authorization: Bearer $NOVACODES_KEY"
Read the order every few seconds until status is no longer processing. The answer then has the same shape as a completed order.
When an order is refunded
An eSIM is refunded automatically only when its purchase was refused, so that nothing was bought. An eSIM that is paid and simply not ready yet is never refunded: the order stays processing until the eSIM is there. Do not treat a long processing as a failure, and do not order again under a new reference, or you buy twice.
{"data": {
"number": "NC-22750", "reference": "trip-8843", "kind": "esim", "status": "refunded",
"plan_id": 43, "plan": "1 GB · 7 days", "destination": "Maldives", "days": 7,
"quantity": 1, "delivered": 0, "processing": 0, "refunded_units": 1,
"currency": "MVR", "unit_price": 18000, "total": 18000, "refunded": 18000, "charged": 0,
"created_at": "2026-09-21T21:18:48+00:00",
"esims": []}}To give back an eSIM that was delivered, cancel it: see Manage an eSIM.
The install details
Each entry of esims is one eSIM. The fields about its state and data are explained in Manage an eSIM. install is what your customer needs:
| Field | Meaning |
|---|---|
| install.lpa | The full activation text: LPA:1$, the SM-DP+ address, $, the activation code. This is what a QR code for the eSIM contains. |
| install.smdp_address | The SM-DP+ address, for phones where the details are typed in by hand. |
| install.activation_code | The activation code, for the same screen. |
| install.qr_svg | The activation text as a QR code: a complete SVG document of 240 × 240, as a string. |
| install.ios_install_url | Apple’s install link for the same activation text. |
- These are raw details. There is no NovaCodes page or link in them: you present them under your own name.
installisnullwhen the eSIM iscancelledorrevoked.- One eSIM installs on one phone. Give each customer their own.
Showing the QR
Use qr_svg
qr_svg is SVG markup in a string. It starts at <svg, so you can put it straight into your HTML, or base64-encode it on your server and use it as an image source.
<!-- qr_svg put straight into your page --> <div class="esim-qr" style="width:240px;background:#fff"><svg xmlns="http://www.w3.org/2000/svg" …>…</svg></div> <!-- or, base64-encoded by your server, as an ordinary image --> <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0i…" width="240" height="240" alt="eSIM QR code">
Show the QR code at 200 pixels or more, dark on a white background, and do not crop its white border.
Or make your own QR from lpa
Encode the lpa string as the text of a QR code with any QR library. Use it exactly as it is, including LPA:1$. Do this when you need a PNG: most email clients do not show SVG images.
The iPhone link
A customer who reads your message on the iPhone itself cannot scan a QR code from its own screen. Offer ios_install_url as a link or button: it opens eSIM set-up directly. It needs iOS 17.4 or later.
<a href="https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA%3A1%24rsp.test%24MATCH-1">Install on this iPhone</a>
By hand
Every phone also has a screen to enter the details by hand. Show smdp_address and activation_code as text your customer can copy, for the case where neither the QR code nor the link works.
Read orders
404 not_found when it is not yours, does not exist, or is a gift-card order.| Query field | Type | Required | Meaning |
|---|---|---|---|
| page | integer | no | The page to read. 1 when left out. |
| per_page | integer | no | Orders per page, up to 100. 25 when left out. |
curl -s "https://api.novacodes.app/v1/esim/orders?page=1&per_page=25" \ -H "Authorization: Bearer $NOVACODES_KEY"
{"data": [
{"number": "NC-22750", "reference": "trip-8843", "kind": "esim", "status": "refunded",
"plan_id": 43, "plan": "1 GB · 7 days", "destination": "Maldives", "days": 7,
"quantity": 1, "delivered": 0, "processing": 0, "refunded_units": 1,
"currency": "MVR", "unit_price": 18000, "total": 18000, "refunded": 18000, "charged": 0,
"created_at": "2026-09-21T21:18:48+00:00"}
],
"meta": {"current_page": 1, "last_page": 1, "total": 3}}meta carries current_page, last_page and total. Gift-card orders are never in this list.