Skip to content
FX-Port/Docs
GuidesAPI referenceChangelog
Get API keys
  • Overview
  • Error object

Catalog

  • PackagesGET
  • Compatible devicesGET

Orders and top-ups

  • Create an orderPOST
  • Top-up packagesGET
  • Top upPOST

After the order

  • UsageGET
  • Usage of several eSIMsGET
  • BookingsGET
  • Top-up historyGET
  • Check ownershipGET
  • Setup dataGET
  • Installation instructionsGET

Objects

  • eSIM package
  • eSIM booking

eSIMs · Orders and top-ups

Top up an eSIM

Add a topup package to an eSIM of your agency and debit your agency balance (live only).

POST/api/v1/esims/topups

Requires an API key with Read+Write permission: a Read key is refused with read_write_permission_required.

Call GET /esims/topup-packages/{iccid} first and send one of its package_id values: a package that was not returned for this eSIM is refused. email and phone are required and kept on the booking; the email is not sent to the supplier on a topup. The ICCID must be an eSIM that your agency ordered.

The same rules as for an order apply: JSON body, server-side prices, no idempotency key, duplicate_request while the same topup is running or (live) when a topup of the same ICCID was confirmed in the last 60 seconds. If the supplier refuses the topup nothing is debited and a failed booking is saved. The sandbox debits nothing, returns a balance of 0.0, and adds the balanceDebited, transactionCreated and payoutCreated flags.

The booking of a topup is listed by GET /esims/bookings/{iccid}/topup-history, not by GET /esims/bookings.

curl https://api.fx-port.com/api/v1/esims/topups \
  -H "Authorization: Bearer fxp_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "package_id": "france-in-7days-1gb-topup",
  "iccid": "8900000540463077957",
  "first_name": "John",
  "last_name": "Smith",
  "email": "[email protected]",
  "phone": "+15555550123"
}'
Response200
{
  "environment": "sandbox",
  "success": true,
  "data": {
    "topup": {
      "code": "20261101-106853",
      "order_id": "20261101-106853",
      "package_id": "france-in-7days-1gb-topup",
      "package": "KPN France Data only-1 GB - 7 days",
      "data": "1 GB",
      "validity": 7,
      "price": 468.84,
      "currency": "DZD",
      "total_price": 468.84,
      "retail_price": 468.84,
      "agency_currency": "DZD",
      "supplier_currency": "USD",
      "exchange_rate": 250
    },
    "iccid": "8900000540463077957",
    "balance": {
      "previous": 0,
      "current": 0,
      "currency": "DZD"
    }
  },
  "booking_id": "FX-1793546625391",
  "message": "eSIM topup completed successfully",
  "balanceDebited": false,
  "balance_debited": false,
  "transactionCreated": false,
  "transaction_created": false,
  "payoutCreated": false,
  "payout_created": false
}

Request

Body

Required, JSON.

package_idstringrequired

The id of a topup package returned for this ICCID by the topup packages endpoint (its package_id).

At most 128 characters.

iccidstringrequired

The ICCID of the eSIM to top up: 18 to 22 digits, which may be written in groups of spaces or hyphens (8944 4654 0000 0123 456). It must be an eSIM that your agency ordered.

emailstringrequired

The traveler's email address. Kept on the booking: it is not sent to the supplier on a topup.

At most 254 characters.

phonestringrequired

The traveler's phone number: at least 3 digits. Kept on the booking.

At most 32 characters.

first_namestring

The traveler's first name. Any characters are accepted.

At most 100 characters.

last_namestring

The traveler's last name. Any characters are accepted.

At most 100 characters.

agent_idstring (uuid)

The id of the user of your agency who places the topup. Optional. A user of another agency is refused.

user_idstring (uuid)deprecated

Legacy name, still accepted. Use agent_id instead.

Previous name of agent_id.

customer_emailstringdeprecated

Legacy name, still accepted. Use email instead.

The name the booking rows use for email. Still accepted.

customer_phonestringdeprecated

Legacy name, still accepted. Use phone instead.

The name the booking rows use for phone. Still accepted.

customer_first_namestringdeprecated

