---
title: "Webhooks"
space: "Frappe Framework"
url: "https://www.prilk.com/docs/frappe-framework/webhooks"
updated: "2026-05-14"
---

## Webhooks

A Webhook is an outbound HTTP request Frappe makes when a document event happens. Use to notify external systems — Slack, custom services, integrations — without polling.

### Setting one up
Open **Webhook → New**:

| Field | Example |
|---|---|
| Webhook DocType | Sales Invoice |
| Webhook DocEvent | After Submit |
| Request URL | https://hooks.slack.com/services/T0/B0/XYZ |
| Request Method | POST |
| Request Structure | Form URL-Encoded / JSON |
| Condition | doc.grand_total > 10000 (optional) |

### Payload
Default body is the document as JSON. To customize, add **Webhook Data** rows mapping fields to your desired keys — useful when the receiving system expects a specific shape (Slack messages, custom API formats).

For full control, use **Webhook → Request Body Template** with Jinja:

```json
{
    "channel": "#sales",
    "text": "Invoice {{ doc.name }} for {{ doc.customer_name }} totaling {{ doc.grand_total }} just submitted."
}
```

### Headers
Add Authorization, content-type, or custom headers in **Webhook Headers**. Bearer tokens go here.

### Failures and retries
Frappe logs each call to **Webhook Request Log** with status code and response. Failures don't retry automatically — review the log and trigger manually, or set up your own retry logic in the receiving system.

### Security
- Webhook URLs are stored encrypted on disk if they contain secrets in query strings.
- For incoming webhooks (Mollie, GoCardless, PEPPOL), use dedicated webhook receiver endpoints — see the relevant integration's docs.

### When to use the API instead
Webhooks push notifications to you. The API lets a consumer pull data on demand. Pick the one matching your direction.
