Skip to content
FX-Port/Docs
GuidesAPI referenceChangelog
Get API keys
  • Introduction
  • Quickstart
  • Security
  • Authentication
  • Environments and Postman
  • Sandbox
  • Conventions and naming
  • Legacy names and twins
  • Errors
  • Rate limits and fair use
  • Streaming search results

Concepts

  • Overview
  • Pricing
  • Supplier continuity

Catalog and orders

  • Package catalog
  • Create an order
  • Top up

After the order

  • Usage
  • Bookings
  • Setup instructions
  • Use these docs with AI

eSIMs · After the order

eSIM bookings

List the eSIM orders of your agency, read the topups of an eSIM and check that a booking is yours.

Three read-only endpoints cover the eSIM orders of your agency: the list of orders, the topups of one eSIM, and a check that a booking reference is yours. Orders and topups are stored as bookings of the same shape; the list shows orders only, and the topups of an eSIM are read with the topup history.

List bookings

GET /api/v1/esims/bookings

Permission: Read

A paginated list of the eSIM orders of your agency in this environment, newest first. A sandbox key lists sandbox orders and a live key lists live orders. Topups are not in this list: read them with the topup history of the eSIM, or in the account history, which lists orders and topups together. A failed attempt is listed too, with the status failed.

curl --request GET \
  --url 'https://api.fx-port.com/api/v1/esims/bookings?page=1&limit=50&[email protected]' \
  --header 'Authorization: Bearer fxp_test_YOUR_KEY'
const params = new URLSearchParams({ page: "1", limit: "50", search: "[email protected]" });
const response = await fetch(`https://api.fx-port.com/api/v1/esims/bookings?${params}`, {
  headers: { Authorization: "Bearer fxp_test_YOUR_KEY" },
});
const { data: bookings, pagination } = await response.json();
import requests

response = requests.get(
    "https://api.fx-port.com/api/v1/esims/bookings",
    params={"page": 1, "limit": 50, "search": "[email protected]"},
    headers={"Authorization": "Bearer fxp_test_YOUR_KEY"},
    timeout=30,
)
body = response.json()
Query parameterDescription
searchPart of a booking id, the traveler's first or last name, the email, the package name or the ICCID. It does not match the supplier order code or the phone number. At most 100 characters
pageThe page, starting at 1 (at most 10,000)
limitBookings per page, 1 to 200 (default 50). A larger value is refused with 422 validation_error
alltrue returns the largest pages: 200 bookings, see below

An empty page, limit or all (?page=) means not sent and takes the default.

search is safe with any text. Characters other than letters, digits and @ . - _ + ' : / & • are treated as spaces, so brackets, commas, quotes or wildcards cannot break the search. A term longer than 100 characters, or one with control characters, is refused with 400 invalid_search; a term with nothing searchable in it answers an empty page. pagination.total counts the orders that match, search included.

all=true does not return every booking in one answer: an API key gets pages of at most 200 bookings (limit defaults to 200). The response carries a coerced_value warning. Follow pagination.has_more and page to read the rest.

Response example

{
  "environment": "sandbox",
  "success": true,
  "data": [
    {
      "id": "639417b4-b103-4ece-bd5d-850315322278",
      "booking_id": "FX-1793546602916",
      "order_id": "20261101-106852",
      "status": "confirmed",
      "currency": "DZD",
      "total_price": 468.84,
      "agency_commission": 50.24,
      "type": "esim",
      "package_name": "1 GB - 7 days • France",
      "iccid": "8900000540463077957",
      "customer_email": "[email protected]",
      "customer_first_name": "John",
      "customer_last_name": "Smith",
      "customer_phone": "+15555550123",
      "provider_name": "Airalo",
      "supplier_id": "airalo",
      "created_at": "2026-11-01T15:23:22.961228+00:00",
      "updated_at": "2026-11-01T15:23:22.961228+00:00",
      "environment": "sandbox"
    }
  ],
  "pagination": { "total": 61, "page": 1, "limit": 1, "pages": 61, "total_pages": 61, "has_more": true }
}

Booking fields