Legacy name, still accepted. Use first_name instead.

The name the booking rows use for first_name. Still accepted.

customer_last_namestringdeprecated

Legacy name, still accepted. Use last_name instead.

The name the booking rows use for last_name. Still accepted.

Response

200The topup was applied. The response has status 200, not 201.

successboolean

true when the topup was applied.

dataobject

The topup, the ICCID and the balance change.

ShowHide 3 attributes
topupobject

The topup, with the amounts in your agency currency.

ShowHide 13 attributes
codestringdeprecated

Legacy name, still accepted. Use order_id instead.

The supplier's order code of the topup. Booking rows call it order_id. The older name of order_id: same value, use order_id.

order_idstring

The supplier's order code of the topup. Booking rows call it order_id. The snake_case twin of code, with the same value: use this name.

package_idstring

The topup package that was bought.

packagestring

Name of the topup package.

datastring

Data allowance added, as text.

validityinteger

Validity of the topup in days.

pricenumber

What the traveler pays, in your agency currency. Equal to total_price here (in the catalog, price is a different amount: see the pricing guide).

currencystring

Currency of the amounts: the settlement currency of your agency.

total_pricenumber

The price to charge the traveler, in your agency currency. Your commission is total_price minus the amount debited from your balance.

retail_pricenumber

The price to charge the traveler, in your agency currency. Your commission is total_price minus the amount debited from your balance. Another name of total_price, with the same value.

agency_currencystring

Same as currency.

supplier_currencystring

Currency the supplier prices the package in.

exchange_ratenumber

Rate used to convert supplier_currency to your agency currency.

iccidstring

The ICCID that was topped up.

balanceobject

The agency balance around the topup.

ShowHide 3 attributes
previousnumber

Agency balance in this currency before the topup. Always 0.0 in the sandbox.

currentnumber

Agency balance after the topup. Always 0.0 in the sandbox.

currencystring

Currency of the balance.

booking_idstring

The FX-Port booking reference of the topup, FX- followed by a number.

messagestring

A confirmation sentence.

balanceDebitedbooleandeprecated

Legacy name, still accepted. Use balance_debited instead.

Sandbox only, always false: no balance was debited. The older name of balance_debited: same value, use balance_debited.

balance_debitedboolean

Sandbox only, always false: no balance was debited. The snake_case twin of balanceDebited, with the same value: use this name.

transactionCreatedbooleandeprecated

Legacy name, still accepted. Use transaction_created instead.

Sandbox only, always false: no balance transaction was created. The older name of transaction_created: same value, use transaction_created.

transaction_createdboolean

Sandbox only, always false: no balance transaction was created. The snake_case twin of transactionCreated, with the same value: use this name.

payoutCreatedbooleandeprecated

Legacy name, still accepted. Use payout_created instead.

Sandbox only, always false: no supplier payout was created. The older name of payout_created: same value, use payout_created.

payout_createdboolean

Sandbox only, always false: no supplier payout was created. The snake_case twin of payoutCreated, with the same value: use this name.

Errors

StatusCodeExample message
400missing_fieldpackage_id and iccid are required
400invalid_iccidiccid must be 18-22 digits (received '123').
402insufficient_balanceAgency balance is insufficient. Available: 300.0 DZD, Required: 418.6 DZD.
403read_write_permission_requiredThis endpoint requires an API key with read_write permission.
404iccid_not_foundNo eSIM with this ICCID was found for your account.
404not_foundPackage no-such-topup not found or has no valid price
409duplicate_requestA duplicate topup was detected for this eSIM. If intentional, please wait 60 seconds before retrying.
429rate_limit_exceededToo many requests hit the API too quickly. Please retry your request after the time specified in the `ratelimit-reset` header.
429concurrency_limit_exceededToo many requests of this kind are already running for this API key; wait for one to finish and retry.
503service_unavailableAiralo token unavailable

The shape of the error body depends on the endpoint. See Errors for every shape and code.

Related guides

  • Top up an eSIM
  • Supplier continuity
PreviousList topup packages of an eSIMNext Get the usage of an eSIM

© 2026 FX-Port

TermsPrivacy[email protected]