Skip to content
Preview. The Partners API is not live yet, so details on this page can change before launch.

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.

  • 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/events lists your test events.
  • 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 with ord_test_ and sandbox top-up ids with top_test_. Activation strings look like LPA: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_at has passed reads as expired.
  • The balance is virtual.
  • balance.low uses 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.

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.

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.

Terminal window
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.

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:

Terminal window
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 409 and the code invalid_state. A usage_80 on a ready eSIM is one example. An expired eSIM takes no further events.
  • An event that changes nothing returns the eSIM as it is and sends no webhook. Sending activated twice is one example.
  • Usage never goes down. usage_80 after usage_100 changes nothing.
  • A top-up on a depleted eSIM makes it active again, 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.

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.

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/orders can take up to about 20 seconds, and large orders can come back as processing.
  • A supplier failure shows as an order or top-up with the status failed, not as 503.
  • balance.low comes with the low-balance email from the Business portal. The sandbox sends the event only.