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

# Webhooks

> Receive signed HTTP callbacks when payments, paywalls, and services change in your account.

**Webhooks** push events to your server as they happen — payments, paywall and service changes — so you don't have to poll [Transactions](/dashboard/transactions) or [Events](/dashboard/events). Each delivery is a signed HTTP `POST` to an endpoint you control.

<Note>
  Webhooks are configured from the dashboard only. There is no API to create or manage endpoints.
</Note>

## Add an endpoint

In the dashboard, open **Webhooks** and click **Add endpoint**:

| Field              | Description                                                                                       |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| **Endpoint URL**   | The HTTPS URL Proceeds sends events to — for example `https://api.example.com/webhooks/proceeds`. |
| **Description**    | Optional label to identify the endpoint.                                                          |
| **Events to send** | The event types this endpoint receives. Use **Select all** or pick individually.                  |

You can configure up to **20 endpoints**. Each endpoint can subscribe to a different set of events.

## Events

Choose which events each endpoint receives:

| Group        | Event               | Fires when                                                        |
| ------------ | ------------------- | ----------------------------------------------------------------- |
| **Payments** | `payment.requested` | A `402` challenge was issued for a request.                       |
|              | `payment.pending`   | A payment attempt exists but isn't yet validated and proxied.     |
|              | `payment.succeeded` | A payment was validated and the request was proxied successfully. |
|              | `payment.failed`    | A payment or fulfillment failed.                                  |
| **Paywalls** | `paywall.created`   | A paywall was created.                                            |
|              | `paywall.updated`   | A paywall was updated.                                            |
|              | `paywall.deleted`   | A paywall was deleted.                                            |
| **Services** | `service.created`   | A service was created.                                            |

The payment events mirror [transaction state](/dashboard/transactions) and the [request lifecycle](/dashboard/events) — webhooks are the push-based equivalent.

## Verify each delivery

Every request includes an `X-Webhook-Signature` header. Each endpoint has its own signing secret (prefixed `whsec_`), shown in the endpoint list.

Before trusting a payload:

1. Read the `X-Webhook-Signature` header from the incoming request.
2. Compute the expected signature from the raw request body using your endpoint's `whsec_` secret.
3. Reject the request if the signatures don't match.

<Warning>
  Treat the `whsec_` secret like an API key — store it server-side and never expose it. Always verify the signature before acting on a webhook; never trust an unverified payload.
</Warning>

## Delivery and retries

Proceeds expects your endpoint to respond with a `2xx` status. If it doesn't, the delivery is retried — up to **3 attempts** per event.

Open an endpoint's **Recent deliveries** to inspect history:

| Column   | Meaning                                 |
| -------- | --------------------------------------- |
| Event    | The event type delivered.               |
| Status   | `Succeeded` or failed.                  |
| Code     | The HTTP status your endpoint returned. |
| Attempts | Delivery attempts used, out of 3.       |
| Time     | When the delivery was sent.             |
| Resend   | Manually replay the delivery.           |

## Manage endpoints

The Webhooks list shows each endpoint's **Status** (active or paused), subscribed **Events**, **Last delivery**, and signing **Secret**. From there you can pause, edit, or delete an endpoint.

## Best practices

* **Respond fast.** Return `2xx` immediately and process the event asynchronously so deliveries don't time out.
* **Verify the signature.** Always check `X-Webhook-Signature` before acting on a payload.
* **Be idempotent.** A retried or resent delivery can arrive more than once — de-duplicate on the event so repeats are safe.
* **Subscribe narrowly.** Only enable the events each endpoint actually needs.

<CardGroup cols={2}>
  <Card title="Transactions" icon="receipt" href="/dashboard/transactions">
    The payment state that `payment.*` events mirror.
  </Card>

  <Card title="Events" icon="list-timeline" href="/dashboard/events">
    The request lifecycle you can also inspect in the dashboard.
  </Card>
</CardGroup>
