Manage an eSIM
This page is about travel eSIMs. Selling gift cards instead? See Gift card orders.
Status and data used, top-ups, and cancelling for a refund.
After delivery an eSIM is known by its iccid. With it you can read the eSIM's state and data used, add data to it, and cancel it for a refund while it was never installed. Amounts are in minor units, laari and cents: see Balances & amounts.
Status and data used
You read an eSIM by its ICCID. A key only sees eSIMs that were ordered through the API: one bought on the website, even by the same account, answers 404 not_found.
404 not_found when there is no eSIM with that ICCID on your account.| Path field | Type | Required | Meaning |
|---|---|---|---|
| iccid | string | yes | The eSIM's iccid from the order: 15 to 22 digits. |
curl -s https://api.novacodes.app/v1/esim/esims/8985224628000101 \ -H "Authorization: Bearer $NOVACODES_KEY"
{"data": {
"iccid": "8985224628000101", "order": "NC-22748", "plan_id": 43, "destination": "Maldives",
"state": "in_use", "data_total_mb": 1024, "data_used_mb": 256,
"usage_at": "2026-09-21T21:18:48+00:00",
"expires_at": "2027-03-18T10:00:00+00:00", "installed_at": "2026-09-21T21:18:48+00:00",
"top_up": true, "cancellable": false,
"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"
}}}| Field | Type | Meaning |
|---|---|---|
| iccid | string | The serial number of the eSIM. |
| order | string | The number of the order that bought it. |
| plan_id, destination | integer, string | The plan it was bought with, and the destination’s name. |
| state | string | ready, installed, in_use, depleted, expired, cancelled or revoked. Explained in The life of an eSIM. |
| data_total_mb | integer or null | The data on the eSIM, in MB, top-ups included. null while it is not known. |
| data_used_mb | integer or null | The data used so far, in MB. null while it is not known. |
| usage_at | string or null | When state and the data figures were last read from the network. null when they were never read. |
| expires_at | string or null | When the eSIM ends, as the network reports it now. The date can move: when the plan starts, and when data is added. |
| installed_at | string or null | When we first saw the eSIM installed. null while it is ready. |
| top_up | boolean | Whether data can be added to this eSIM. |
| cancellable | boolean | Whether a cancel can succeed as far as we know. The real check is made when you cancel: see Cancel for a refund. |
| install | object or null | The install details, as in the order. null when the eSIM is cancelled or revoked. |
Times are ISO 8601 with a time zone offset.
How fresh the figures are
- This call asks the network for the state and the data used, but at most once every five minutes per eSIM. In between, it answers with what it knew, and
usage_attells you how old that is. - So polling faster than every five minutes gains nothing. When you show usage to your customer, show
usage_atwith it. - The networks themselves report data use with a delay, which can be a few hours. Do not present
data_used_mbas live. - When the network does not answer, you still get a normal answer, with the last known figures and their
usage_at. - The eSIMs inside an order (
GET /esim/orders/…) show the last known state and never ask the network. Read the eSIM itself for a current one.
What can be added to an eSIM
curl -s https://api.novacodes.app/v1/esim/esims/8985224628000101/topups \ -H "Authorization: Bearer $NOVACODES_KEY"
{"data": [
{"plan_id": 43, "name": "Maldives 1GB 7Days", "destination": {"code": "MV", "name": "Maldives"},
"type": "fixed", "data_mb": 1024, "days": 7, "min_days": null, "max_days": null,
"price": {"MVR": 18000, "USD": 899, "USDT": 872}, "retail_price": {"MVR": 24000, "USD": 1199, "USDT": 1199}, "price_days": null,
"speed": "3G/4G", "after_daily_limit": null, "validity_starts": "first_use", "install_within_days": 180,
"top_up": true, "phone_number": true, "ip_country": "PL", "countries": 1},
{"plan_id": 45, "name": "Maldives 3GB 30Days", "destination": {"code": "MV", "name": "Maldives"},
"type": "fixed", "data_mb": 3072, "days": 30, "min_days": null, "max_days": null,
"price": {"MVR": 55000, "USD": 2749, "USDT": 2667}, "retail_price": {"MVR": 73000, "USD": 3649, "USDT": 3649}, "price_days": null,
"speed": "3G/4G", "after_daily_limit": null, "validity_starts": "first_use", "install_within_days": 180,
"top_up": true, "phone_number": true, "ip_country": "PL", "countries": 1}
]}- Each entry is a plan, with the same fields as in the catalogue.
- Only these plans can be added. Another plan, even one for the same destination, is refused.
- The list is empty when the eSIM's
top_upisfalse, and when the eSIM isexpired,cancelledorrevoked. AdepletedeSIM can still be topped up.
Add data (top up)
| Field | Type | Required | Meaning |
|---|---|---|---|
| plan_id | integer | yes | A plan from GET /esim/esims/{iccid}/topups. |
| balance | string | if the key has no default | "MVR", "USD" or "USDT": the balance to charge, at that currency's price. Left out, the key's default currency is charged (USD when none is set). |
| reference | string | yes | Your own unique id for this purchase, with the same rules as for an order. Use a new one: the reference of the order that bought the eSIM, or of a top-up of another eSIM, is refused with 409 reference_in_use. |
| days | integer | daily plans | How many days to add. Required when the plan is a daily plan, ignored otherwise. |
curl -s https://api.novacodes.app/v1/esim/esims/8985224628000101/topups \
-H "Authorization: Bearer $NOVACODES_KEY" \
-H "Content-Type: application/json" \
-d '{"plan_id": 45, "balance": "MVR", "reference": "trip-8841-more"}'{"data": {
"number": "NC-22751", "reference": "trip-8841-more", "kind": "topup", "status": "completed",
"plan_id": 45, "plan": "3 GB · 30 days", "destination": "Maldives", "days": 30,
"quantity": 1, "delivered": 1, "processing": 0, "refunded_units": 0,
"currency": "MVR", "unit_price": 55000, "total": 55000, "refunded": 0, "charged": 55000,
"created_at": "2026-09-21T21:18:48+00:00",
"iccid": "8985224628000101"}}- There is no
quantity: a top-up is always one plan added to one eSIM. - The answer is an order of
kindtopup. It carries theiccidit was added to, and noesims. - It is an order like any other: the same statuses, the same safe retry with the same reference, and you read it with
GET /esim/orders/{reference}. - Once an eSIM has been topped up, it can no longer be cancelled.
- Read the eSIM afterwards to see its new
data_total_mbandexpires_at.
{"error": {"code": "topup_not_allowed", "message": "That data cannot be added to this eSIM any more."}}Cancel for a refund
curl -s -X POST https://api.novacodes.app/v1/esim/esims/8985224628000102/cancel \ -H "Authorization: Bearer $NOVACODES_KEY"
{"data": {"iccid": "8985224628000102", "state": "cancelled", "refunded": 18000, "currency": "MVR"}}| Field | Meaning |
|---|---|
| iccid, state | The eSIM, now cancelled. It can no longer be installed, and its install is null from now on. |
| refunded, currency | The amount returned, in minor units, and the balance it went to: the one that paid for the eSIM. |
A cancel succeeds only when all of this is true:
- The eSIM was never installed: its state is
ready. We ask the network at the moment you cancel, so an eSIM your customer installed a minute ago is refused even if you last sawcancellable: true. - It was never topped up.
- It was not cancelled before. An eSIM is refunded once.
Otherwise the answer is 409 not_cancellable, nothing changes and nothing is refunded. The message says which rule applied. It also says so when the network could not be asked just now: that is the one case where trying again a minute later can help.
{"error": {"code": "not_cancellable", "message": "This eSIM has been installed, so it can no longer be cancelled."}}After a cancel, the order that bought the eSIM counts it in refunded_units and refunded, and its status becomes partial_refunded or refunded.