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

Top-ups

A top-up adds a package to an eSIM your customer already has, so they do not need to install a new one. The price of the package is charged to your partner balance. eSIMify sends nothing to your customer about it.

Method Path What it does
GET /v1/esims/{iccid}/topup-packages List the packages this eSIM can be topped up with.
POST /v1/esims/{iccid}/topups Add one of those packages to the eSIM.
GET /v1/esims/{iccid}/topups List the top-ups of an eSIM, newest first.
GET /v1/topups/{id} Get one top-up.

Not every eSIM can be topped up. Always list the top-up packages for the eSIM before you offer one.

  • A top-up adds the package’s data and validity to the eSIM. GET /v1/esims/{iccid} shows the new data.total_mb, validity_days and expires_at at once.
  • A depleted eSIM becomes active again. A ready eSIM stays ready: its validity still starts on first use.
  • An expired or cancelled eSIM cannot be topped up.
  • A top-up can be completed, processing or failed. Check status in the response. A failed top-up added nothing, and the amount was returned to your balance. It is still answered with 201.
  • topup.completed is sent for a completed top-up. A failed one sends no event.
  • After a completed top-up, esim.usage_80 and esim.usage_100 can be sent again for the new allowance.
  • Top-ups are not orders. They are not in GET /v1/orders. List them with GET /v1/esims/{iccid}/topups.
  • While a top-up is running, the eSIM cannot be cancelled, and an eSIM that is being cancelled cannot be topped up.

GET /v1/esims/{iccid}/topup-packages

Returns the packages that can be added to this eSIM, with your price for each. The list is not paginated and holds at most 200 packages. An empty data array, or 409 esim_not_topupable, means there is nothing to offer.

Name In Type Required Description
iccid path string Yes The ICCID of the eSIM.
Terminal window
curl "$ESIMIFY_API_URL/v1/esims/8999999000000012345/topup-packages" \
-H "Authorization: Bearer $ESIMIFY_API_KEY"

200 OK with Package objects.

{
"data": [
{
"id": "pkg_10482",
"name": "Thailand 1 GB 7 days",
"type": "country",
"country": "TH",
"countries": [
"TH"
],
"data_mb": 1024,
"unlimited": false,
"validity_days": 7,
"price": {
"amount": "249.00",
"currency": "INR"
},
"retail_price": {
"amount": "349.00",
"currency": "INR"
},
"topup": true
}
]
}
Status Code When
404 esim_not_found No eSIM has this ICCID for your account in this mode.
409 esim_not_topupable The eSIM is expired or cancelled.

Any endpoint can also return the common errors.

POST /v1/esims/{iccid}/topups

Adds a package to the eSIM and charges its price to your balance.

Name In Type Required Description
iccid path string Yes The ICCID of the eSIM.
Idempotency-Key header string Yes 1 to 255 characters. Use a new one for each top-up. See Idempotency.
package_id body string Yes A package id from this eSIM’s top-up packages.
customer_ref body string No Your own reference for the top-up, up to 120 characters.
Terminal window
curl -X POST "$ESIMIFY_API_URL/v1/esims/8999999000000012345/topups" \
-H "Authorization: Bearer $ESIMIFY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: booking-84512-topup-1" \
-d '{
"package_id": "pkg_10482",
"customer_ref": "booking-84512-topup-1"
}'

201 Created with a Topup. A replay answers 200 OK.

{
"id": "top_test_7a1c9e02b4d6",
"status": "completed",
"iccid": "8999999000000012345",
"package_id": "pkg_10482",
"customer_ref": "booking-84512-topup-1",
"total": {
"amount": "249.00",
"currency": "INR"
},
"balance_after": {
"amount": "999502.00",
"currency": "INR"
},
"created": "2026-10-04T06:30:12Z"
}

Check status. completed means the data was added. failed means the mobile network provider did not apply the top-up: nothing was added and the amount was returned to your balance. processing means it is still being applied: fetch it again with GET /v1/topups/{id}.

Sending the same Idempotency-Key and body again returns the same top-up with the header Idempotent-Replayed: true. The data is added once. That is also true for a failed top-up: to try again, use a new Idempotency-Key.

A topup.completed webhook is sent when the top-up is done. Fetch the eSIM afterwards to see its new data values.

In the sandbox, the customer_ref triggers work on top-ups too.

Status Code When
400 invalid_request package_id is missing, customer_ref is longer than 120 characters or has control characters, or the body is not a JSON object. param names the field when one field is at fault.
400 idempotency_key_required A POST was sent without an Idempotency-Key header.
402 insufficient_balance Your balance does not cover the top-up. Nothing was added.
404 esim_not_found No eSIM has this ICCID for your account in this mode.
404 package_not_found package_id is not one of this eSIM’s top-up packages. That covers an id that does not exist, and a real package this eSIM cannot take.
409 esim_not_topupable The eSIM is expired or cancelled, or it is being cancelled.
409 idempotency_key_reused This Idempotency-Key was already used with a different request body.
409 request_in_progress A request with the same Idempotency-Key is still being processed. Wait a moment and send it again.
503 supplier_unavailable Sandbox only: returned for the test_supplier_down trigger. In live, a top-up the mobile network provider does not apply comes back as a Topup with the status failed.

Any endpoint can also return the common errors.

GET /v1/esims/{iccid}/topups

Returns every top-up of one eSIM, newest first, whatever its status. Use it to reconcile: a top-up whose response you lost is here.

Name In Type Required Description
iccid path string Yes The ICCID of the eSIM.
limit query integer No 1 to 100. Default 25.
cursor query string No The next_cursor of the previous page.
Terminal window
curl "$ESIMIFY_API_URL/v1/esims/8999999000000012345/topups?limit=10" \
-H "Authorization: Bearer $ESIMIFY_API_KEY"

200 OK with a list of Topup objects.

{
"data": [
{
"id": "top_test_7a1c9e02b4d6",
"status": "completed",
"iccid": "8999999000000012345",
"package_id": "pkg_10482",
"customer_ref": "booking-84512-topup-1",
"total": {
"amount": "249.00",
"currency": "INR"
},
"balance_after": {
"amount": "999502.00",
"currency": "INR"
},
"created": "2026-10-04T06:30:12Z"
}
],
"has_more": false,
"next_cursor": null
}
Status Code When
400 invalid_request limit or cursor is not valid. param names it.
404 esim_not_found No eSIM has this ICCID for your account in this mode.

Any endpoint can also return the common errors.

GET /v1/topups/{id}

Returns one top-up.

Name In Type Required Description
id path string Yes The top-up id, such as top_test_7a1c9e02b4d6.
Terminal window
curl "$ESIMIFY_API_URL/v1/topups/top_test_7a1c9e02b4d6" \
-H "Authorization: Bearer $ESIMIFY_API_KEY"

200 OK with a Topup.

{
"id": "top_test_7a1c9e02b4d6",
"status": "completed",
"iccid": "8999999000000012345",
"package_id": "pkg_10482",
"customer_ref": "booking-84512-topup-1",
"total": {
"amount": "249.00",
"currency": "INR"
},
"balance_after": {
"amount": "999502.00",
"currency": "INR"
},
"created": "2026-10-04T06:30:12Z"
}
Status Code When
404 topup_not_found No top-up has this id for your account in this mode. A live key cannot see sandbox top-ups, and a test key cannot see live ones.

Any endpoint can also return the common errors.