FieldMeaning
idInternal id of the booking row (UUID): the id the account history returns
booking_idThe FX-Port reference, FX- followed by a number. Use it in setup instructions and in the booking detail
order_idThe supplier's order code (code in the order response)
statusconfirmed, or failed when the supplier refused the order (the ICCID of such a row starts with PENDING-)
typeesim for an order, topup for a topup
currency, total_priceYour agency currency and the price charged to the traveler
agency_commissionYour commission as an amount. The amount debited from your balance is total_price minus this amount (see eSIM pricing)
package_namePackage name, with the destination for an order
iccidThe ICCID of the eSIM. A topup row carries the ICCID that was topped up
customer_email, customer_first_name, customer_last_name, customer_phoneThe traveler details you sent when ordering
provider_name, supplier_idThe supplier that fulfilled the booking. Here airalo: the supplier list calls the same supplier airalo_1
created_at, updated_atISO 8601 with a zone (UTC)
environmentsandbox or live

Only agency-facing fields are returned: the supplier's cost and FX-Port's internal margins are never part of a booking.

Pagination

FieldMeaning
totalNumber of orders that match (search included)
page, limitThe page returned and the page size used
pagesNumber of pages, 0 when there is no order. total_pages carries the same value
has_moretrue when another page follows

Topup history for an ICCID

GET /api/v1/esims/bookings/{iccid}/topup-history

Permission: Read

The topups of one eSIM, newest first, with the same booking shape as above and type: "topup". There is no pagination. The list is empty (status 200) when the eSIM has no topup or is not an eSIM of your agency.

curl --request GET \
  --url https://api.fx-port.com/api/v1/esims/bookings/8900000540463077957/topup-history \
  --header 'Authorization: Bearer fxp_test_YOUR_KEY'
{
  "environment": "sandbox",
  "success": true,
  "data": [
    {
      "id": "bd6ff7d7-392f-4d56-8dea-4f0f3dff0af9",
      "booking_id": "FX-1793546625391",
      "order_id": "20261101-106853",
      "status": "confirmed",
      "currency": "DZD",
      "total_price": 468.84,
      "agency_commission": 50.24,
      "type": "topup",
      "package_name": "1 GB - 7 days",
      "iccid": "8900000540463077957",
      "customer_email": "[email protected]",
      "customer_first_name": "John",
      "customer_last_name": "Smith",
      "customer_phone": "+15555550123",
      "provider_name": "Airalo",
      "supplier_id": "airalo",
      "created_at": "2026-11-01T15:23:45.424526+00:00",
      "updated_at": "2026-11-01T15:23:45.424526+00:00",
      "environment": "sandbox"
    }
  ]
}

The ICCID is 18 to 22 digits (groups of spaces or hyphens are read as the digits), or the PENDING-... placeholder of an order whose eSIM the supplier has not returned yet (letters, digits and -, at most 64 characters); anything else is refused with 400 invalid_iccid.

Check that a booking is yours

GET /api/v1/esims/bookings/{booking_id}/verify

Permission: Read

Tells whether an eSIM booking belongs to your agency, before you build a link or a screen around a booking_id. The reference is the booking_id of an eSIM order or topup (FX- followed by a number, not the internal UUID), at most 100 characters of letters, digits and ._:=+~- (400 invalid_booking_id otherwise).

curl --request GET \
  --url https://api.fx-port.com/api/v1/esims/bookings/FX-1793546602916/verify \
  --header 'Authorization: Bearer fxp_test_YOUR_KEY'
{
  "environment": "sandbox",
  "isOwner": true,
  "is_owner": true,
  "userAgencyId": "0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
  "bookingAgencyId": "0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d"
}
FieldMeaning
isOwnertrue when the booking is an eSIM booking of your agency in this environment. is_owner carries the same value
userAgencyId, bookingAgencyIdPresent only when isOwner is true; both are your own agency id

A booking of another agency and a booking that does not exist are answered the same way, {"isOwner": false} with status 200, so the call cannot be used to discover which references exist. This answer has no success key.

Errors

HTTPcodeCause
400invalid_searchsearch is longer than 100 characters or has control characters
400invalid_iccidThe ICCID of the topup history is not valid
400invalid_booking_idThe booking reference of verify is not valid
401authentication_required, invalid_api_keyMissing or invalid API key
422validation_errorpage or limit is not an integer in its range (for example limit=201)
429rate_limit_exceededOver 6,000 requests per minute for this key
PreviouseSIM usageNext Setup and installation instructions

On this page

  • List bookings
  • Response example
  • Booking fields
  • Pagination
  • Topup history for an ICCID
  • Check that a booking is yours
  • Errors

© 2026 FX-Port

TermsPrivacy[email protected]