Skip to content

List eSIMs

POST
/esims/list
curl --request POST \
--url 'https://api.roamex.com/v1/esims/list?lang=nl' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "status": "active", "page": 1, "limit": 50 }'

Lists your eSIMs, newest first, 20 per page by default. Each status filter other than all returns the eSIMs whose own status has that value, so together they cover every eSIM once.

lang
string
default: en

Language of plan and destination names in the response: en, nl, es, de, it, fr, pl, pt, tr, el, cs or ro. Any other value, or none, gives English. It never changes which items are returned or any figure.

Example

nl

Optional. An empty body lists every eSIM.

Media typeapplication/json
object
status

Any other value returns 400 INVALID_STATUS.

string
default: all
Allowed values: all cancelled expired active installed ready pending
page

Page number. A missing or non-numeric value means 1.

integer
default: 1 >= 1
limit

ESIMs per page. A missing or non-numeric value means 20; larger values are lowered to 100.

integer
default: 20 >= 1 <= 100

Example

{
"status": "active",
"page": 1,
"limit": 50
}

A page of eSIMs.

Media typeapplication/json
object
success
required
boolean
esims
required
Array<object>
object
id
required
string format: uuid
plan
required
object
name
required
string
region
required

The destination name.

string
status
required
  • pending: not ready to install yet.
  • ready: can be installed, including after it was removed from a device.
  • installed: on a device.
  • active: in use, and data has been used.
  • expired: all data is used (statusLabel Used Up). An eSIM past its end date keeps its other status; compare validity.expiresAt.
  • cancelled: cancelled by you or on the network, or spent and removed from the device.
string
Allowed values: pending ready installed active expired cancelled
statusLabel
required
string
Allowed values: Pending Ready Installed Active Used Up Cancelled
data
required
object
total
required
object
bytes
required

0 when unknown.

integer
formatted
required

Two decimals in GB, whole numbers in MB and KB, 0 B when unknown.

string
used
required
object
bytes
required

0 when unknown.

integer
formatted
required

Two decimals in GB, whole numbers in MB and KB, 0 B when unknown.

string
remaining
required
object
bytes
required

0 when unknown.

integer
formatted
required

Two decimals in GB, whole numbers in MB and KB, 0 B when unknown.

string
percentUsed
required

Rounded. 0 when the total is unknown.

integer
validity
required
object
days
required
integer | null
unit
required
string
expiresAt
required

When the validity ends, once known.

string | null
activatedAt
required

When the eSIM was activated, once known.

string | null
fulfillment
required

null until the eSIM has been emailed to a traveller.

object
fulfilledAt
required

When it was first sent.

string
email
required

The most recent recipient.

string | null
name
required
string | null
costCentre
required

The costCentre sent with the purchase. Never shown to the traveller.

string | null
createdAt
required
string format: date-time
lastRefreshedAt
required

When the eSIM’s figures were last read from the network.

string | null
pagination
required
object
page
required
integer
limit
required
integer
total
required

Matching items across all pages.

integer
totalPages
required
integer

Example

{
"success": true,
"esims": [
{
"id": "00000000-0000-4000-8000-0000000000c1",
"plan": {
"name": "Japan · 1 GB · 7 days",
"region": "Japan"
},
"status": "active",
"statusLabel": "Active",
"data": {
"total": {
"bytes": 1073741824,
"formatted": "1.00 GB"
},
"used": {
"bytes": 268435456,
"formatted": "256 MB"
},
"remaining": {
"bytes": 805306368,
"formatted": "768 MB"
},
"percentUsed": 25
},
"validity": {
"days": 7,
"unit": "DAY",
"expiresAt": "2026-10-29T08:00:00Z",
"activatedAt": "2026-10-22T08:00:00Z"
},
"fulfillment": {
"fulfilledAt": "2026-10-21T15:00:00+00:00",
"email": "traveller@example.com",
"name": "Sam Example"
},
"costCentre": "NL-SALES-2026",
"createdAt": "2026-10-21T14:58:00+00:00",
"lastRefreshedAt": "2026-10-22T09:00:00+00:00"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 1,
"totalPages": 1
}
}
X-RateLimit-Limit
integer

Calls allowed per minute for this endpoint group.

X-RateLimit-Remaining
integer

Calls left in the current minute.

X-RateLimit-Reset
integer

When the current window ends, in Unix seconds.

  • INVALID_JSON: the body is not a JSON object.
  • INVALID_STATUS: status is not one of the accepted values. The message lists them.
Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false
}

AUTH_ERROR: the key is missing, malformed, unknown or revoked. The message says which, for example Missing Authorization header, Invalid Authorization header format. Use: Bearer <api_key>, Invalid API key format or Invalid API key.

Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false,
"error": {
"code": "AUTH_ERROR",
"message": "Invalid API key"
}
}

AUTH_ERROR: the account is suspended (Your account is suspended. Please contact support.) or rejected (Account is not approved for API access).

Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false
}

NOT_FOUND: the API is switched off on the platform. Every endpoint answers this before the key is checked, with the message This feature is not available.

Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "This feature is not available."
}
}

PAYLOAD_TOO_LARGE: the Content-Length header is over 100 KB.

Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false
}

RATE_LIMITED: the account’s per-minute budget for this endpoint group is used up, or too many refused keys came from this IP address. Wait the Retry-After seconds.

Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Please wait 42 seconds before retrying."
}
}
X-RateLimit-Limit
integer

Calls allowed per minute for this endpoint group.

X-RateLimit-Remaining
integer

Calls left in the current minute.

X-RateLimit-Reset
integer

When the current window ends, in Unix seconds.

Retry-After
integer

Seconds to wait before retrying.

  • DATABASE_ERROR: the eSIMs could not be read.
  • INTERNAL_ERROR, or AUTH_ERROR with status 500: see the shared errors.
Media typeapplication/json
object
success
required
boolean
error
required
object
code
required

Machine-readable. Branch on this.

string
message
required

A sentence for people. It can change.

string

Example

{
"success": false
}