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

# Webhook events and payloads

> Reference for Blaaiz webhook event types and common payload structure

Use this page to quickly see which events Blaaiz emits and what every webhook payload contains.

## Event types

Your business has two webhook URLs: `collection_url` and `payout_url`. The table below shows every event and which URL it is delivered to.

| Event                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                  | Delivered to     | Guide                                               |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------------------------------------------------- |
| `collection.initiated`     | Collection request created                                                                                                                                                                                                                                                                                                                                                                                                   | `collection_url` | [Collection](/guides/webhooks/collection/ngn)       |
| `collection.pending`       | Awaiting customer payment                                                                                                                                                                                                                                                                                                                                                                                                    | `collection_url` | [Collection](/guides/webhooks/collection/ngn)       |
| `collection.completed`     | Payment received successfully                                                                                                                                                                                                                                                                                                                                                                                                | `collection_url` | [Collection](/guides/webhooks/collection/ngn)       |
| `collection.failed`        | Payment failed                                                                                                                                                                                                                                                                                                                                                                                                               | `collection_url` | [Collection](/guides/webhooks/collection/ngn)       |
| `payout.initiated`         | Payout has been created                                                                                                                                                                                                                                                                                                                                                                                                      | `payout_url`     | [Payout](/guides/webhooks/payout/ngn)               |
| `payout.processing`        | Payout is being processed                                                                                                                                                                                                                                                                                                                                                                                                    | `payout_url`     | [Payout](/guides/webhooks/payout/ngn)               |
| `payout.completed`         | Payout completed successfully                                                                                                                                                                                                                                                                                                                                                                                                | `payout_url`     | [Payout](/guides/webhooks/payout/ngn)               |
| `payout.failed`            | Payout failed                                                                                                                                                                                                                                                                                                                                                                                                                | `payout_url`     | [Payout](/guides/webhooks/payout/ngn)               |
| `customer.status_changed`  | Customer's `verification_status` transitioned. The single event covers all customer-level transitions for both KYC (individual) and KYB (business): inspect `old_status` and `new_status` on the payload to know which way it moved. The legacy event labels `customer.verified` and `customer.rejected` are still mentioned in this guide for clarity, but the wire `event_type` value is always `customer.status_changed`. | `collection_url` | [Customer](/guides/webhooks/customer)               |
| `virtual_account.created`  | Virtual account created                                                                                                                                                                                                                                                                                                                                                                                                      | `collection_url` | [Virtual account](/guides/webhooks/virtual-account) |
| `virtual_account.ready`    | Virtual account ready to receive funds                                                                                                                                                                                                                                                                                                                                                                                       | `collection_url` | [Virtual account](/guides/webhooks/virtual-account) |
| `virtual_account.rejected` | Virtual account verification rejected                                                                                                                                                                                                                                                                                                                                                                                        | `collection_url` | [Virtual account](/guides/webhooks/virtual-account) |
| `virtual_account.failed`   | Virtual account creation failed                                                                                                                                                                                                                                                                                                                                                                                              | `collection_url` | [Virtual account](/guides/webhooks/virtual-account) |
| `virtual_account.credited` | Funds received in virtual account                                                                                                                                                                                                                                                                                                                                                                                            | `collection_url` | [Virtual account](/guides/webhooks/virtual-account) |

<Note>
  All events except payout events are delivered to your `collection_url`. Register both URLs via the [Webhook API](/api-reference/webhook/register).
</Note>

## Payload structure

All webhook payloads include:

* `event` — The event type
* `data` — The event data object
* `timestamp` — When the event occurred
* `signature` — HMAC signature for verification (header: `x-blaaiz-signature`)

> Always verify the `x-blaaiz-signature` using your webhook `signing_secret` to ensure the webhook originates from Blaaiz.

## Webhook retries

We retry deliveries with exponential backoff and jitter to avoid thundering herds.

* Attempts: up to 10 total
* Initial backoff: 5 minutes
* Backoff factor: 2x per attempt
* Max backoff cap: 24 hours (1440 minutes)
* Jitter: 80–120% randomization on each delay
* Success: any HTTP 2xx response stops retries
* Any non-2xx (4xx/5xx/timeout/connection error) triggers the next retry

Approximate schedule (actual delays vary ±20% because of jitter):

| Attempt | Approx. delay  | Cumulative time |
| ------- | -------------- | --------------- |
| 1       | Immediate      | 0               |
| 2       | \~5 minutes    | \~5 min         |
| 3       | \~10 minutes   | \~15 min        |
| 4       | \~20 minutes   | \~35 min        |
| 5       | \~40 minutes   | \~1.25 hours    |
| 6       | \~80 minutes   | \~2.5 hours     |
| 7       | \~160 minutes  | \~5 hours       |
| 8       | \~320 minutes  | \~10 hours      |
| 9       | \~640 minutes  | \~21 hours      |
| 10      | \~1280 minutes | \~42 hours      |

After 10 failed attempts, the webhook is marked permanently failed and no further automatic retries occur. You can manually replay via the API.

> ⚙️ Best practices
>
> * Reply with a 2xx quickly (within 30 seconds) and process work asynchronously if needed.
> * Implement idempotency using the `event_id` so duplicate deliveries don’t double-process work.
> * Return non-2xx only when you truly want a retry.

## Data retention

Webhook logs (payloads, responses, attempt history) are retained for **90 days**. After 90 days, records are pruned for both successful and failed deliveries.

* If you need webhook data beyond 90 days, store it in your own systems.
* Replay is only available for webhooks within the 90-day window.
