API ReferenceeSIM

Webhooks

How eSIM status and lifecycle events are surfaced - polling today, webhooks planned

eSIM order events (esim.delivered / esim.failed / esim.cancelled) fire at terminal status transitions, and lifecycle events (esim.installed / esim.activated / esim.depleted) fire as the eSIM is used. Each lifecycle event fires once, when the order genuinely transitions. Polling remains available as an alternative.

Tracking eSIM Status

1. Poll the order endpoint

GET /api/v1/esim/orders/:id refreshes installation status on every call for delivered-but-not-installed orders, and returns whatever's persisted otherwise.

# Initial fulfilment poll (10 minutes)
while true; do
  resp=$(curl -s "$HOST/api/v1/esim/orders/$ORDER_ID" \
    -H "Authorization: Bearer $TOKEN")
  status=$(echo "$resp" | jq -r '.data.status')
  case "$status" in
    DELIVERED|FAILED|CANCELLED) break ;;
  esac
  sleep 5
done

# Post-delivery install poll (next 10 minutes)
while true; do
  resp=$(curl -s "$HOST/api/v1/esim/orders/$ORDER_ID" \
    -H "Authorization: Bearer $TOKEN")
  installed=$(echo "$resp" | jq -r '.data.is_installed')
  [ "$installed" = "true" ] && break
  sleep 30
done

Two poll phases:

PhaseWatch forCadence
Fulfilmentstatus flips from PENDING to DELIVERED / FAILED / CANCELLED5–10s for the first minute, then 30s. An order that stays PENDING longer is Octopus Cards automatically retrying — it isn't stuck.
Installis_installed flips to true; activation_status to ACTIVE30–60s for the first 10 minutes, then back off

After 10 minutes uninstalled, stop the foreground install loop — the customer may install later, and you'd otherwise burn rate limits.

2. Attach a notification email

PATCH /api/v1/esim/orders/:id/notification-email attaches (or updates) an email address that is sent a templated receipt on terminal transitions — same pattern as topups and vouchers. Useful when the customer enters their email after placing the order, or when your UX can't render the eSIM details directly.

Webhook Events

The envelope matches the voucher webhook shape:

{
  "id": "evt_esim_abc123",
  "type": "esim.delivered",
  "created_at": "2026-05-15T14:30:32Z",
  "data": {
    "id": 9302481,
    "client_reference": "TRIP_TOKYO_OCT",
    "status": "DELIVERED",
    "activation_status": "NOT_INSTALLED",
    "product_name": "Japan eSIM",
    "country_code": "JPN",
    "data_amount_gb": 1.0,
    "validity_days": 7,
    "amount": 4.275,
    "currency": "USD",
    "iccid": "8910300000123456789"
  }
}

Expected event types:

EventTriggerStatus
esim.deliveredOrder moved to DELIVERED and an activation code is available. Payload does not include the activation_code — fetch the order to retrieve it.Live
esim.failedOrder moved to FAILED. Wallet auto-refunded. Includes failure_code / failure_reason / is_user_fixable.Live
esim.cancelledOrder cancelled administratively. Wallet refunded.Live
esim.installedCustomer's device downloaded the profile (installed_at set, activation_statusACTIVE). ICCID identifies the eSIM.Live
esim.activatedFirst data usage detected (activated_at set).Live
esim.depletedPlan validity expired or data quota exhausted (activation_statusEXPIRED).Live

Lifecycle events carry the same data shape as order events; the activation_status field reflects the new state (ACTIVE for installed/activated, EXPIRED for depleted). The order status stays DELIVERED throughout — the event type and activation_status convey the lifecycle change.

In-flight workflow stages do not fire client webhooks — only terminal status transitions do. status: PENDING is the entire intermediate state; granular fulfilment stages are intentionally not surfaced.

Activation Code Handling in Webhooks

The activation_code is never included in the webhook payload. Webhook payloads are written to logs and may be retried; including a single-use credential there would risk exposure. Pattern:

  1. Receive esim.delivered.
  2. Pull data.id (or data.client_reference).
  3. Call GET /esim/orders/:id over your authenticated channel.
  4. Render the LPA string / QR code immediately for the customer.
  5. Do not persist the activation code on your side beyond the install window.

This matches voucher webhooks, where order.delivered confirms delivery but the voucher codes themselves come from a follow-up GET /orders/:id.

For HMAC verification mechanics shared with outbound voucher webhooks, see Signature Verification.

On this page