> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bondio.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Events

> Receive real-time events from Bondio at your server endpoint

A webhook allows you to receive certain events at a specified endpoint on your server, upon which you can take actions.

## Configuring a webhook

A webhook can be created from the Bondio portal by following these steps:

1. Go to the **webhooks** section on the sidebar
2. Click **New webhook** at the top right
3. Enter your server endpoint where you want to receive the webhook events
4. Click **Create**

## Sample event

```json theme={null}
{
  "type": "attachment.activated",
  "timestamp": 1730474606,
  "data": {
    "esim": "89928374298342734",
    "planId": "plan_rndmid12",
    "attachmentId": "pattch_3rnplcna"
  }
}
```

## Validating the webhook signature

Each webhook call generated from Bondio contains a unique signature header to authenticate the call. The webhook contains a header `bondio-signature`, which identifies the call signature for each user uniquely. To validate the signature, we have created an npm library: [@bondio/webhook-signature-validator](https://www.npmjs.com/package/@bondio/webhook-signature-validator)

```javascript theme={null}
import * as bondioSignatureValidator from '@bondio/webhook-signature-validator';

bondioSignatureValidator.validate(signature, signingKey, webhookDataObject);
```

| Field               | Description                                                                                                                          |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `signature`         | The header received in the `bondio-signature` field.                                                                                 |
| `signingKey`        | The key defined while registering the webhook URL on [dashboard.bondio.co/home/webhooks](https://dashboard.bondio.co/home/webhooks). |
| `webhookDataObject` | The JSON data received in the webhook call.                                                                                          |

## Event types

### Subscription (V1)

#### `subscription.activated`

Fired when a subscription is activated.

<ResponseField name="type" type="string" required>
  `subscription.activated`
</ResponseField>

<ResponseField name="subscriptionId" type="string" required>
  The ID of the subscription that was activated.
</ResponseField>

<ResponseField name="esimIccid" type="string" required>
  The ICCID used in the subscription.
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

```json Example theme={null}
{
  "type": "subscription.activated",
  "timestamp": 1730474606,
  "subscriptionId": "subs.dbrt3472j"
}
```

#### `subscription.allowance.thresholdBreached`

Fired when a usage threshold is breached on a subscription.

<ResponseField name="type" type="string" required>
  `subscription.allowance.thresholdBreached`
</ResponseField>

<ResponseField name="subscriptionId" type="string" required>
  The ID of the subscription whose threshold was breached.
</ResponseField>

<ResponseField name="breachedService" type="enum" required>
  The service where the threshold was breached: `data`, `voice`, or `sms`.
</ResponseField>

<ResponseField name="threshold" type="integer" required>
  The percentage threshold that was breached (e.g., `80`).
</ResponseField>

<ResponseField name="esimIccid" type="string" required>
  The ICCID used in the subscription.
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

```json Example theme={null}
{
  "type": "subscription.allowance.thresholdBreached",
  "timestamp": 1730474606,
  "subscriptionId": "subs.dbrt3472j",
  "breachedService": "data",
  "threshold": 80
}
```

### Subscription V2

#### `attachment.activated`

Fired when a plan attachment gets activated, regardless of activation type.

<ResponseField name="type" type="string" required>
  `attachment.activated`
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

<ResponseField name="data" type="object" required>
  <Expandable title="properties">
    <ResponseField name="esim" type="string" required>
      The eSIM ICCID.
    </ResponseField>

    <ResponseField name="plan" type="object" required>
      The plan object with `dataMegaBytes`, `periodDays`, `periodIterations`, `throttledSpeedKbps`, `coverageProfileId`, and `label`.
    </ResponseField>

    <ResponseField name="attachmentId" type="string" required>
      The ID of the plan attachment.
    </ResponseField>
  </Expandable>
</ResponseField>

```json Example theme={null}
{
  "type": "attachment.activated",
  "timestamp": 1730474606,
  "data": {
    "esim": "89928374298342734",
    "plan": {
      "dataMegaBytes": 1024,
      "periodDays": 1,
      "periodIterations": 7,
      "throttledSpeedKbps": 128,
      "coverageProfileId": "cvpr_j64hksfs",
      "label": "tau"
    },
    "attachmentId": "pattch_3rnplcna"
  }
}
```

#### `attachment.allowanceConsumed`

This event is sent at 50%, 80% & 100% of data usage on an attachment of a fixed-validity plan. No events are sent for recurring plans.

<Note>
  In cases where data consumption on the eSIM is very heavy (e.g., HD streaming), the system may skip sending the 50% or 80% usage events.
</Note>

<ResponseField name="type" type="string" required>
  `attachment.allowanceConsumed`
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

<ResponseField name="data" type="object" required>
  <Expandable title="properties">
    <ResponseField name="usagePercentage" type="number" required>
      The percentage of the allowance consumed (0–100).
    </ResponseField>

    <ResponseField name="dataUsageBytes" type="number" required>
      Total data usage in bytes.
    </ResponseField>

    <ResponseField name="esim" type="string" required>
      The eSIM ICCID.
    </ResponseField>

    <ResponseField name="plan" type="object">
      The plan object with `dataMegaBytes`, `periodDays`, `periodIterations`, `throttledSpeedKbps`, `coverageProfileId`, and `label`.
    </ResponseField>

    <ResponseField name="attachmentId" type="string" required>
      The ID of the plan attachment.
    </ResponseField>
  </Expandable>
</ResponseField>

```json Example theme={null}
{
  "type": "attachment.allowanceConsumed",
  "timestamp": 1730474606,
  "data": {
    "usagePercentage": 80,
    "dataUsageBytes": 1231230,
    "esim": "89123465789487473",
    "planId": "plan_dy393lsf2",
    "attachmentId": "ptac_lkajsdfkll"
  }
}
```

#### `subscriptionV2.esim.locationChanged`

Sent whenever a change in the country of an eSIM is detected.

<ResponseField name="type" type="string" required>
  `subscriptionV2.esim.locationChanged`
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

<ResponseField name="data" type="object" required>
  <Expandable title="properties">
    <ResponseField name="esim" type="string" required>
      The eSIM ICCID.
    </ResponseField>

    <ResponseField name="countryIso2" type="string" required>
      The ISO2 code of the new country.
    </ResponseField>
  </Expandable>
</ResponseField>

```json Example theme={null}
{
  "type": "subscriptionV2.esim.locationChanged",
  "timestamp": 1738678426,
  "data": {
    "esim": "8937204017177713446",
    "countryIso2": "IN"
  }
}
```

### eSIM

#### `esim.smdp.stateChanged`

Sent whenever the SMDP state of an eSIM is changed.

<ResponseField name="type" type="string" required>
  `esim.smdp.stateChanged`
</ResponseField>

<ResponseField name="timestamp" type="integer" required>
  The Unix timestamp at which this event was fired.
</ResponseField>

<ResponseField name="data" type="object" required>
  <Expandable title="properties">
    <ResponseField name="esim" type="string" required>
      The eSIM ICCID.
    </ResponseField>

    <ResponseField name="smdpStateChange" type="object" required>
      Contains `state` (e.g., `RELEASED`), `modifiedAt` (Unix timestamp), and `modificationResult` (e.g., `SUCCESS`).
    </ResponseField>
  </Expandable>
</ResponseField>

```json Example theme={null}
{
  "type": "esim.smdp.stateChanged",
  "timestamp": 1738678426,
  "data": {
    "esim": "8937204017177713446",
    "smdpStateChange": {
      "state": "RELEASED",
      "modifiedAt": 17892378963,
      "modificationResult": "SUCCESS"
    }
  }
}
```
