Webhooks

Events and payloads

Register one HTTPS URL per environment in the portal and we POST a signed JSON envelope whenever something happens to your orders or eSIMs.

The envelope

http
POST https://your-app.example.com/hooks/journeystack
Content-Type: application/json
X-JourneyStack-Event: order.completed
X-JourneyStack-Timestamp: 1768383061
X-JourneyStack-Signature: sha256=6f1c…

{
  "id": "evt_9a3c7f1e0b2d4c6a8e5f1b3d",
  "event": "order.completed",
  "environment": "live",
  "created_at": "2026-01-14T09:31:03.402Z",
  "data": { "order": { "id": "b1f0a3c9-…", "status": "completed", "esims": [ … ] } }
}

Events

EventFires whenPayload
order.completedEvery eSIM on an order was issued successfully.data.order — the full order object, eSIMs included.
order.failedIssuing failed and your balance was refunded.data.order — the order with status: "failed" and an error message.
esim.activatedThe traveller installed the profile and it attached to a network.data.esim — the eSIM object.
esim.usage_alertA fixed plan crossed its usage threshold.data.esim plus data.used_bytes and data.total_bytes.
esim.expiredValidity ran out or the bundle was fully consumed.data.esim — the eSIM object.
wallet.low_balanceAfter an order, when the remaining balance is under three times that order's total.data.balance and data.currency.

Choosing events

By default you receive every event. You can narrow the list per environment in the portal — an empty selection means all events. Sandbox and live have separate URLs and separate secrets, so a test never reaches your production handler.

Webhooks are a notification, not a source of truth

Order completion is already in the response to your API call. Use webhooks for things you cannot see synchronously — activation, usage alerts, expiry and low balance — and always confirm against the API before acting on money.