Skip to main content

Credentials and accounts

API key only. The paying account must be:
  • active, and debitable
  • one of your own — a customer wallet is refused
  • any currency you hold — unlike bill payments, nothing is restricted to one
Anything else is 409 esim_account_ineligible, one code for all three causes. There is no tier gate on eSIM. If your key works and you hold an eligible account, the service is available — subject to it being enabled on the deployment at all, which surfaces as 503 esim_feature_disabled.

The catalog

Synchronised from the network and cached by Sakawave, refreshed a few times a day. If it is empty when you call, Sakawave refreshes inline; if that fails you get 503 esim_catalog_unavailable. Cache it your side too. Re-read before quoting if your copy is more than an hour old — a plan withdrawn between your catalog read and your order produces 404 esim_package_unavailable.
Destination codes and plan slugs are stable in practice but not guaranteed. Store slugs against your own product records rather than treating them as permanent keys.

The quote window

A quote lasts about two minutes and is spent by the order that uses it.
One 409 esim_fx_quote_required covers every way a quote can be unusable: absent, expired, already spent, bound to a different account, or priced against a catalog figure that has since moved. In all of them the fix is the same — quote again, show the new figure, then buy.
Re-quoting silently and charging the new figure defeats the point. If the price moved, the customer agreed to the old one; show them the new one before you take the money.

Idempotency

externalReference is the key, unique per business. Reusing it returns the existing order whatever its status — including a failure. That is the same contract as transfers and bill payments, and deliberately not the re-driving one cards use. A genuine second attempt after a failure needs a fresh reference and a fresh quote. Sakawave also sends the network a deterministic identifier of its own, so a retry inside Sakawave — after a timeout, say — can never allocate two eSIMs for one order.

How failures return money

Nothing here requires you to claim a refund. Every refund returns exactly what was debited, in the currency it was debited in. Sakawave absorbs any rate movement in between rather than passing it on.

Provisioning and reconciliation

An order that comes back provisioning is being chased on your behalf. Sakawave asks the network on a short backoff for roughly two hours; if nothing resolves in that time the order fails and refunds itself. The network distinguishes “not yet” from “no”, and so does Sakawave. While a profile is still being generated the network answers “the batchOrder has been getting resource” — which is progress, not a failure, and does not end the order. Only an actual refusal does. You do not need to implement that loop. Take esim.order.completed and esim.order.failed, or poll the order while it is provisioning.

Assigning to a customer

Pass customerId on the order and the eSIM belongs to that customer. It changes nothing about who is billed — your account is still debited — but it lets you list a customer’s eSIMs, and it is what a support agent will search on.

Rate limits

SMS reaches a real handset, which is why it is the tightest. It is not a notification channel.