Webhooks Guide
Overview
Webhooks deliver real-time event notifications to your endpoint as things happen — data usage thresholds crossed, eSIMs installed or removed, packages activated, bookings approaching departure. Use them to trigger push notifications, update your CRM, or drive automated workflows.
Note: Webhook events are identical for both WebView and Native API integrations. The same events fire regardless of how the traveler interacts with their eSIM.
Setup
Contact support@hubbyesim.com to configure your webhook endpoint. You can register one URL per environment (staging and production).
Authentication
Every webhook request includes an x-api-key header with your configured API key. Verify this header matches your key before processing the payload.
Payload Format
All webhook payloads share a common envelope:
{
"event": "event.name",
"timestamp": "2026-07-15T14:30:00Z",
"data": { ... }
}| Field | Type | Description |
|---|---|---|
event | string | Event type identifier |
timestamp | string | ISO 8601 UTC timestamp of when the event occurred |
data | object | Event-specific payload |
Retry Policy
If your endpoint returns a non-2xx status code, Hubby retries the delivery up to 3 times with exponential backoff (1 min, 5 min, 30 min). After all retries are exhausted, the event is dropped.
Note: Design your webhook handler to be idempotent. The same event may be delivered more than once in edge cases.
Events
Package Usage
These events are emitted per package, not per eSIM. If a traveler has multiple packages on their universal eSIM, each package emits its own usage events independently. The package_id field identifies which package triggered the event.
For data-limited packages, events fire when data consumption crosses a threshold. For time-limited packages, the same events fire when the corresponding percentage of the package's duration has elapsed (e.g., package.usage.50_percent fires when half the validity period has passed).
Use these to send push notifications prompting top-ups before the package runs out.
package.usage.20_percent
{
"event": "package.usage.20_percent",
"timestamp": "2026-07-16T09:12:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"package_id": "pkg_xyz",
"destination": "GR",
"size": "1GB",
"package_type": "data-limited",
"used_bytes": 214748365,
"remaining_bytes": 858993459,
"usage_percent": 20
}
}package.usage.50_percent
{
"event": "package.usage.50_percent",
"timestamp": "2026-07-18T16:45:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"package_id": "pkg_xyz",
"destination": "GR",
"size": "1GB",
"package_type": "data-limited",
"used_bytes": 536870912,
"remaining_bytes": 536870912,
"usage_percent": 50
}
}package.usage.80_percent
{
"event": "package.usage.80_percent",
"timestamp": "2026-07-20T11:30:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"package_id": "pkg_xyz",
"destination": "GR",
"size": "1GB",
"package_type": "data-limited",
"used_bytes": 858993459,
"remaining_bytes": 214748365,
"usage_percent": 80
}
}Time-limited package example
For time-limited or unlimited packages, the same events fire based on duration elapsed instead of data consumed:
{
"event": "package.usage.80_percent",
"timestamp": "2026-08-10T16:00:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"package_id": "pkg_time_xyz",
"destination": "GR",
"package_type": "time-limited",
"duration_days": 30,
"elapsed_days": 24,
"remaining_days": 6,
"usage_percent": 80
}
}Tip: The 80% event is the most effective trigger for top-up conversion. A well-timed push notification at this point ("Running low on data in Greece — top up now" or "Your package expires in 6 days") drives significant revenue.
eSIM Status
Triggered when the eSIM's installation state changes on the traveler's device.
esim.installed
The traveler has successfully installed the eSIM on their device.
{
"event": "esim.installed",
"timestamp": "2026-07-14T18:20:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"iccid": "8901234567890123456"
}
}esim.removed
The traveler has removed the eSIM from their device.
{
"event": "esim.removed",
"timestamp": "2026-08-01T10:05:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"iccid": "8901234567890123456"
}
}Note: A removed eSIM can be re-installed. This event does not mean the traveler has lost access permanently.
Package Lifecycle
Triggered when a package changes state.
package.activated
A package has been activated and the traveler can now use data. This typically occurs when the traveler arrives at the destination and connects to a local network.
{
"event": "package.activated",
"timestamp": "2026-07-15T16:00:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"package_id": "pkg_xyz",
"destination": "GR",
"size": "1GB",
"activated_at": "2026-07-15T16:00:00Z",
"expires_at": "2027-07-15T16:00:00Z"
}
}Promo Code
promo_code.redeemed
Triggered when a traveler successfully redeems a promo code.
{
"event": "promo_code.redeemed",
"timestamp": "2026-07-10T12:00:00Z",
"data": {
"promocode": "SUMMER2026GR",
"booking_id": "booking_abc",
"redeemed_at": "2026-07-10T12:00:00Z"
}
}Booking Events
Triggered based on the booking's departure date and time. These are powered by the departure_date field you provide when creating a booking. Including a full datetime with timezone (e.g., 2026-07-15T14:30:00+02:00) enables precisely timed events.
booking.within_cutoff
The booking's departure date is now within the configured cutoff window (default: 7 days). Use this to trigger installation reminders — this is the optimal time for travelers to install their eSIM while still at home on Wi-Fi.
{
"event": "booking.within_cutoff",
"timestamp": "2026-07-08T08:00:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"departure_date": "2026-07-15T14:30:00+02:00",
"days_until_departure": 7,
"esim_installed": false
}
}Tip: The
esim_installedfield tells you whether the traveler has already installed their eSIM. Iffalse, this is the moment to send a push notification with installation instructions. Iftrue, you can skip it or send a "You're all set" confirmation instead.
booking.about_to_depart
The booking's departure is imminent (default: 2 hours before the time in departure_date). This is the last-chance reminder for travelers who haven't installed their eSIM yet.
{
"event": "booking.about_to_depart",
"timestamp": "2026-07-15T12:30:00Z",
"data": {
"external_user_id": "partner_user_456",
"booking_id": "booking_abc",
"departure_date": "2026-07-15T14:30:00+02:00",
"hours_until_departure": 2,
"esim_installed": false
}
}Note: This event requires a full datetime with timezone in
departure_date(e.g.,2026-07-15T14:30:00+02:00). If only a date was provided (e.g.,2026-07-15), this event cannot fire because the exact departure time is unknown.
Recommended Communication Strategy
Map webhook events to traveler-facing messages for maximum conversion:
| Event | Suggested action | Channel |
|---|---|---|
booking.within_cutoff (eSIM not installed) | "Your trip is in 7 days — install your eSIM now while you're on Wi-Fi" | Push notification, email |
booking.about_to_depart (eSIM not installed) | "Departing in 2 hours — install your eSIM before you board" | Push notification |
esim.installed | "You're all set! Your eSIM is ready for Greece" | Push notification |
package.activated | "Connected! You're using data in Greece" | Push notification (optional) |
package.usage.50_percent | "You've used half your data in Greece" or "Your package is halfway through its validity" | Push notification (optional) |
package.usage.80_percent | "Running low on data — top up now to stay connected" or "Your package expires in 6 days" | Push notification |
esim.removed | "eSIM removed — you can re-install anytime from the eSIM section" | Push notification (optional) |
Event Reference
| Event | Description |
|---|---|
package.usage.20_percent | 20% of package data consumed (data-limited) or 20% of package duration elapsed (time-limited) |
package.usage.50_percent | 50% of package data consumed or duration elapsed |
package.usage.80_percent | 80% of package data consumed or duration elapsed |
esim.installed | eSIM installed on the traveler's device |
esim.removed | eSIM removed from the traveler's device |
package.activated | Package activated and data is usable |
promo_code.redeemed | Promo code redeemed by a traveler |
booking.within_cutoff | Booking is within the departure cutoff window |
booking.about_to_depart | Departure is imminent (requires time + timezone in departure_date) |
Related
- The Hubby WebView — full WebView flow including
departure_date - Authentication guide — verify webhook signatures