Why two-step eSIM provisioning beats single-call APIs
Bundled provisioning APIs feel simpler. They are worse in production. Here is why separating eSIM creation from package ordering matters.
Why two-step eSIM provisioning beats single-call APIs
When you compare eSIM APIs, you'll see two architectural patterns. Bundled: one API call creates the eSIM and attaches a plan in a single operation. Split: one call creates the eSIM, a separate call attaches a package.
Bundled looks simpler. It's worse in production. Here's why.
What the calls look like
Bundled (the Airalo, eSIM Go, eSIM Access pattern):
httpPOST /api/esims { "country": "DE", "dataAmount": "3GB", "duration": 30 } Response: { iccid, activationCode, planDetails }
Split (Firsty's pattern):
httpPOST /api/v3/esims {} Response: { data: { profileReference: "1234567890123456", esimReference: "123456000000000001", iccid: "89012345678901234567", activationCode: "LPA:1$provider.example.com$..." } } POST /api/v3/profiles/{profileRef}/esims/{esimRef}/packages { "planReference": "C123456XYZDUSR" } Response: 200 OK with packageReference
On the surface, bundled wins on simplicity. You're done in one HTTP call instead of two. Why would anyone choose the extra round trip?
Reason 1: Different operations, different failure modes
Try it yourself
Free sandbox. Real Tier-1 carriers. 60 seconds from signup to credentials.
Get started →eSIM creation and package ordering fail in different ways.
eSIM creation involves the carrier's HLR/HSS (the database that tracks SIMs on a mobile network). Failures here are slow (multi-second timeouts), rare, and require carrier-side intervention to retry.
Package ordering is a lighter operation on the eSIM provider's side. Failures are faster, more common (plan availability, rate limits), and usually self-recoverable.
In bundled APIs, when something fails, you don't know which part broke. Was your customer's SIM created with the wrong plan? With no plan? Not created at all? You have to retry the whole thing, including the slow carrier-side operation. If the SIM was created successfully but plan attachment failed, retry creates a duplicate SIM.
In split, the failure modes are explicit. eSIM creation failed? Retry that. Package ordering failed? Retry just the package ordering against the existing eSIM. You don't burn carrier resources on retries that didn't need to retry that part.
Reason 2: Pre-provisioning patterns
Some real-world flows want to provision SIMs before knowing which plan they'll use.
Travel app at checkout: customer books a hotel in Tokyo. You could:
- (a) Provision the SIM now with a Japan plan, hope they don't cancel
- (b) Wait until departure to provision, risking last-minute carrier issues
Split enables option (c): provision the eSIM now with no package attached. Attach the right package 24 hours before departure when the customer confirms their travel dates. The customer's QR code is ready, they're confident their connectivity is set up, but you didn't commit to a plan until you had to.
Reseller inventory model: a corporate travel manager wants 50 eSIMs ready for their team's upcoming trips. With split, you provision the 50 eSIMs now and attach packages as employees confirm destinations.
Bundled APIs can't do this. You must commit to a plan at provisioning time.
Reason 3: Plan changes mid-cycle
What happens when a customer wants to upgrade their data package mid-month?
Split makes this trivial: order a new package on the existing eSIM. The new package becomes active when the old one expires (or immediately, depending on configuration).
Bundled APIs usually treat each "purchase" as a separate SIM operation. Upgrading requires deactivating the old SIM and creating a new one, which means a new QR code, a new installation, and a confused customer.
Reason 4: Package history and lifecycle
Each eSIM in Firsty can have multiple packages over its lifetime. You can list them via
GET /profiles/{ref}/esims/{ref}/packages/historyThis kind of history tracking only makes sense when packages are separable from the eSIM. In bundled APIs, the eSIM and the package are conceptually one thing, so history is just a list of SIMs.
When bundled is acceptable
Bundled APIs work fine for one-shot consumer flows where the customer chooses a plan, pays, and installs immediately. Most travel eSIM consumer apps use bundled patterns because that's all their flow needs.
Once you're building anything more complex (B2B resellers, corporate fleets, IoT, multi-stop trips), the limitations of bundled become real costs.
The cost of split
To be fair, split has costs:
- One extra HTTP request per provisioning (mostly negligible: about 100ms)
- More state to track (profileReference, esimReference, and packageReference)
- Tutorials are slightly longer (two API calls instead of one)
These are real but small costs. They're paid once during development. The benefits of split accrue every day in production.
How to choose
If you're building:
- A simple consumer travel app: either pattern works, bundled is slightly simpler
- A B2B integration: split is significantly better
- A reseller platform: split is required
- An IoT fleet system: split is required
- Anything with bulk operations: split is required
If you have any chance of growing into a more complex flow, start with a split API. Migrating from bundled to split later is painful because every existing SIM in your database uses the bundled data model.
Firsty's stance
We chose split. We think it's the right default for a developer-first eSIM platform. The API has more endpoints, but each endpoint does one thing well.
If you want to see it in action, our first eSIM tutorial walks through the full flow.
Related guides
MVNO, MVNE, MVNA: who does what and which one do you actually need?
The telecom acronyms decoded. When you need a network agreement, when you do not, and the cheapest path to launch your own mobile brand.
How to provision your first eSIM via API in 30 minutes
From OAuth token to first eSIM activated, with QR code generation server-side. Real code, real credentials, real eSIM, in about 30 minutes.
OAuth2 client credentials in production: what most tutorials get wrong
Token caching, refresh strategy, and the security mistakes we see in production integrations every week.