Sandbox
The sandbox is the same API, used with a test key (sk_test_...). Paths, fields and errors are the same as live. No eSIM is bought from a mobile network provider, and your real balance is never touched. The Business portal labels this mode Test.
What works in the sandbox
Section titled “What works in the sandbox”- The catalogue returns the same packages and prices as live.
- Orders succeed immediately and return test eSIMs with ICCIDs, QR codes and activation details.
- Top-ups succeed on sandbox eSIMs and add the package’s data and validity. They can be listed and fetched like live ones.
- Webhooks are sent to your test-mode webhook endpoints.
GET /v1/eventslists your test events.
What is different
Section titled “What is different”- Sandbox eSIMs cannot be installed on a phone. The QR code is there so you can build and check your delivery screen.
- Sandbox ICCIDs start with
8999999, sandbox order ids start withord_test_and sandbox top-up ids withtop_test_. Activation strings look likeLPA:1$sandbox.esimify.in$TEST-A1B2C3D4E5F6. - Data usage and status do not change on their own. You change them with the simulate endpoint. The one exception: a sandbox eSIM whose
expires_athas passed reads asexpired. - The balance is virtual.
balance.lowuses the same threshold as live, the one you set in the portal under Settings. It is sent when a sandbox order or top-up takes the virtual balance below that threshold. No email is sent in the sandbox.- Sandbox orders, with their eSIMs and top-ups, are deleted 90 days after they were created.
- Sandbox orders and eSIMs are not shown on the Orders and eSIMs pages of the Business portal. Those pages show live data.
Virtual balance
Section titled “Virtual balance”Each partner account has a sandbox balance that starts at 1000000.00 INR. Sandbox orders and top-ups are charged to it, so balance_after and GET /v1/balance behave as they do in live.
When an order or top-up leaves the sandbox balance below 10000.00 INR, it is refilled to 1000000.00 INR automatically. You cannot run out by accident, and an order for 50 eSIMs of any package can be rehearsed. To test what happens when you do run out, use the trigger below.
Triggers
Section titled “Triggers”To test a failure, start the customer_ref of an order or a top-up with one of these values. Anything after the prefix is yours, so test_order_failed-booking-84512 works.
customer_ref starts with |
On an order | On a top-up |
|---|---|---|
test_insufficient_balance |
Refused with 402 and the code insufficient_balance. |
The same. |
test_order_failed |
Created with the status failed, and an order.failed webhook is sent. |
Created with the status failed. Nothing is added, nothing is charged and no webhook is sent. |
test_processing |
Comes back as processing. It completes 10 to 25 seconds later, and an order.completed webhook is sent. |
No effect. The top-up completes. |
test_supplier_down |
Refused with 503 and the code supplier_unavailable. |
The same. |
Any other customer_ref, or none, gives a completed order and an order.completed webhook.
curl -X POST "$ESIMIFY_API_URL/v1/orders" \ -H "Authorization: Bearer $ESIMIFY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: qa-processing-001" \ -d '{ "package_id": "pkg_10482", "customer_ref": "test_processing-qa-001" }'pkg_10482 is a sample id. Use a package id from your own catalogue. Change the Idempotency-Key each time you run a command again: the same key returns the first response and does nothing new.
There is no trigger for a partially_completed order. Test that case with your own code path: it is a completed order whose esims list is shorter than quantity.
Simulating eSIM events
Section titled “Simulating eSIM events”In live, an eSIM is activated when a traveller installs it and it connects, and its data runs down as they use it. In the sandbox you make those things happen yourself:
curl -X POST "$ESIMIFY_API_URL/v1/sandbox/esims/8999999000000012345/simulate" \ -H "Authorization: Bearer $ESIMIFY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: sim-usage80-001" \ -d '{ "event": "usage_80" }'event |
Works when the eSIM is | The eSIM becomes | Webhook sent |
|---|---|---|---|
activated |
ready |
active |
esim.activated |
usage_80 |
active |
active, with 80% of its data used |
esim.usage_80 |
usage_100 |
active |
depleted |
esim.usage_100 |
expired |
active or depleted |
expired |
esim.expired |
The events must come in the order a real eSIM would go through: activated first, then usage, then expired.
- An event that does not fit the eSIM’s status is refused with
409and the codeinvalid_state. Ausage_80on areadyeSIM is one example. AnexpiredeSIM takes no further events. - An event that changes nothing returns the eSIM as it is and sends no webhook. Sending
activatedtwice is one example. - Usage never goes down.
usage_80afterusage_100changes nothing. - A top-up on a
depletedeSIM makes itactiveagain, so the usage events can be simulated once more. - Usage events cannot be simulated for an unlimited eSIM. They answer
400.
The sandbox eSIM is updated to match, so fetching it afterwards shows the new state. The endpoint only exists for test keys. With a live key it answers 404. See the reference.
Isolation
Section titled “Isolation”The sandbox and live are kept fully apart.
- A test key never sees live orders, eSIMs, top-ups or events. A live key never sees sandbox ones. Asking for one with the wrong kind of key gives
404. - Sandbox orders never touch your real balance.
- Idempotency keys are separate in each mode.
- Webhook endpoints belong to one mode. A test-mode endpoint only receives test events.
Moving to live
Section titled “Moving to live”Replace the test key with your live key. Paths, fields and webhooks stay the same. Run the test plan and the Going live checklist first.
What you will meet in live and not in the sandbox:
- eSIM events arrive with a delay, and only while you have an enabled live endpoint. See eSIM events in live.
POST /v1/orderscan take up to about 20 seconds, and large orders can come back asprocessing.- A supplier failure shows as an order or top-up with the status
failed, not as503. balance.lowcomes with the low-balance email from the Business portal. The sandbox sends the event only.

