# Webhooks Overview

> Overview of webhook behavior, delivery flow, retries, configuration in the dashboard, and the common request payload structure.


## Overview

Webhooks provide real-time notifications when significant state changes occur within the system. They enable external systems to react to updates without polling the API.

### Event Flow

1. **Trigger**: A webhook event is issued when a specific state change occurs.
2. **Payload**: The webhook is sent as a `POST` request to the configured endpoint with a JSON payload.
3. **Acceptance**: The receiving server must return an HTTP `2xx` status to confirm successful processing.
4. **Retry Mechanism**: If a non-`2xx` response is received, retries follow an exponential backoff strategy.

### Configuration

Webhooks can be configured via the dashboard. You can set the endpoint URL, select the events to subscribe to, and manage security settings.

---

## Webhook Structure

Each webhook request follows a consistent structure to ensure idempotency and compatibility across API versions.

```yaml
title: WebhookEvent
type: object
required:
  - id
  - api_version
  - type
  - data
properties:
  id:
    type: string
    example: "abcd1234"
    description: A unique identifier for the webhook event. Used for idempotency.
  api_version:
    type: string
    example: "1.0"
    description: The API version used for this webhook event.
  type:
    type: string
    enum:
    - account.low_balance
    - activation.updated
    - activation_report.updated
    - customer.low_balance
    - customer.updated
    - customer.activation.updated
    - customer.activation_report.updated
    - alternative.activation.updated
    example: activation.updated
    description: The type of webhook event.
  data:
    $ref: "#/components/schemas/EventData"
```

### Idempotency

The `id` field ensures that each event is uniquely identifiable. The receiver should ignore duplicate deliveries.

---

## Webhook Acceptance and Response

To confirm successful receipt of a webhook, the receiver must return an HTTP `2xx` status.
Failure to return a `2xx` response will trigger the retry mechanism.

---

## Delivery Retry Policy

If the initial webhook delivery fails, retries occur with exponential backoff:

| Attempt     | Delay       |
| ----------- | ----------- |
| 1st         | Immediately |
| 2nd         | 1 minute    |
| 3rd         | 5 minutes   |
| 4th         | 15 minutes  |
| 5th         | 1 hour      |
| 6th         | 6 hours     |
| 7th (final) | 24 hours    |

After the final attempt, the webhook is considered failed, and no further retries are made.

---

## Authenticity Verification

Each webhook request includes security headers for verification:

| Header         | Description                                                               |
| -------------- | ------------------------------------------------------------------------- |
| `x-webhook-id` | Unique identifier for the webhook setting.                                |
| `x-timestamp`  | UNIX timestamp of when the webhook was sent.                              |
| `x-signature`  | HMAC-SHA256 signature of the payload, used for authenticity verification. |

### Signature Calculation

To verify the authenticity of the webhook, compute the `HMAC-SHA256` signature using the `x-webhook-id`, `x-timestamp`, and the request body. The signature is included in the `x-signature` header.

The signature is calculated as follows:

```text
HMAC_SHA256(webhook_secret, x-timestamp + "\n" + request_body)
```

- Ensure `x-timestamp` is **a string** representing the UNIX timestamp.
- Use a **newline (`\n`) separator** between `x-timestamp` and `request_body` to avoid formatting issues.
- `request_body` must be the **exact JSON payload as sent**, encoded in UTF-8.

