1. Home
  2. Blog
  3. API & Integration
  4. eSIM API Error Handling and Idempotency: Never Double-Charge an Order
API & Integration

eSIM API Error Handling and Idempotency: Never Double-Charge an Order

Quick answer

eSIM API idempotency means sending a unique key with every order so a retried request returns the original order instead of buying a second eSIM. Combine it with timeouts, clear handling of balance and catalogue errors, webhooks and daily reconciliation, and your integration will never double-charge a customer. Fully Signal's REST API supports idempotent orders and a free sandbox to test every case.

In this article
  1. What is idempotency in an eSIM API?
  2. Rules for safe retries
  3. Error cases to handle
  4. Keep your catalogue fresh
  5. Use webhooks, not polling
  6. Reconcile daily
  7. Test every case in the sandbox
  8. Security checklist
  9. FAQ

An eSIM order spends real money from your balance. If your server times out and retries, you must not buy the same eSIM twice. This guide covers eSIM API idempotency and the error cases every integration should handle before going live.

What is idempotency in an eSIM API?

An operation is idempotent when doing it twice has the same effect as doing it once. For eSIM orders, you send a unique idempotency key (for example your own order ID) with the request. If the same key arrives again, the API returns the original result instead of creating a new order.

Without it, this happens:

  1. Your server sends "order 1 × Italy 5 GB".
  2. The order succeeds, but the response is lost to a network timeout.
  3. Your code retries.
  4. A second eSIM is bought and charged.

With an idempotency key, step 4 returns the eSIM from step 2.

Rules for safe retries

  • One key per customer order, generated before the first attempt and stored with the order.
  • Reuse the key on every retry of that order — never generate a new one inside the retry loop.
  • Retry only on network errors, timeouts and 5xx responses. A 4xx means the request itself is wrong; fix it rather than retrying.
  • Back off: wait 1s, 2s, 4s… with a cap, rather than retrying instantly.
  • Set a sensible timeout so a slow request does not hold your checkout forever.
order_key = "shop-order-10482"   # stored before the first call
for attempt in 1..5:
    response = POST /orders  {plan, quantity: 1}  Idempotency-Key: order_key
    if response.ok: save eSIM; break
    if response.status in 400..499: mark order failed; alert; break
    sleep(min(2 ** attempt, 30))

The exact header and endpoint names are in the API documentation inside the Fully Signal partner panel.

Error cases to handle

SituationWhat it meansWhat to do
Insufficient balanceYour prepaid balance cannot cover the orderStop, alert your team, show the customer a friendly delay message
Plan unavailableThe plan was changed or withdrawn from the catalogueRefresh your catalogue; offer the closest alternative
Invalid requestMissing or wrong fieldLog it and fix your code; do not retry
Authentication errorWrong, revoked or test-vs-live key mismatchCheck the key and IP allowlist
Timeout / 5xxTemporary problemRetry with the same idempotency key

Keep your catalogue fresh

Most "plan unavailable" errors come from stale catalogues. Sync the catalogue regularly through the API and check prices at checkout time rather than caching them for weeks. Fully Signal refreshes its catalogue continuously.

Use webhooks, not polling

After ordering, the eSIM moves through states (issued, installed, data used, expired). Subscribe to webhooks instead of polling status in a loop — see eSIM webhooks. Make your webhook handler idempotent too: the same event may arrive more than once, so store event IDs and ignore duplicates.

Reconcile daily

Once a day, compare:

  • Orders in your database
  • Orders in the partner panel / API order list
  • Balance movements on your statement

Any difference — an order you charged the customer for but never received, or the reverse — shows up within 24 hours instead of at month end.

Test every case in the sandbox

The free sandbox uses test keys and sample data, and nothing is charged, so you can force timeouts, retry with the same key, and confirm only one order exists. Our sandbox testing guide has a full test plan.

Security checklist

  • Separate test and live keys; never ship a live key in a mobile app
  • Scoped API keys with only the permissions each service needs
  • IP allowlists for your servers
  • Rotate keys when staff leave

FAQ

What is an idempotency key?

A unique value you send with a request so the server can recognise repeats. If the same key arrives twice, the server returns the first result instead of acting again.

When should I retry an eSIM order?

Only after network errors, timeouts or 5xx server errors, always with the same idempotency key and with increasing waits between attempts.

Should I retry a 4xx error?

No. A 4xx error means the request was rejected — for example invalid data or insufficient balance. Fix the cause first.

Can webhooks arrive twice?

Yes, webhook systems may deliver an event more than once. Store event IDs and ignore duplicates.

How do I test error handling without spending money?

Use the sandbox with test keys. Nothing is charged, so you can simulate retries and failures safely.

Guide eSIM API: for apps, websites and platforms B2B eSIM REST API: catalogue, orders, top-ups, refunds and eSIM status in 210+ countries, with webhooks, idempotency, scoped keys and a free sandbox. Read the guide
Fully Signal Team The Fully Signal team builds the white-label eSIM wholesale platform used by resellers, travel brands and apps to sell eSIM data in 210+ countries.