NovaCodes

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 fieldTypeRequiredMeaning
qstringnoKeeps 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}}
]}
FieldTypeMeaning
codestringA country's two-letter ISO code (MV), or a word for a region or global (asia, global).
slugstringThe same destination as a readable word (maldives). The code and the slug both work in the next call.
namestringThe name to show.
kindstringcountry, region or global.
continentstring or nullThe continent of a country. null for a region and for global.
countriesintegerHow many countries the destination’s plans cover, at most. 1 for a country.
plan_countintegerHow many plans are on sale there.
price_fromobjectYour 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 fieldTypeRequiredMeaning
code or slugstringyesThe 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

FieldTypeMeaning
plan_idintegerWhat you send to order the plan.
namestringThe plan’s name.
destinationobjectThe destination it belongs to: {code, name}.
typestringfixed: an amount of data for a number of days. daily: an amount of data per day, for the number of days you order.
data_mbintegerThe data in MB. For a fixed plan, in total. For a daily plan, per day.
daysinteger or nullFixed plan: how many days it lasts. null for a daily plan.
min_days, max_daysinteger or nullDaily plan: the fewest and the most days you can order. null for a fixed plan.
priceobjectWhat you pay for one eSIM, per currency: {MVR, USD, USDT}. For a daily plan it is the price of price_days days.
retail_priceobjectThe public price on novacodes.app for the same thing, for reference.
price_daysinteger or nullDaily plan: the number of days that price and retail_price are for. null for a fixed plan.
speedstringThe network generations the plan uses, for example 3G/4G.
after_daily_limitstring or nullDaily plan: the speed for the rest of a day once that day's data is used, for example 128 Kbps.
validity_startsstringWhen 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_daysintegerHow many days after the purchase the eSIM can still be installed.
top_upbooleanWhether data can be added to an eSIM of this plan later.
phone_numberbooleanWhether the plan comes with a phone number for SMS. false: data only. Messaging apps and internet calls still work.
ip_countrystring or nullThe country the internet traffic comes out in. Websites see an address in that country.
countriesintegerHow many countries the plan covers.
coveragearrayOnly in GET /esim/plans/{plan_id}: the ISO codes of the countries covered.
networksarrayOnly 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.
FieldInTypeRequiredMeaning
plan_idpathintegeryesThe plan.
daysqueryintegernoDaily 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_days equals min_days. That is the price you see in a destination's plans.
  • With ?days=10, price is the price of one eSIM for 10 days and price_days is 10.
  • 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 days in 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.