Skip to content

List catalogs with packages

GET/v1/catalog/catalogscatalog:read

Returns catalogs with their packages nested inside each catalog. Use this endpoint to build a storefront grouped by destination: Turkey, Europe, Global. Every package includes your account price, selling price and network details.

Only active catalogs with matching, active, priced eSIM packages are included. Packages removed by their provider are excluded. Top-ups are listed separately with List top-ups for an existing eSIM.

Name Type Default Notes
country string — Case-insensitive ISO alpha-2, e.g. TR. Includes only packages covering that country; catalogs without matches are omitted
coverage enum — local, regional or global. Filters catalog types; regional also includes combine and custom
catalog string — Exact catalog id. An unavailable or unknown catalog returns an empty list
limit integer 50 Number of catalogs, from 1 to 200. Does not limit packages inside a catalog
cursor string — next_cursor from this endpoint’s previous page
Terminal window
curl 'https://partner-api.esimfo.com/v1/catalog/catalogs?limit=10' \
-H 'Authorization: Bearer esf_live_at_...'
Field Type Notes
data[].id string Catalog id; also accepted by the catalog filter in List packages
data[].name string Catalog display name
data[].slug string Catalog slug
data[].type enum local, regional, global, combine or custom
data[].packages array All matching eSIM packages in this catalog. Fields are the same as List packages
data[].packages[].id string Use as package_id when placing an order
data[].packages[].price string Your account’s purchase price
data[].packages[].selling_price string | null Your selling price; null when hidden for your account
next_cursor string | null Cursor for the next page of catalogs
has_more boolean Whether another page of catalogs exists
{
"data": [
{
"id": "cat_turkey",
"name": "Turkey",
"slug": "turkey",
"type": "local",
"packages": [
{
"id": "pkg_tr_3gb_30d",
"type": "esim",
"coverage": "local",
"name": "Turkey 3 GB — 30 days",
"service_type": "DATA",
"data_policy": "FIXED",
"has_number": false,
"data_amount_mb": 3072,
"validity_days": 30,
"countries": ["TR"],
"networks": [
{ "country": "TR", "name": "Turkcell", "types": ["4G", "5G"] }
],
"currency": "EUR",
"price": "4.20",
"selling_price": "6.30"
}
]
},
{
"id": "cat_europe",
"name": "Europe",
"slug": "europe",
"type": "regional",
"packages": [
{
"id": "pkg_eu_unl_15d",
"type": "esim",
"coverage": "regional",
"name": "Europe Unlimited — 15 days",
"service_type": "DATA_VOICE_SMS",
"data_policy": "UNLIMITED",
"has_number": true,
"data_amount_mb": null,
"validity_days": 15,
"countries": ["AT", "BE", "DE", "ES", "FR", "IT", "NL", "PT"],
"networks": [
{ "country": "DE", "name": "Telekom", "types": ["4G", "5G"] },
{ "country": "FR", "name": "Orange", "types": ["4G"] }
],
"currency": "EUR",
"price": "18.90",
"selling_price": "27.40"
}
]
}
],
"next_cursor": null,
"has_more": false
}

Pagination applies to catalogs. With limit=1, a response contains at most one catalog, but every matching package in that catalog is included. Follow next_cursor while has_more is true, keeping the same filters. Do not pass a cursor from List packages.

Catalogs follow the order set by our team, then name and id. Packages follow their order within the catalog, then package id. A package assigned to two catalogs appears under both with the same account price; deduplicate by package id if you need a unique inventory.

country=TR filters the nested packages, not just catalog names. Regional or global catalogs can appear when they contain packages covering Turkey. Each returned catalog includes all packages matching the request’s filters.

A catalog’s type describes its curated group. A package’s coverage describes its geographic reach; they can differ.

Use this endpoint for catalog → packages in one response. Use List packages for a flat list with package pagination, or List coverage for a lightweight destination summary with plan counts. The existing endpoints keep their response formats.

Large catalogs can produce large responses. Start with a small catalog limit and cache results per account; prices differ between partners.

Status Code Cause
401 unauthorized Access token is missing or invalid
403 insufficient_scope Key lacks catalog:read
422 validation_failed Invalid country, coverage, cursor or limit
429 rate_limited Over the per-minute allowance