Buvei
API ReferenceeSIM

Purchase eSIM

Buy an eSIM. Wallet is charged synchronously; issuance is asynchronous.

POST/open-api/v1/esim/purchase

Charges your project wallet at your catalog price and issues an eSIM. The request waits a few seconds for issuance: if the eSIM is ready in time you get ISSUED with iccid / qrCode directly; otherwise you get PAID — then rely on the ESIM_ISSUED webhook (recommended) or poll GET /esim/orders/{orderNo}.

If issuance ultimately cannot complete, the order is refunded in full and an ESIM_REFUNDED webhook fires. Insufficient wallet balance or an unavailable plan fails the request immediately with no charge.

Headers

X-Idempotency-Keystringheader

Strongly recommended. 1–64 chars [a-zA-Z0-9_-]. Same key + same body retried returns the same orderNo without a second charge. Same key + different body → 409. A definitively failed purchase is terminal for its key — retry with a new key. Without a key every call creates a new order (two calls = two eSIMs). Keys are durable and can be reconciled later via GET /operations/{idempotencyKey}.

Body

planNostringbodyrequired

Plan id (epln_...) from List eSIM Plans.

Response

orderNostring
Order id (eord_...) — keep it; it keys the webhook and the order lookup.
statusstring
ISSUED (done, iccid/qrCode present) or PAID (issuing — wait for webhook / poll).
iccidstring
null until issued.
qrCodestring
LPA install string. null until issued.
esimNostring
eSIM id (esim_...), null until issued — use it for usage lookup and recharge.
operationIdstring
Present only when X-Idempotency-Key was supplied.
Request
{ "planNo": "epln_b312537653c3a51f00" }
Response
{
  "code": 0,
  "message": "SUCCESS",
  "data": {
    "orderNo": "eord_9fec42a158b64f8ba4",
    "status": "ISSUED",
    "iccid": "8948010010043989416",
    "qrCode": "LPA:1$smdp.io$K2-XXXXXX-XXXXXXX",
    "esimNo": "esim_6ba300976dbb48b8a1",
    "operationId": "oaop_f208ddcc9ef2461dbf79"
  }
}
{
  "code": 409,
  "message": "Idempotency-Key 'your-key' was already used with a different request body"
}

Order lifecycle

PAID ──> ISSUING ──> ISSUED                       (terminal: iccid + qrCode available)
  │          │
  └──────────┴─────> FAILED ──> REFUNDED          (terminal: wallet refunded in full)

orderNo vs esimNo

orderNo (eord_...) identifies a transaction; esimNo (esim_...) identifies the eSIM itself. Every purchase and every recharge creates a new orderNo (think: receipt number), while the esimNo is created once at purchase and never changes (think: card number) — one eSIM accumulates many orders over its lifetime. Use orderNo to track the outcome of a payment you just made; use esimNo for everything about the card: usage lookup and recharge. Webhooks carry both, so you can tell which transaction completed and which eSIM it affected.