eSIM destinations & plans
This page is about travel eSIMs. Selling gift cards instead? See Gift card products.
What is on sale, at your prices, and how a daily plan is priced.
The catalogue is two levels: destinations (a country, a region or global) and, under each, the plans you can order. Every price is your own price, in minor units (laari and cents): see Balances & amounts.
List destinations
GET/esim/destinations
Every destination on sale, by name.
| Query field | Type | Required | Meaning |
|---|---|---|---|
| q | string | no | Keeps the destinations whose name, or another name they are known by, contains the text, or whose code equals it. ?q=maldiv and ?q=mv both find the Maldives. |
Request
curl -s "https://api.novacodes.app/v1/esim/destinations" \ -H "Authorization: Bearer $NOVACODES_KEY"
Response (3 destinations shown)
{"data": [
{"code": "asia", "slug": "asia", "name": "Asia", "kind": "region", "continent": null,
"countries": 7, "plan_count": 15, "price_from": {"MVR": 5000, "USD": 249, "USDT": 242}},
{"code": "europe", "slug": "europe", "name": "Europe", "kind": "region", "continent": null,
"countries": 41, "plan_count": 15, "price_from": {"MVR": 4000, "USD": 199, "USDT": 193}},
{"code": "global", "slug": "global", "name": "Global", "kind": "global", "continent": null,
"countries": 127, "plan_count": 4, "price_from": {"MVR": 21000, "USD": 1049, "USDT": 1018}}
]}| Field | Type | Meaning |
|---|---|---|
| code | string | A country's two-letter ISO code (MV), or a word for a region or global (asia, global). |
| slug | string | The same destination as a readable word (maldives). The code and the slug both work in the next call. |
| name | string | The name to show. |
| kind | string | country, region or global. |
| continent | string or null | The continent of a country. null for a region and for global. |
| countries | integer | How many countries the destination’s plans cover, at most. 1 for a country. |
| plan_count | integer | How many plans are on sale there. |
| price_from | object | Your lowest price there, per currency: {MVR, USD, USDT}. A currency is null when nothing is priced in it. |
One destination and its plans
GET/esim/destinations/{code or slug}
The destination, plus
plans: every plan you can order there. 404 not_found when the destination is not on sale.| Path field | Type | Required | Meaning |
|---|---|---|---|
| code or slug | string | yes | The destination's code or its slug: MV or maldives. |
Request
curl -s https://api.novacodes.app/v1/esim/destinations/MV \ -H "Authorization: Bearer $NOVACODES_KEY"
Response (2 of the 6 plans shown)
{"data": {
"code": "MV", "slug": "maldives", "name": "Maldives", "kind": "country", "continent": "Asia",
"countries": 1, "plan_count": 6, "price_from": {"MVR": 16000, "USD": 799, "USDT": 775},
"plans": [
{"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": 44, "name": "Maldives 3GB 15Days", "destination": {"code": "MV", "name": "Maldives"},
"type": "fixed", "data_mb": 3072, "days": 15, "min_days": null, "max_days": null,
"price": {"MVR": 52000, "USD": 2599, "USDT": 2521}, "retail_price": {"MVR": 69000, "USD": 3449, "USDT": 3449}, "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 fields
| Field | Type | Meaning |
|---|---|---|
| plan_id | integer | What you send to order the plan. |
| name | string | The plan’s name. |
| destination | object | The destination it belongs to: {code, name}. |
| type | string | fixed: an amount of data for a number of days. daily: an amount of data per day, for the number of days you order. |
| data_mb | integer | The data in MB. For a fixed plan, in total. For a daily plan, per day. |
| days | integer or null | Fixed plan: how many days it lasts. null for a daily plan. |
| min_days, max_days | integer or null | Daily plan: the fewest and the most days you can order. null for a fixed plan. |
| price | object | What you pay for one eSIM, per currency: {MVR, USD, USDT}. For a daily plan it is the price of price_days days. |
| retail_price | object | The public price on novacodes.app for the same thing, for reference. |
| price_days | integer or null | Daily plan: the number of days that price and retail_price are for. null for a fixed plan. |
| speed | string | The network generations the plan uses, for example 3G/4G. |
| after_daily_limit | string or null | Daily plan: the speed for the rest of a day once that day's data is used, for example 128 Kbps. |
| validity_starts | string | When the days start to count. first_use: when the eSIM first connects at the destination. install: when it is installed on the phone. |
| install_within_days | integer | How many days after the purchase the eSIM can still be installed. |
| top_up | boolean | Whether data can be added to an eSIM of this plan later. |
| phone_number | boolean | Whether the plan comes with a phone number for SMS. false: data only. Messaging apps and internet calls still work. |
| ip_country | string or null | The country the internet traffic comes out in. Websites see an address in that country. |
| countries | integer | How many countries the plan covers. |
| coverage | array | Only in GET /esim/plans/{plan_id}: the ISO codes of the countries covered. |
| networks | array | Only in GET /esim/plans/{plan_id}: per country, the operators the eSIM connects to and their network type. |
One plan, and the price of a daily plan
GET/esim/plans/{plan_id}?days=N
One plan, with
coverage and networks. 404 invalid_plan when the plan is not in the API catalogue.| Field | In | Type | Required | Meaning |
|---|---|---|---|---|
| plan_id | path | integer | yes | The plan. |
| days | query | integer | no | Daily plans only. Prices the plan for exactly that many days, from min_days to max_days. On a fixed plan, or outside the range, the answer is 422 invalid_request. |
Request
curl -s "https://api.novacodes.app/v1/esim/plans/5?days=10" \ -H "Authorization: Bearer $NOVACODES_KEY"
Response (coverage and networks shortened)
{"data": {
"plan_id": 5, "name": "Asia (7 areas) 500MB/Day", "destination": {"code": "asia", "name": "Asia"},
"type": "daily", "data_mb": 500, "days": null, "min_days": 1, "max_days": 365,
"price": {"MVR": 22000, "USD": 1099, "USDT": 1066}, "retail_price": {"MVR": 29000, "USD": 1449, "USDT": 1449}, "price_days": 10,
"speed": "3G/4G/5G", "after_daily_limit": "128 Kbps", "validity_starts": "first_use", "install_within_days": 180,
"top_up": false, "phone_number": true, "ip_country": "HK", "countries": 7,
"coverage": ["TH", "SG", "VN"],
"networks": [
{"country": "KH", "operators": [{"name": "Metfone", "type": "4G"}]},
{"country": "ID", "operators": [{"name": "Telkomsel", "type": "5G"}]}
]}}- Without
days, a daily plan is priced for its shortest stay:price_daysequalsmin_days. That is the price you see in a destination'splans. - With
?days=10,priceis the price of one eSIM for 10 days andprice_daysis10. - Do not multiply a one-day price. Longer stays cost less per day, and that discount is already in
price. Ask for the price of the days your customer wants. - To order those days, send the same number as
daysin the order.
Plans and prices change. Read them shortly before you sell, rather than storing a copy for days. What an order really cost is always in the order:
unit_price and charged.