Packages
Order a package
Orders a package for an eSIM. Each package plan is specific to a region and has a recurring setting (one-time or auto-renewing). A successful response confirms the order and returns its stable package reference. The package may become usable asynchronously; the reference remains unchanged across retries. The package.created webhook confirms acceptance; package.activated confirms the package is usable. An order on a suspended eSIM reactivates it, reported by esim.lifecycle.activated. An order on a terminated eSIM is refused.
/profiles/{profileReference}/esims/{esimReference}/packagesAuthorization
Authorization: Bearer {token} — an OAuth2 access token from the client-credentials flow. How authentication works
Path parameters
profileReferencestringrequiredThe eSIM's profile reference (16-digit numeric string)
esimReferencestringrequiredeSIM reference identifier (18-digit opaque token)
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 by their JSON content. Object key order, including in nested objects, and whitespace do not affect matching. 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 request body matching
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 · required
planReferencestringrequiredPlan reference identifier (14-character opaque token)
externalTransactionIdstringOptional client-provided external transaction ID to associate with this package.
Responses
200Package order acceptedapplication/jsonShow response bodyHide response body
dataobjectoptionalShow propertiesHide properties
packageReferencestringPackage reference identifier (23-character opaque token)
externalTransactionIdstring | nullThe client's external transaction ID if provided
profileReferencestringexternalProfileIdstring | nullThe client's external profile ID if provided
esimReferencestringeSIM reference identifier (18-digit opaque token)
iccidstringplanReferencestringPlan reference identifier (14-character opaque token)
typestringExtensible enum. Package type: data for mobile data, sms for text messaging, voice for calls.
datasmsvoicecountryCodestringstatusstringPending means the order is accepted but not yet fully confirmed. Active means all required addons are confirmed. Legacy compatibility can represent pending packages as active and include them in active-filter results; webhook milestones remain the same.
pendingactivethrottledexhaustedexpiredremovedrecurringbooleanWhether this package will auto-renew
activatedAtstring | null · date-timeexpiresAtstring | null · date-time400Invalid request or package cannot be ordered for this regionapplication/problem+jsonShow response bodyHide response body
typestring · uriURI reference to error documentation
titlestringShort, consistent error summary
statusintegerHTTP status code
detailstringHuman-readable explanation specific to this occurrence
codestringExtensible enum. Machine-readable error slug. This is the field clients should branch on. The URI in type documents the code. Handle an unknown code by its HTTP status.
bad_requestvalidation_failedunauthorizedpayment_requiredfeature_not_enabledforbiddenbalance_not_foundesim_not_foundnot_foundnumber_registration_not_foundport_in_not_foundprofile_not_foundscheduled_action_not_foundsubscription_not_foundsubscription_plan_not_foundwebhook_endpoint_not_foundbalance_not_availablebalance_update_pendingconcurrent_modificationconflictesim_change_pendingesim_not_activeesim_not_provisionedesim_suspendedesim_swap_cooldownesim_swap_pendingesim_terminatedinvalid_state_transitionlimit_reachedno_esim_availablenumber_registration_pendingport_in_pendingservices_change_pendingservices_not_availablebalance_not_supportedbalance_operation_not_supportedbalance_update_refusedclient_transaction_id_reusedesim_variant_not_allowedesim_variant_not_swappableidempotency_key_reusedinsufficient_balancenumber_not_availablenumber_registration_not_supportedport_in_cancel_refusedporting_not_supportedservices_change_refusedservices_not_changeableservices_not_supportedsim_refused_by_networkunprocessable_entitylockedrate_limit_exceededinternal_errorbad_gatewayservice_unavailable409The eSIM cannot take this package nowapplication/problem+jsonShow response bodyHide response body
typestring · uriURI reference to error documentation
titlestringShort, consistent error summary
statusintegerHTTP status code
detailstringHuman-readable explanation specific to this occurrence
codestringExtensible enum. Machine-readable error slug. This is the field clients should branch on. The URI in type documents the code. Handle an unknown code by its HTTP status.
bad_requestvalidation_failedunauthorizedpayment_requiredfeature_not_enabledforbiddenbalance_not_foundesim_not_foundnot_foundnumber_registration_not_foundport_in_not_foundprofile_not_foundscheduled_action_not_foundsubscription_not_foundsubscription_plan_not_foundwebhook_endpoint_not_foundbalance_not_availablebalance_update_pendingconcurrent_modificationconflictesim_change_pendingesim_not_activeesim_not_provisionedesim_suspendedesim_swap_cooldownesim_swap_pendingesim_terminatedinvalid_state_transitionlimit_reachedno_esim_availablenumber_registration_pendingport_in_pendingservices_change_pendingservices_not_availablebalance_not_supportedbalance_operation_not_supportedbalance_update_refusedclient_transaction_id_reusedesim_variant_not_allowedesim_variant_not_swappableidempotency_key_reusedinsufficient_balancenumber_not_availablenumber_registration_not_supportedport_in_cancel_refusedporting_not_supportedservices_change_refusedservices_not_changeableservices_not_supportedsim_refused_by_networkunprocessable_entitylockedrate_limit_exceededinternal_errorbad_gatewayservice_unavailable401Unauthorized - missing or invalid API key403Forbidden - client does not have access to this resource404Resource not found422Idempotency key was previously used with a different request body429Rate limit exceeded. A `429` can also arrive without these headers or this body; handle it by its status code.500Internal server error503Service temporarily unavailable. Safe to retry.