eSIM
Order an eSIM
Orders an eSIM and creates a new profile in a single operation.
Returns the eSIM details including the activation code (LPA string) for device installation, along with the newly created profile reference for future API calls.
To port an existing number onto the new eSIM, include the optional portIn block — the eSIM then stays pre-active (installable, but no service) until the port completes. See the Porting tag for the full workflow.
/esimsAuthorization
Authorization: Bearer {token} — an OAuth2 access token from the client-credentials flow. How authentication works
Headers
X-Idempotency-KeystringOptional idempotency key for mutating requests (POST, PATCH). If provided, duplicate requests with the same key within 48 hours will return the cached original response without duplicating side effects.
Behavior:
- Same key + same request body → returns cached response (prevents duplicate operations)
- Same key + different request body → returns 422 error
- Same key + in-flight request → returns 409 error with Retry-After header
- Keys expire after 48 hours
Request Body Matching: Request bodies are compared using a deterministic fingerprint. The fingerprint is computed by canonicalizing the JSON (sorting object keys recursively) and hashing with SHA-256. This means:
{"a":1,"b":2}and{"b":2,"a":1}are treated as identical ✓- Whitespace differences are ignored ✓
- URL parameters and headers are NOT included in the fingerprint
Best Practices:
- Use UUIDs or client-generated unique strings
- Store keys on your side to support retries
- Don't reuse keys across different operations
Request body
application/json
externalProfileIdstringOptional client-provided external ID to associate with this eSIM. Must be unique per client.
esimVariantstringThe eSIM variant to draw from the pool (e.g. 'travel'). Draws from the client's assigned variants of this type. Optional — falls back to the client's default variant when omitted.
portInobjectOptional port-in of an existing number onto the ordered eSIM. When present, the eSIM stays pre-active until the port completes and the response contains a portIn object.
Show propertiesHide properties
msisdnstringrequiredThe number to port, in international format (E.164 without a leading +) — i.e. the country code, not the national 0 trunk prefix. Belgium: 324 + 8 digits, e.g. 32470123456; Netherlands: 316 + 8 digits, e.g. 31612345678.
detailsobjectrequiredProvider-specific donor details. The exact fields and validation depend on the eSIM variant. Fields that are accepted, required, or mutually exclusive are resolved from the selected eSIM's number-porting provider. Unknown fields are rejected.
Show propertiesHide properties
donorContractTypestringrequiredContract type of the number at the donor operator
prepaidpostpaiddonorIccidstringDonor SIM ICCID at the donor operator. Exact format is validated per eSIM variant.
donorAccountNumberstringAccount/customer number at the donor operator
Responses
201Profile created and eSIM successfully orderedapplication/jsonShow response bodyHide response body
dataobjectShow propertiesHide properties
profileReferencestringThe eSIM's profile reference for API access (16-digit numeric)
externalProfileIdstring | nullThe client's external profile ID if provided
esimReferencestringeSIM reference identifier (18-digit opaque token)
iccidstringThe eSIM's ICCID (needed for device installation)
activationCodestringLPA activation code for device installation
pin1stringPIN1 for the eSIM profile, as personalised by the manufacturer. Required to unlock the profile when SIM PIN is enabled on the device.
puk1stringPUK1 for the eSIM profile. Resets PIN1 after it has been entered incorrectly three times.
pin2stringPIN2 for the eSIM profile, guarding SIM service settings.
puk2stringPUK2 for the eSIM profile. Resets PIN2.
esimVariantstring | nullThe eSIM's variant (e.g. 'travel'), or null if it has none.
statusstringSM-DP+ profile state on the device.
released: Profile is available for download (QR code ready)downloaded: Profile has been downloaded to the deviceinstalled: Profile is installed on the eSIM chipenabled: Profile is active on the devicedisabled: Profile is installed but disabled on the devicedeleted: Profile has been removed from the devicefaulted: Profile encountered a provisioning or operational failure
releaseddownloadedinstalledenableddisableddeletedfaultedlifecycleStatusstring | nullIMSI connectivity lifecycle status. Null when the eSIM has not yet been assigned to a profile.
preactive: IMSI is provisioned but not yet active on the networkactive: IMSI is active and connected to the networksuspended: IMSI is temporarily suspended from the networkterminated: IMSI has been permanently terminatedfaulted: IMSI encountered a provisioning failurestale: IMSI has a configuration mismatch (e.g., wrong base plan)
preactiveactivesuspendedterminatedfaultedstalenullmsisdnsarray of objectPhone numbers (MSISDNs) attached to the eSIM. Only available for eSIM variants that include a phone number; empty for variants without one, and until a number is assigned during provisioning.
Show propertiesHide properties
msisdnstringrequiredPhone number in E.164 format without the leading +
primarybooleanrequiredWhether this is the eSIM's primary phone number
createdAtstring · date-timeportInobject | nullPresent when the order included a portIn block.
Show propertiesHide properties
portInRequestReferencestringrequiredPublic opaque port-in request reference (8-char uppercase base36)
statusstringrequiredrequested: Accepted by Firsty; provider submission in progressapproved: Donor/provider accepted the portscheduled: Port scheduled for a future date (reserved for future markets)cancelling: Cancellation requested, awaiting provider confirmationcompleted: Number ported — the eSIM activates with the ported numberrejected: Donor rejected the request (see reason)failed: Port failed (see reason)cancelled: Cancellation confirmed
requestedapprovedscheduledcancellingcompletedrejectedfailedcancelled404No available eSIM foundapplication/problem+jsonShow response bodyHide response body
typestring · urirequiredURI reference to error documentation
titlestringrequiredShort, consistent error summary
statusintegerrequiredHTTP status code
detailstringrequiredHuman-readable explanation specific to this occurrence
409Conflict - Request with this idempotency key is still being processed, or a profile with this externalProfileId already existsapplication/problem+jsonShow response bodyHide response body
typestring · urirequiredURI reference to error documentation
titlestringrequiredShort, consistent error summary
statusintegerrequiredHTTP status code
detailstringrequiredHuman-readable explanation specific to this occurrence
401Unauthorized - missing or invalid API key403Forbidden - client does not have access to this resource422Idempotency key was previously used with a different request body429Rate limit exceeded500Internal server error