> For the complete documentation index, see [llms.txt](https://docs.peakcommerce.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peakcommerce.com/developers/api-reference/webhooks-overview.md).

# Webhooks overview

Webhooks let your systems react to events in your PeakCommerce tenant in near real time. This page is the developer reference; for the admin UI walk-through see the Webhooks page under **Settings → Developer Tools**. For the API to manage subscriptions see [API reference: webhook subscriptions](/developers/reference-pages/webhooks.md).

## Architecture

```
PeakCommerce
   │  (event happens)
   ▼
Webhook subscription      ── HMAC-signed POST ──▶ Your endpoint
   ▲                                                  │
   │                                       2xx within 10s
   │  (retry up to 5× on failure)                     ▼
   └────────────────────────────────────────  Delivered, recorded
```

## Delivery format

Each delivery is a `POST` with `Content-Type: application/json` and this body:

```json
{
  "event": "subscription.changed",
  "timestamp": "2026-05-02T14:01:23Z",
  "tenantId": "ten_01H...",
  "data": { /* the resource that changed */ }
}
```

Headers:

| Header                | Description                                                   |
| --------------------- | ------------------------------------------------------------- |
| `X-Webhook-Signature` | `sha256=<hex_hmac_sha256>` — HMAC of the raw body (see below) |
| `X-Webhook-Event`     | The event type (e.g. `subscription.changed`)                  |
| `X-Webhook-Timestamp` | ISO 8601 time of the event                                    |

## Signature verification

Each subscription has a signing secret, returned **once** when you create it (`POST /webhooks`) — store it securely; it is never shown again.

The signature is `HMAC-SHA256(secret, rawBody)`, hex-encoded, sent in `X-Webhook-Signature` with a `sha256=` prefix. Verify it over the **raw** request body (do not parse first), using a constant-time comparison:

```python
import hmac, hashlib

def verify(secret: str, signature_header: str, raw_body: bytes) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature_header, expected)
```

Reject any request whose signature does not match, and confirm the `tenantId` in the body matches the tenant you expect.

## Event types (selected)

The `event` field carries the event type. A selection:

| Event                                                                                            | When                            |
| ------------------------------------------------------------------------------------------------ | ------------------------------- |
| `account.created`, `account.updated`                                                             | Account CRUD                    |
| `subscription.created`, `subscription.changed`, `subscription.cancelled`, `subscription.renewed` | Subscription lifecycle          |
| `order.created`, `order.updated`                                                                 | Order lifecycle                 |
| `payment.session_created`, `payment.succeeded`, `payment.failed`                                 | Payment lifecycle               |
| `invoice.created`, `invoice.paid`, `invoice.failed`                                              | Invoice lifecycle               |
| `webhook.test`                                                                                   | Manually sent from the admin UI |

The complete, live list is in `GET /api/v1/manifest` under `capabilities.eventTypes`.

## Retries & dead-lettering

* A delivery succeeds on any `2xx` response within **10 seconds**.
* On failure (non-`2xx`, network error, or timeout) the delivery is retried up to **5 attempts total**, with exponential backoff of `2^attempt` seconds (≈2s, 4s, 8s, 16s between attempts).
* After the 5th failed attempt the delivery is marked **`dead_letter`** and recorded under **Admin → Webhooks → Deliveries**.
* List dead-lettered deliveries with `GET /api/v1/webhooks/{id}/deliveries?status=dead_letter`, and re-enqueue any of them with `POST /api/v1/webhooks/{id}/deliveries/{deliveryId}/replay`.

## Best practices

* **Respond quickly** — return a `2xx` within 10 seconds. Move slow work to a queue.
* **Be idempotent** — deliveries may be retried, so process the same event safely more than once.
* **Verify the signature on every request.**
* **Don't assume ordering** — events may arrive out of order; use the resource's own `updatedAt` / `timestamp` as your watermark.

## Related

* Webhooks (admin app: **Settings → Developer Tools → Webhooks**)
* [API reference: webhook subscriptions](/developers/reference-pages/webhooks.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.peakcommerce.com/developers/api-reference/webhooks-overview.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
