Setup and installation instructions
Retrieve the QR code, the APN and the installation instructions for a booking or an ICCID.
Two endpoints return what a traveler needs to install an eSIM: the setup data of an order (the QR code, the activation data and the installation steps, with the prices of the booking) and the installation steps of an ICCID in the language of your choice. Both contain the activation data of the eSIM: show it only to the traveler who owns the eSIM.
Setup instructions by booking
GET /
Permission: Read
Returns the original order of an eSIM booking as JSON: the QR code and the activation data, the APN settings, the steps to install by QR code or by hand (as HTML), and the agency-facing prices. Use it to build your own confirmation or setup page.
booking_id is the reference of an order: the booking_id of the order response or of the
bookings list (FX- followed by a number).
- A topup booking has no setup data:
404with the message "Setup data not available for this booking". - A booking that does not exist and a booking of another agency are answered the same way:
404 booking_not_found. - A reference that is not valid (more than 100 characters, or characters other than letters, digits and
._:=+~-) is refused with400 invalid_booking_id.
curl --request GET \
--url https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/setup-instructions \
--header 'Authorization: Bearer fxp_test_YOUR_KEY'const response = await fetch("https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/setup-instructions", {
headers: { Authorization: "Bearer fxp_test_YOUR_KEY" },
});
const { data: order } = await response.json();
const sim = order.sims[0]; // sim.qrcode_url, sim.sharing.link, sim.direct_apple_installation_url ...Response example
A sandbox order (the HTML and the QR link shortened with ...):
{
"environment": "sandbox",
"success": true,
"data": {
"code": "20261101-106852",
"order_id": "20261101-106852",
"currency": "DZD",
"package_id": "france-in-7days-1gb",
"quantity": 1,
"type": "sim",
"description": "Order for John Smith",
"esim_type": "local",
"validity": 7,
"package": "KPN France Data only-1 GB - 7 days",
"data": "1 GB",
"price": 468.84,
"created_at": "2026-11-01 15:23:22",
"manual_installation": "<p><b>eSIM name:</b> ...</p><ol><li>Settings > Cellular/Mobile > Add Cellular/Mobile Plan.</li>...</ol>",
"qrcode_installation": "<p><b>eSIM name:</b> ...</p>...",
"installation_guides": { "en": "https://www.airalo.com/help/getting-started-with-airalo" },
"text": null,
"voice": null,
"sims": [
{
"created_at": "2026-11-01 15:23:22",
"iccid": "8900000540463077957",
"lpa": "lpa.airalo.com",
"imsis": null,
"qrcode": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"qrcode_url": "https://sandbox.airalo.com/qr?expires=1879860202&id=473564&signature=...",
"apn_type": "automatic",
"apn_value": "N/A",
"is_roaming": true,
"confirmation_code": null,
"apn": {
"ios": { "apn_type": "automatic", "apn_value": "N/A" },
"android": { "apn_type": "automatic", "apn_value": "N/A" }
},
"msisdn": null,
"direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"direct_android_installation_url": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"sharing": { "access_code": 8803, "link": "https://esims.cloud/v8hy7-usgkq6wg" }
}
],
"total_price": 468.84,
"retail_price": 468.84,
"agency_currency": "DZD"
}
}| Field | Meaning |
|---|---|
code | The supplier's order code. order_id carries the same value |
price, total_price, retail_price | What the traveler pays, in your agency currency (currency and agency_currency). The three fields have the same value. price here is the retail price, see eSIM pricing |
package_id, package, data, validity, esim_type | The package that was ordered: id, name, allowance, validity in days and kind |
quantity | Always 1 |
manual_installation, qrcode_installation | HTML with the steps to install by entering the activation data, and by scanning the QR code. Show it as HTML, or strip the tags |
installation_guides | Links to the supplier's general guide, by language |
sims[] | The eSIM of the order: iccid, the activation data (lpa, qrcode, qrcode_url), the install links (direct_apple_installation_url, direct_android_installation_url), the APN settings (apn_type, apn_value, apn per platform) and sharing, a page where the traveler can open the eSIM (link and access_code). Keys without a value are null |
created_at | When the supplier created the order: YYYY-MM-DD HH:MM:SS, UTC, without a zone |
Installation instructions by ICCID
GET /
Permission: Read
Structured, step-by-step installation instructions for one ICCID, per operating system, in the language of the
locale parameter. The ICCID is 18 to 22 digits (it may be written in groups of spaces or hyphens, 8944 4654 0000 0123 456)
and must belong to an eSIM your agency ordered in this
environment; any other ICCID is answered 404 iccid_not_found.
curl --request GET \
--url 'https://api.fx-port.com/api/v1/esims/instructions/8900000540463077957?locale=en' \
--header 'Authorization: Bearer fxp_test_YOUR_KEY'| Query parameter | Description |
|---|---|
locale | Language of the steps: en, fr, ar, de, es, it, ja, ko, pl, pt, ro, ru, sq, tr, vi or zh. Any spelling of a locale is read and only its language counts (fr-CA, zh-Hans, pt_BR, fr_FR.UTF-8, or a whole Accept-Language value such as fr-FR,fr;q=0.9: the first language is used). Another well-formed language is answered in English with a coerced_value warning; a value that is not a locale is refused with 400 invalid_locale. Falls back to Accept-Language, then en |
Response example
Steps shortened to the first ones:
{
"environment": "sandbox",
"success": true,
"data": {
"data": {
"instructions": {
"language": "EN",
"ios": [
{
"model": null,
"version": "15.0,14.0,13.0,12.0",
"direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"installation_via_qr_code": {
"steps": {
"1": "Go to “Settings”, tap “Cellular/Mobile Data”, then tap “Add Cellular/Data Plan” on your device.",
"2": "Scan the QR code available on the app, then tap “Add Cellular/Data Plan”.",
"3": "Choose a label for your new eSIM plan."
},
"qr_code_data": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"qr_code_url": "https://sandbox.airalo.com/qr?expires=1879860202&id=473564&signature=..."
},
"installation_manual": {
"steps": { "1": "Go to “Settings”, tap “Cellular/Mobile Data”, ...", "2": "Tap “Enter Details Manually” ..." },
"smdp_address_and_activation_code": "LPA:1$lpa.airalo.com$DUMMY-2610301358-iKFxr-44741",
"smdp_address": "lpa.airalo.com",
"activation_code": "DUMMY-2610301358-iKFxr-44741"
},
"network_setup": {
"steps": { "1": "Go to “Cellular/Mobile Data”, then select the recently downloaded eSIM ...", "2": "..." },
"apn_type": "automatic",
"apn_value": "N/A",
"is_roaming": true
}
}
],
"android": [ { "...": "same shape, with direct_android_installation_url and the steps of Android phones" } ]
}
},
"meta": { "message": "success" }
}
}The steps are in data.data.instructions, one entry per family of devices in ios and android.
model and version say which devices an entry is written for (null means all). steps is an object whose keys are the
step numbers "1", "2", ...
Sending instructions directly to the traveler
You do not have to relay the QR code yourself: the email of an eSIM order is passed to
the supplier, who emails the QR code and a sharing link to that address as soon as the eSIM is created. This is the
recommended flow whenever you have the traveler's own email. Use the endpoints on this page when you need to
render the QR code or the instructions inside your own product. On a topup the email is only
kept on the booking: nothing is emailed.
Deprecated: the setup link
GET / is deprecated: use
setup instructions instead. It still answers, with the install links of the
order only (no supplier data), and the response carries a deprecated_endpoint warning:
{
"success": true,
"fullUrl": "https://esims.cloud/v8hy7-usgkq6wg",
"setup_url": "https://esims.cloud/v8hy7-usgkq6wg",
"links": {
"sharing_link": "https://esims.cloud/v8hy7-usgkq6wg",
"direct_apple_installation_url": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$...",
"direct_android_installation_url": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$...",
"qrcode_url": "https://sandbox.airalo.com/qr?..."
}
}fullUrl and setup_url are the first link that exists (the sharing link, else the Apple or Android link, else the QR
image). links lists the links the order has. An order without any link is answered 404 setup_link_not_available.
Errors
| HTTP | code | Cause |
|---|---|---|
400 | invalid_booking_id | The booking reference is not valid |
400 | invalid_iccid, invalid_locale | The ICCID or the locale is not valid |
401 | authentication_required, invalid_api_key | Missing or invalid API key |
404 | booking_not_found | No eSIM booking of your agency has this reference |
404 | not_found | The booking is a topup, which has no setup data |
404 | iccid_not_found | The ICCID is not an eSIM of your agency in this environment |
429 | rate_limit_exceeded | Over 6,000 requests per minute for this key |
503 | service_unavailable, service_busy | The supplier connection or the service is busy (instructions by ICCID). Retry in a few seconds |
When the supplier cannot give the instructions, the answer carries the supplier's own status.