Introduction
Welcome to the Mobilexy - eSIM API documentation.
This API allows you to integrate eSIM purchasing and management capabilities directly into your application. You can retrieve coverage information, view plans, check your balance, and purchase eSIMs programmatically.
All responses are returned in JSON format. The API accepts both GET and POST requests depending on the endpoint.
Authentication
Authenticating your API requests.
Most endpoints require authentication using your API Key. You can find your API Key in your dashboard explicitly. Include the api_key parameter in your request body or query string for authenticated endpoints.
List Countries
Retrieve a list of all supported countries.
Endpoint: https://mobilexy.com/api/coverage/countries
Method: GET
Response Parameters
| Name | Type | Description |
|---|---|---|
| countries | array | List of country objects |
| countries[].name | string | Country name |
| countries[].slug | string | Country identifier slug |
| countries[].image | string | Country flag image URL |
| countries[].converted_price | string | Starting price for plans |
{
"remark": "countries",
"status": "success",
"message": ["Countries List"],
"data": {
"countries": [
{
"name": "Afghanistan",
"slug": "afghanistan",
"image": null,
"converted_price": "8.12000000"
},
{
"name": "Aland Islands",
"slug": "aland-islands",
"image": null,
"converted_price": "6.14000000"
}
]
}
}
List Regions
Retrieve a list of all supported regions.
Endpoint: https://mobilexy.com/api/coverage/regions
Method: GET
Response Parameters
| Name | Type | Description |
|---|---|---|
| regions | array | List of region objects |
| regions[].name | string | Region name |
| regions[].slug | string | Region identifier slug |
| regions[].plan_count | integer | Number of available plans |
{
"remark": "regions",
"status": "success",
"message": ["Regions List"],
"data": {
"regions": [
{
"name": "Africa (AF-29)",
"slug": "africa-af-29",
"image": null,
"plan_count": 3
},
{
"name": "Asia (AS-12)",
"slug": "asia-as-12",
"image": null,
"plan_count": 10
}
]
}
}
Country Plans
Get plans for a specific country.
Endpoint: https://mobilexy.com/api/country-plans/{slug}
Method: GET
Replace {slug} with the country slug (e.g., afghanistan).
Response Parameters
| Name | Type | Description |
|---|---|---|
| plans | array | List of plan objects |
| plans[].id | integer | Plan ID |
| plans[].name | string | Plan name |
| plans[].period | integer | Validity period in days |
| plans[].data_volume | integer | Data amount in bytes (-1 for unlimited) |
| plans[].converted_price | string | Price of the plan |
{
"remark": "country_plan",
"status": "success",
"message": ["Afghanistan eSIM Plans"],
"data": {
"plans": [
{
"id": 855,
"slug": "AF_0.5_Daily",
"name": "Afghanistan 500MB/Day",
"period": 1,
"package_type": "DATA",
"data_volume": -1,
"voice_quantity": "0.00",
"sms_quantity": 0,
"fup_policy_text": "500MB high-speed/day, 512 Kbps after limit, resets daily",
"phone_number": 0,
"operator_name": "Etisalat",
"operator_slug": null,
"network_speed": "3G",
"area_coverage": "local",
"status": 1,
"converted_price": "8.12000000",
"currency": null
"packageCode": "CKH226"
},
],
"flag": "url_to_flag_image",
"flagCode": "US"
}
}
Region Plans
Get plans for a specific region.
Endpoint: https://mobilexy.com/api/region-plans/{slug}
Method: GET
Replace {slug} with the region slug (e.g., europe).
Response Parameters
| Name | Type | Description |
|---|---|---|
| plans | array | List of plan objects |
| plans[].countries | array | List of countries included in the region |
| plans[].countries[].name | string | Country name |
{
"remark": "region_plan",
"status": "success",
"message": ["Asia (AS-12) eSIM Plans"],
"data": {
"plans": [
{
"id": 855,
"slug": "AS-12_0.5_Daily",
"name": "Asia (12 areas) 500MB/Day",
"period": 1,
"package_type": "DATA",
"data_volume": -1,
"voice_quantity": "0.00",
"sms_quantity": 0,
"fup_policy_text": "500MB high-speed/day, 128 Kbps after limit, resets daily",
"operator_name": "Metfone, China Unicom, csl, Telkomsel, KDDI/au, CTM, CelcomDigi, Maxis, SingTel, SKTelecom, LG U+, Chunghwa, DTAC, TrueMove H, MobiFone, Viettel Mobile, Vietnamobile",
"operator_slug": null,
"network_speed": "3G/4G",
"area_coverage": "continental",
"status": 1,
"converted_price": "7.28000000",
"currency": null,
"packageCode": "CKH226"
"countries": [
{
"name": "Hong Kong (China)",
"slug": "hong-kong-china",
"image": null
},
{
"name": "Macao (China)",
"slug": "macao-china",
"image": null
},
]
}
],
"flag": "url_to_image"
}
}
Global Plans
Get global eSIM plans.
Endpoint: https://mobilexy.com/api/global-plans
Method: GET
Response Parameters
| Name | Type | Description |
|---|---|---|
| plans | array | List of global plan objects |
| plans[].countries | array | List of supported countries |
{
"remark": "global_plan",
"status": "success",
"message": ["Global eSIM Plans"],
"data": {
"plans": [
{
"id": 855,
"slug": "AS-12_0.5_Daily",
"name": "Asia (12 areas) 500MB/Day",
"period": 1,
"package_type": "DATA",
"data_volume": -1,
"voice_quantity": "0.00",
"sms_quantity": 0,
"fup_policy_text": "500MB high-speed/day, 128 Kbps after limit, resets daily",
"operator_name": "Metfone, China Unicom, csl, Telkomsel, KDDI/au, CTM, CelcomDigi, Maxis, SingTel, SKTelecom, LG U+, Chunghwa, DTAC, TrueMove H, MobiFone, Viettel Mobile, Vietnamobile",
"operator_slug": null,
"network_speed": "3G/4G",
"area_coverage": "continental",
"status": 1,
"converted_price": "7.28000000",
"currency": null,
"packageCode": "CKH226"
"countries": [
{
"name": "Hong Kong (China)",
"slug": "hong-kong-china",
"image": null
},
{
"name": "Macao (China)",
"slug": "macao-china",
"image": null
},
]
}
],
"flag": "url_to_globe_image"
}
}
Check Balance
Check your account balance.
Endpoint: https://mobilexy.com/api/balance
Method: POST
Parameters
| Name | Type | Description |
|---|---|---|
| api_key | string | Required Your API Key |
Response Parameters
| Name | Type | Description |
|---|---|---|
| balance | float | Current account balance |
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://mobilexy.com/api/balance',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'api_key' => 'YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
{
"remark": "balance",
"status": "success",
"message": ["Account balance"],
"data": {
"balance": 100.00
}
}
Plan Details
Get details of a specific plan.
Endpoint: https://mobilexy.com/api/plan/{id}
Method: GET
Replace {id} with the plan ID.
Response Parameters
| Name | Type | Description |
|---|---|---|
| plan | object | Plan details object |
| plan.name | string | Plan name |
| plan.voice_quantity | integer | Voice quantity in minutes |
| plan.sms_quantity | integer | SMS quantity. -1 for unlimited |
{
"remark": "plan_details",
"status": "success",
"message": ["Plan Details"],
"data": {
"plan": {
"id": 811,
"slug": "AS-12_3_30",
"name": "Asia (12 areas) 3GB 30Days",
"period": 30,
"package_type": "DATA",
"data_volume": 3221225472,
"voice_quantity": "0.00",
"sms_quantity": 0,
"fup_policy_text": "",
"operator_name": "Metfone, China Unicom, csl, Telkomsel, KDDI/au, CTM, CelcomDigi, Maxis, SingTel, SKTelecom, LG U+, Chunghwa, DTAC, TrueMove H, MobiFone, Viettel Mobile, Vietnamobile",
"operator_slug": null,
"network_speed": "3G/4G",
"area_coverage": "continental"
"packageCode": "CKH226"
}
}
}
Purchase Plan
Purchase an eSIM plan.
Endpoint: https://mobilexy.com/api/plan/purchase
Method: POST
Request Parameters
| Name | Type | Description |
|---|---|---|
| api_key | string | Required Your API Key |
| plan_id | integer | Required ID of the plan to purchase |
Response Parameters
| Name | Type | Description |
|---|---|---|
| order | object | Order details |
| order.order_number | string | Unique order number |
| esim | object | eSIM details |
| esim.qr_code | string | LPA string for eSIM activation |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://mobilexy.com/api/plan/purchase',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'api_key' => 'YOUR_API_KEY',
'plan_id' => '10'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"remark": "order_completed",
"status": "success",
"message": ["Order completed successfully"],
"data": {
"order": {
"order_number": "GW7DUVMKGO",
"total_amount": "6.20000000",
"status": 0
},
"esim": {
"serial_number": 2147483647,
"iccid": null,
"phone_number": "0840358292",
"qr_code": "LPA:1$ais.prod.ondemandconnectivity.com$SEW7JEBMFGPRVSPD",
"qr_code_image": null,
"expiry_date": "2025-08-05",
"info": null
}
}
}
Manage Profile - Top Up
Top up the data service of an existing installed eSIM with a new plan.
Endpoint: https://mobilexy.com/api/profile/topup
Method: POST
Request Parameters
| Name | Type | Description |
|---|---|---|
| api_key | string | Required Your API Key |
| esimTranNo | string | Required Single eSIM transaction number |
| packageCode | string | Required Top up package code (provider package code) |
Response Parameters
| Name | Type | Description |
|---|---|---|
| transactionId | string | Transaction ID |
| iccid | string | ICCID of the topped-up eSIM |
| expiredTime | long | New package expiry (ISO timestamp) |
| totalVolume | long | New total data balance in bytes |
| totalDuration | integer | New validity period in days |
| orderUsage | long | Total package usage in bytes |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://mobilexy.com/api/profile/topup',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'api_key' => 'YOUR_API_KEY',
'esimTranNo' => '26021613280014',
'packageCode' => 'PFRQ8FIBC'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"remark": "topup_completed",
"status": "success",
"message": {
"success": [
"Top up completed successfully"
]
},
"data": {
"success": true,
"errorCode": null,
"errorMsg": null,
"obj": {
"transactionId": "MBL-RGNRTU9DAK_1771248518",
"iccid": "8910300000056693431",
"expiredTime": "2026-03-30T07:37:12+0000",
"totalVolume": 6442450944,
"totalDuration": 42,
"orderUsage": 0,
"topUpEsimTranNo": "26021613280014"
}
}
}
Usage Check
Retrieve the latest data usage snapshot (in bytes) for up to 10 eSIMs by their esimTranNo. Usage data is refreshed every 2–3 hours by the carrier and is not real-time.
Endpoint: https://mobilexy.com/api/profile/usage-check
Method: POST
Request Parameters
| Name | Type | Description |
|---|---|---|
| api_key | string | Required Your API Key |
| iccid | string | ICCID that resolves to an eSIM owned by the account |
| esimTranNo | string | Single eSIM transaction number. Use when checking one profile |
| esimTranNos | array | Up to 10 esimTranNo values to query together. |
Response Parameters
| Name | Type | Description |
|---|---|---|
| success | string | true: succeeded, false: failed |
| obj.usageList | object | One entry per requested eSIM with usage data |
| dataUsage | long | Current data usage in bytes |
| totalData | long | Plan allowance in bytes |
| lastUpdateTime | string | Timestamp of the latest usage update |
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://mobilexy.com/api/profile/usage-check',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'api_key' => 'YOUR_API_KEY',
'iccid' => '8948010010002120847'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"success": true,
"errorCode": "0",
"errorMsg": null,
"obj": {
"usageList": [
{
"esimTranNo": "26021607100025",
"dataUsage": 0,
"totalData": 1073741824,
"lastUpdateTime": "2026-02-16T07:10:58+0000"
}
]
}
}
}
Virtual Numbers API
Use these endpoints to search, purchase and manage virtual numbers through your API account.
Virtual number endpoints use the same API key authentication as the eSIM endpoints. Pass api_key in the query string or request body. Bearer token authentication is also supported where available.
Prices are returned in USD. Purchasing a virtual number through the API uses the partner wallet balance directly. The customer must have enough balance before calling the purchase endpoint.
Available numbers are cached for a short time because Roamlinx offer tokens expire. If an offer token expires, request the available numbers endpoint again and use the new offerToken.
Virtual Number Countries
Retrieve enabled countries for virtual numbers. Use with_price=1 to return only countries that currently have a cached starting price.
Endpoint: https://mobilexy.com/api/virtual-numbers/countries
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| with_price | No | boolean | Set to 1 to return only countries with cached minimum price |
Response Parameters
| Name | Type | Description |
|---|---|---|
| countries | array | List of enabled virtual number country objects |
| countries[].country_code | string | ISO country code |
| countries[].country_name | string | Country name |
| countries[].min_retail_price | decimal | Minimum current retail price in USD when available |
| countries[].cached_numbers_count | integer | Number of currently cached available offers |
| countries[].types | array | Available number types, when provided by Roamlinx |
curl "https://mobilexy.com/api/virtual-numbers/countries?api_key=YOUR_API_KEY&with_price=1"
{
"remark": "virtual_number_countries",
"status": "success",
"message": ["Virtual number countries"],
"data": {
"countries": [
{
"country_code": "AR",
"country_name": "Argentina",
"min_retail_price": "8.33000000",
"cached_numbers_count": 10,
"types": ["local"]
}
]
}
}
Available Virtual Numbers
Search available virtual numbers. The returned offerToken is required to purchase the number and expires after a short time.
Endpoint: https://mobilexy.com/api/virtual-numbers/available
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| country | No | string | ISO country code, for example AR |
| type | No | string | Number type, for example local, mobile, tollfree, national |
| features | No | string | Comma separated features when supported, for example voice_in,sms_in |
| numberPrefix | No | string | Optional number prefix filter |
curl "https://mobilexy.com/api/virtual-numbers/available?api_key=YOUR_API_KEY&country=AR&type=local"
{
"remark": "virtual_numbers_available",
"status": "success",
"message": ["Available virtual numbers"],
"data": {
"success": true,
"obj": {
"items": [
{
"offerToken": "OFFER_TOKEN_HERE",
"number": "542494401315",
"country": "AR",
"countryName": "Argentina",
"type": "local",
"features": ["voice_in", "voice_out"],
"setupPrice": "0.00",
"monthlyPrice": "8.33",
"currency": "USD",
"offerExpiresInSec": 600
}
]
}
}
}
Purchase Virtual Number
Purchase a virtual number with a valid offerToken. The amount is deducted from the API user balance.
Endpoint: https://mobilexy.com/api/virtual-numbers/order
Method: POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| offerToken | Yes | string | Offer token returned by the available numbers endpoint |
| number | No | string | Number shown to the customer; used for local order display |
| country | No | string | ISO country code |
| type | No | string | Number type |
| setupPrice | No | decimal | Provider setup price from the available response |
| monthlyPrice | No | decimal | Provider monthly price from the available response |
curl -X POST "https://mobilexy.com/api/virtual-numbers/order" \
-d "api_key=YOUR_API_KEY" \
-d "offerToken=OFFER_TOKEN_HERE" \
-d "number=542494401315" \
-d "country=AR" \
-d "type=local" \
-d "setupPrice=0.00" \
-d "monthlyPrice=8.33"
{
"remark": "virtual_number_ordered",
"status": "success",
"message": ["Virtual number ordered successfully"],
"data": {
"order": {
"order_number": "ABCD12345678",
"transaction_id": "VN-1-ABCD12345678",
"number": "542494401315",
"country": "AR",
"status": "active",
"retail_price": "8.33000000",
"virtual_number": {
"id": 15,
"roamlinx_number_id": "rlx_number_id",
"number": "542494401315",
"status": "active"
}
}
}
}
List Purchased Virtual Numbers
Retrieve purchased virtual numbers for the authenticated API user.
Endpoint: https://mobilexy.com/api/virtual-numbers/list
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| status | No | string | Filter by status, for example active, pending_activation, pending_termination, blocked_no_funds |
| per_page | No | integer | Pagination size |
curl "https://mobilexy.com/api/virtual-numbers/list?api_key=YOUR_API_KEY&status=active"
Virtual Number Details
Get details for one purchased virtual number. The identifier can be the local ID or the Roamlinx number ID.
Endpoint: https://mobilexy.com/api/virtual-numbers/{id}
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| id | Yes | integer/string | Local virtual number ID or Roamlinx number ID in the URL |
| api_key | Yes | string | Your API key |
curl "https://mobilexy.com/api/virtual-numbers/15?api_key=YOUR_API_KEY"
Cancel Virtual Number
Cancel a virtual number. The number stays active until its expiration date when Roamlinx returns pending termination.
Endpoint: https://mobilexy.com/api/virtual-numbers/{id}/cancel
Method: POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| id | Yes | integer/string | Local virtual number ID or Roamlinx number ID in the URL |
| api_key | Yes | string | Your API key |
curl -X POST "https://mobilexy.com/api/virtual-numbers/15/cancel" -d "api_key=YOUR_API_KEY"
Virtual Number SMS Messages
Retrieve inbound SMS messages received by a purchased virtual number.
Endpoint: https://mobilexy.com/api/virtual-numbers/{id}/sms
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| id | Yes | integer/string | Local virtual number ID or Roamlinx number ID in the URL |
| api_key | Yes | string | Your API key |
| per_page | No | integer | Pagination size |
curl "https://mobilexy.com/api/virtual-numbers/15/sms?api_key=YOUR_API_KEY"
Virtual Number Charges
Retrieve SMS charge records for a purchased virtual number when SMS charge billing is enabled.
Endpoint: https://mobilexy.com/api/virtual-numbers/{id}/charges
Method: GET
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| id | Yes | integer/string | Local virtual number ID or Roamlinx number ID in the URL |
| api_key | Yes | string | Your API key |
| per_page | No | integer | Pagination size |
curl "https://mobilexy.com/api/virtual-numbers/15/charges?api_key=YOUR_API_KEY"
Reactivate Blocked Virtual Number
Reactivate a locally blocked virtual number after the user balance is refilled. This does not restore a number that was already cancelled or terminated by Roamlinx.
Endpoint: https://mobilexy.com/api/virtual-numbers/{id}/reactivate
Method: POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| id | Yes | integer/string | Local virtual number ID or Roamlinx number ID in the URL |
| api_key | Yes | string | Your API key |
curl -X POST "https://mobilexy.com/api/virtual-numbers/15/reactivate" -d "api_key=YOUR_API_KEY"
Pay-as-you-go eSIM API
A metered eSIM: you buy one profile and data is billed per megabyte actually used, instead of buying a fixed package up front.
One order gives your customer a working eSIM. The price of the eSIM already contains prepaid data credit, and a set of countries is switched on automatically at purchase — so you can hand the QR code straight to your customer with nothing further to do.
Your API key selects both the wallet and the price. An order placed through an API key is billed to that key's balance and priced at your reseller rate. Use the pricing endpoint to read your own rate rather than assuming the website price.
Money model. When you buy an eSIM, part of the price becomes data credit held on that eSIM. Data usage is deducted from that credit. When a country is switched off and the network has reported its final records, whatever is left of the credit returns to your balance. You are never billed beyond the credit on the eSIM.
Usage is reported late.
Mobile networks deliver usage records with a delay — about half arrive within 30 minutes, and a small share can take up to 17 hours. Every response that carries a usage figure also carries usage_as_of, the moment that figure is true as of. Show it to your customer; a number without it looks stuck.
Units and currency.
Data volumes are binary — 1 GiB = 1024 MiB = 1048576 bytes. Amounts are in wallet credits (XYC), which are 1:1 with USD, the same unit used by the virtual number endpoints.
Authentication is the same as every other endpoint here: pass api_key in the query string or request body, or send it as a bearer token.
PAYG Pricing
What one eSIM costs you, and which countries come switched on with it. Call this before showing a price to your own customer — your rate is not the website rate.
Endpoint: https://mobilexy.com/api/payg/pricing
Method: GET or POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
Response Parameters
| Name | Type | Description |
|---|---|---|
| esim_price | decimal | Total charged to your balance for one eSIM, including the prepaid data credit inside it |
| markup_percent | decimal | Your markup over our cost. 0 means you are on cost price. |
| included_countries | array | ISO codes switched on automatically when the eSIM is ordered, at no extra charge. This set changes as coverage is added — read it, do not hard-code it. |
| currency | string | Wallet credits, 1:1 with USD |
curl "https://mobilexy.com/api/payg/pricing?api_key=YOUR_API_KEY"
{
"remark": "payg_pricing",
"status": "success",
"message": ["Pricing"],
"data": {
"currency": "XYC",
"esim_price": 4.44,
"markup_percent": 0,
"included_countries": ["PL", "BE", "BG", "LV", "NL", "SE", "HU", "SI", "SK", "CZ", "GB", "RO", "AT", "IT", "NO", "GR", "IL", "TH", "AU", "UZ", "RU", "BD", "TN"],
"note": "The eSIM price includes prepaid data credit and the included countries switched on. Data is billed per MiB from that credit; unused credit is returned when a country closes."
}
}
PAYG Countries
Every country you can switch on, priced at your rate. Rates move when the network operator changes them, so read this endpoint rather than caching prices for long.
Endpoint: https://mobilexy.com/api/payg/countries
Method: GET or POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
Response Parameters
| Name | Type | Description |
|---|---|---|
| countries[].country | string | ISO country code |
| countries[].name | string | Country name |
| countries[].price_per_gib | decimal | Your price for 1 GiB of data in that country |
| countries[].price_per_mib | decimal | Same rate per MiB — this is the figure billing actually uses |
| countries[].reserve | decimal | Data credit moved onto the eSIM when this country is switched on outside the included set |
| countries[].networks | integer | How many operators serve the country. The handset picks one; your price is the same either way. |
| markup | decimal | The markup applied to build these prices |
curl "https://mobilexy.com/api/payg/countries?api_key=YOUR_API_KEY"
{
"remark": "payg_countries",
"status": "success",
"message": ["Countries available"],
"data": {
"currency": "XYC",
"markup": 0,
"count": 91,
"countries": [
{
"country": "AT",
"name": "Austria",
"price_per_gib": 1.1719,
"price_per_mib": 0.00114444,
"reserve": 1.17,
"networks": 3
}
]
}
}
Regions
A region is a set of countries switched on with ONE call and covered by ONE reserve. Prefer regions over switching countries one by one — they are cheaper for us to carry, so far more of the world is reachable this way.
Endpoint: https://mobilexy.com/api/payg/regions
Method: GET or POST
Response Parameters
| Name | Type | Description |
|---|---|---|
| region | string | Code to pass to /payg/activate and to the order endpoint |
| name | string | Human-readable name |
| kind | string | base or fallback. A fallback region carries the same countries with more operators enabled — use it when a customer reports no service. |
| countries | integer | How many countries the region covers |
| country_list | array | The ISO codes themselves |
| list_approximate | boolean | true when we believe this list but the operator has not published theirs. Safe to display, but do not treat as contractual. |
| price_per_gib | decimal | Your rate anywhere in the region — one price, no matter which country the customer is in |
| reserve | decimal | Data credit set aside on the eSIM when the region is switched on |
To switch a region on or off, use the same activate / deactivate endpoints with region instead of country. To hand the customer an eSIM that already works, pass region to the order endpoint.
curl "https://mobilexy.com/api/payg/regions?api_key=YOUR_API_KEY"
# switch a region on for an existing eSIM
curl -X POST "https://mobilexy.com/api/payg/activate" \
-d "api_key=YOUR_API_KEY" \
-d "iccid=8948010000024149411" \
-d "region=PAYG-A"
# or hand over an eSIM that already works there
curl -X POST "https://mobilexy.com/api/payg/order" \
-d "api_key=YOUR_API_KEY" \
-d "region=PAYG-A" \
-d "client_request_id=order-10310"
{
"remark": "payg_regions",
"status": "success",
"message": ["Regions available"],
"data": {
"currency": "XYC",
"markup": 0,
"count": 6,
"regions": [
{
"region": "PAYG-A",
"name": "Europe & Popular",
"kind": "base",
"countries": 60,
"country_list": ["AT", "BE", "BG", "CZ", "DE", "ES", "FR", "GB", "..."],
"list_approximate": false,
"price_per_gib": 1.9804,
"price_per_mib": 0.00193398,
"reserve": 3.00
}
]
}
}
PAYG Balance
Spendable balance behind the key you are calling with. If you issued several API keys and split your balance between them, this returns that key's own sub-balance, not the total.
Endpoint: https://mobilexy.com/api/payg/balance
Method: GET or POST
Response Parameters
| Name | Type | Description |
|---|---|---|
| balance | decimal | Spendable amount for this key |
| key | string | Label of the key used, or null when calling with your primary key |
curl "https://mobilexy.com/api/payg/balance?api_key=YOUR_API_KEY"
{
"remark": "payg_balance",
"status": "success",
"message": ["Balance"],
"data": {
"currency": "XYC",
"balance": 214.6,
"key": "storefront-eu"
}
}
Order a PAYG eSIM
Buys one eSIM: your balance is charged, the profile is issued, the prepaid credit is placed on the eSIM and the included countries are switched on. The response carries the QR payload your customer installs.
Endpoint: https://mobilexy.com/api/payg/order
Method: POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key — also selects the wallet and the price |
| client_request_id | Recommended | string | Your own unique id, 1-64 characters of A-Z a-z 0-9 _ - . Repeating it returns the same eSIM instead of buying another. |
| region | No | string | Switch a whole region on as part of the purchase, e.g. PAYG-A. One activation covering dozens of countries — the customer chooses where they are going at checkout and the eSIM works on arrival. |
| countries | No | string | Comma-separated list, e.g. TR,GE,AM. Up to 8 at purchase; more can be added later with /payg/activate at no cost. Ignored when region is given. |
| activate | No | string | Default included switches the included countries on at purchase. none hands over a dormant eSIM — prepaid credit on board, no country switched on yet. Switching one on later costs nothing extra. |
Response Parameters
| Name | Type | Description |
|---|---|---|
| esim.iccid | string | The eSIM identifier — use it in every other PAYG call |
| esim.lpa | string | Full activation string. Render it as a QR code or give it to the customer to enter manually. |
| esim.activation_code | string | Activation code component |
| esim.smdp_address | string | SM-DP+ server address component |
| esim.funded | decimal | Everything ever taken from your balance for this eSIM — the purchase plus every top-up, less anything already returned. Grows when you top up. |
| esim.spent | decimal | What data has actually consumed so far. The three figures reconcile as funded = charged + spent + data_credit. |
| esim.data_credit | decimal | Prepaid credit currently on the eSIM |
| esim.charged | decimal | What was taken from your balance |
| esim.countries | array | Countries switched on, with per-country usage and charges |
| remark | string | payg_order_completed for a new eSIM, payg_order_replay when we returned an existing one instead of buying again |
# Bundled — included countries switched on at purchase
curl -X POST "https://mobilexy.com/api/payg/order" \
-d "api_key=YOUR_API_KEY" \
-d "client_request_id=order-10294"
# Dormant — prepaid credit on board, no country switched on yet
curl -X POST "https://mobilexy.com/api/payg/order" \
-d "api_key=YOUR_API_KEY" \
-d "activate=none" \
-d "client_request_id=order-10295"
{
"remark": "payg_order_completed",
"status": "success",
"message": ["eSIM"],
"data": {
"esim": {
"iccid": "8948010000024149395",
"status": "active",
"charged": 4.44,
"data_credit": 3.74,
"usage_bytes": 0,
"usage_as_of": null,
"lpa": "LPA:1$sm-dp.example.com$K2-XXXXXX-XXXXXX",
"activation_code": "K2-XXXXXX-XXXXXX",
"smdp_address": "sm-dp.example.com",
"countries": [
{ "country": "AT", "status": "active", "usage_bytes": 0, "charged": 0 }
]
}
}
}
Top Up an eSIM
Move more prepaid data credit onto an eSIM from the balance behind your API key. The money is available immediately and can be spent in ANY country switched on for that eSIM.
Endpoint: https://mobilexy.com/api/payg/topup
Method: POST
You do not have to call this to keep an eSIM working: while a country is switched on, credit is topped up automatically from your balance as it runs down. Use this when you want to decide what a particular eSIM carries — for example when your own customer has paid you for more data.
Nothing added here expires. Whatever is unused returns to your balance once the last country on the eSIM closes.
What changes in the response:
data_credit grows by the amount you added and funded grows with it, because the money came out of your balance. charged does NOT move — it records the purchase and stays fixed for the life of the eSIM, so a top-up is never mistaken for a second sale. spent only moves as data is used.
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key — also selects the wallet the money comes from |
| iccid | Yes | string | The eSIM to credit |
| amount | Yes | decimal | How much to move, minimum 0.01 |
| client_request_id | Recommended | string | Replay guard — repeating it will not move the money twice |
curl -X POST "https://mobilexy.com/api/payg/topup" \
-d "api_key=YOUR_API_KEY" \
-d "iccid=8948010000024149395" \
-d "amount=10.00" \
-d "client_request_id=topup-5512"
{
"remark": "payg_topup_completed",
"status": "success",
"message": ["eSIM"],
"data": {
"esim": {
"iccid": "8948010000024149395",
"status": "active",
"data_credit": 13.74,
"usage_bytes": 209715200,
"usage_as_of": "2026-08-18T09:41:00+00:00"
}
}
}
Activate a Country
Switches on a country that is not part of the included set. Data credit is moved onto the eSIM to cover it; the amount is the country's reserve figure. Countries already included with the eSIM need no call.
Endpoint: https://mobilexy.com/api/payg/activate
Method: POST
Activation is done on our side by ICCID and does not require the device to be online, so you can switch a country on before your customer travels.
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| iccid | Yes | string | The eSIM to switch on |
| country | Either this | string | Two-letter ISO country code |
| region | or this | string | Region code from /payg/regions — one call covers every country in it |
Response Parameters
| Name | Type | Description |
|---|---|---|
| status | string | active once data is live |
| reserved | decimal | Data credit moved onto the eSIM for this country |
| price_per_gib | decimal | The rate this country was locked in at. Later rate changes do not affect an open country. |
curl -X POST "https://mobilexy.com/api/payg/activate" \
-d "api_key=YOUR_API_KEY" \
-d "iccid=8948010000024149395" \
-d "country=TH"
{
"remark": "payg_country_activated",
"status": "success",
"message": ["Country switched on"],
"data": {
"iccid": "8948010000024149395",
"country": "TH",
"status": "active",
"reserved": 1.94,
"price_per_gib": 1.9414
}
}
Deactivate a Country
Stops data in a country. Unused credit is not returned at once — the network still owes us its final usage records, and only when they have arrived is the remainder released back to your balance.
Endpoint: https://mobilexy.com/api/payg/deactivate
Method: POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| iccid | Yes | string | The eSIM |
| country | Yes | string | Two-letter ISO country code of an open country |
Response Parameters
| Name | Type | Description |
|---|---|---|
| status | string | Usually settling — stopped, waiting for the final usage records before the remaining credit is released |
curl -X POST "https://mobilexy.com/api/payg/deactivate" \
-d "api_key=YOUR_API_KEY" \
-d "iccid=8948010000024149395" \
-d "country=TH"
{
"remark": "payg_country_deactivated",
"status": "success",
"message": ["Country switched off"],
"data": {
"iccid": "8948010000024149395",
"country": "TH",
"status": "settling",
"note": "Unused prepaid credit returns once the final usage records arrive."
}
}
My PAYG eSIMs
Paginated list of the eSIMs on your account, newest first. QR payloads are omitted here — read a single eSIM to get them.
Endpoint: https://mobilexy.com/api/payg/esims
Method: GET or POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| per_page | No | integer | Pagination size |
curl "https://mobilexy.com/api/payg/esims?api_key=YOUR_API_KEY&per_page=20"
PAYG eSIM Details
One eSIM with its QR payload, remaining credit, usage so far and the state of every country on it. This is the endpoint to poll while a customer is travelling.
Endpoint: https://mobilexy.com/api/payg/esim
Method: GET or POST
Request Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| api_key | Yes | string | Your API key |
| iccid | Yes | string | The eSIM identifier |
Response Parameters
| Name | Type | Description |
|---|---|---|
| charged | decimal | The purchase itself. Does NOT change when you top up. |
| funded | decimal | Everything ever taken from your balance for this eSIM, top-ups included, less anything returned. |
| spent | decimal | What data has consumed so far. |
| data_credit | decimal | Prepaid credit left on the eSIM |
| usage_bytes | integer | Total data used, in bytes |
| usage_as_of | datetime | The moment the usage figure is true as of. Null until the first records arrive. Always show this next to the figure. |
| countries[].status | string | active, settling, stopping or closed |
| countries[].charged | decimal | Billed for that country so far |
curl "https://mobilexy.com/api/payg/esim?api_key=YOUR_API_KEY&iccid=8948010000024149395"
{
"remark": "payg_esim",
"status": "success",
"message": ["eSIM"],
"data": {
"esim": {
"iccid": "8948010000024149395",
"status": "active",
"charged": 4.44,
"data_credit": 3.4474,
"usage_bytes": 209715200,
"usage_as_of": "2026-08-14T09:41:00+00:00",
"lpa": "LPA:1$sm-dp.example.com$K2-XXXXXX-XXXXXX",
"activation_code": "K2-XXXXXX-XXXXXX",
"smdp_address": "sm-dp.example.com",
"countries": [
{ "country": "AT", "status": "active", "usage_bytes": 209715200, "charged": 0.2288 },
{ "country": "PL", "status": "active", "usage_bytes": 0, "charged": 0 }
]
}
}
}
Balance Webhooks
We call your endpoint whenever an eSIM balance moves, so you can mirror it without polling.
Setting it up
Pass callback_url when ordering an eSIM, or give us one address for the whole account and we use it for every eSIM. It must be a public https address. We issue you a shared secret once — keep it, it is not shown again.
When it fires
| Event | reason |
|---|---|
| Data was charged | usage |
| A top-up completed | topup |
| A country or region was switched on | activate / activate_region |
| A country closed and unused credit returned | settled |
Headers
| Header | Description |
|---|---|
| X-Mobilexy-Secret | Your shared secret, verbatim |
| X-Mobilexy-Signature | HMAC-SHA256 of the RAW body, keyed with that secret. Verify before parsing the JSON. |
| X-Mobilexy-Timestamp | Unix seconds at send time |
Body
| Name | Type | Description |
|---|---|---|
| iccid | string | Which eSIM |
| amount | decimal | Credit left on the eSIM — the same figure as data_credit |
| is_active | boolean | false once the remaining credit no longer covers the agreed floor — the same threshold at which we stop the eSIM |
| usage_as_of | datetime | When the usage figures are true as of; null until the first records arrive |
| sequence | integer | Per-eSIM counter, see above |
| countries | array | Per country or region: status, usage_bytes, charged |
Answer 200. Anything else counts as a failure and we retry with growing gaps — 1, 4, 9, 16 minutes — up to six attempts. Make your handler idempotent: a duplicate is always possible.
{
"iccid": "8948010000024149411",
"amount": 3.79,
"is_active": true,
"usage_as_of": "2026-08-21T09:41:00+00:00",
"sequence": 1,
"countries": [
{
"country": null,
"region": "PAYG-A",
"status": "active",
"usage_bytes": 0,
"charged": 0
}
]
}
Errors & Retries
Errors follow the same envelope as the rest of this API: status: "error" with a remark and a message array.
| Remark | Meaning | What to do |
|---|---|---|
| invalid_api_key | Key not recognised or inactive | Check the key |
| not_available | Pay-as-you-go is switched off | Contact us |
| validation_error | A parameter is missing or malformed | Read the message array |
| duplicate_request | An order with this client_request_id is already in flight | Wait, then read the eSIM — do not order again |
| order_failed | The order did not complete | See the note below — the message text matters |
| esim_not_found | No such eSIM on your account | Check the ICCID |
| not_active | That country is not switched on for this eSIM | Nothing to deactivate |
There are no webhooks on this product yet. Poll the eSIM endpoint for usage, and remember the reporting delay before treating a figure as final.