Webhooks push JSON to any endpoint the moment something happens on your site — a form is submitted, content changes, a CRM contact is captured, an order is paid. Paste a Zapier, Make, or n8n catch-hook URL and your site becomes a trigger for thousands of downstream apps; point it at your own endpoint and the deliveries are HMAC-signed so you can verify every request. No code and no API tokens required.
What it does
- Event-driven JSON POSTs to any HTTPS endpoint you add, the instant the subscribed event fires on the site.
- Works with Zapier, Make, n8n, and home-grown automation: catch-hook style receivers work with zero setup; your own endpoints get an
X-Webprocms-Signatureheader to verify. - Per-endpoint event subscriptions: each webhook picks exactly the events it cares about, or
*for everything. - Send test: a one-click button fires a representative sample payload synchronously — so Zapier's "Test trigger" step has a request waiting the moment you switch tabs, with every field available for mapping. Sample keys mirror real deliveries exactly.
- Signed deliveries: every request carries
X-Webprocms-Signature: sha256=<hex>— an HMAC-SHA256 of the raw request body using the webhook's signing secret (shown once at creation). Catch-hook receivers can simply ignore it. - Retried and self-healing: non-2xx responses and transport errors retry up to 4 times with increasing backoff (1 min → 5 min → 30 min); an endpoint that fails 20 deliveries in a row is disabled automatically, and re-enabling it resets the failure budget.
- Observable: the endpoint list shows each webhook's status and last delivery; a per-webhook log keeps the 50 most recent deliveries with response codes (the dashboard shows the latest 10).
Turn it on under Settings → Features → Webhooks (off by default). Manage endpoints under Settings → Webhooks (admins only).
Events
| Event | Fires when |
|---|---|
content_item.created / content_item.updated / content_item.deleted |
A content item is created / updated / deleted |
form.submitted |
A (non-spam) form submission is received — public form or API |
crm.contact.created / crm.contact.updated |
A CRM contact is captured or changed |
subscriber.created / subscriber.unsubscribed |
A marketing subscriber signs up / unsubscribes |
order.created / order.paid / order.status_changed |
A shop order is created / becomes paid / changes status |
project.completed |
A tracked project is marked complete |
booking.created / booking.cancelled / booking.completed |
An appointment is confirmed / cancelled / completed |
restaurant_order.placed |
A restaurant order is placed (pay-at-store immediately, online orders on capture) |
ticket_order.paid |
An event ticket order completes payment |
donation.received |
A donation is paid, including recurring renewals |
invoice.paid |
A client invoice becomes paid |
ticket.created / ticket.closed |
A (non-spam) support ticket is opened / closed |
review.received |
A review lands from any source (synced or on-site form) |
directory_listing.paid |
A directory listing term or featured upgrade is paid for |
member.created / member.cancelled |
A member signs up / cancels |
Events fire regardless of how the change happened — dashboard edit, public form post, checkout, or API call.
Events only fire for add-ons that are turned on, because a disabled add-on never creates the records that trigger them. Every event has a representative sample payload behind the Send test button, so a catch-hook editor (Zapier's "Test trigger", Make, n8n) sees every mappable field before the first real delivery.
Delivery format
Each delivery POSTs a JSON envelope:
{
"event": "form.submitted",
"delivery_id": 123,
"timestamp": "2026-07-05T12:00:00+00:00",
"data": { "...": "same shape as the matching REST endpoint" }
}
The data payloads reuse the API feature's REST resource shapes, so an integration that reads the REST endpoints and one that listens to webhooks see identical fields. Deliveries also carry X-Webprocms-Event and X-Webprocms-Delivery headers, and queue after the database transaction commits — a rolled-back save never emits an event.
Using it with Zapier
- In Zapier, create a Zap with the trigger Webhooks by Zapier → Catch Hook.
- Copy the webhook URL Zapier shows and add it under Settings → Webhooks, picking the events you want.
- Click the Send test button so Zapier receives a sample request, then map its fields in your Zap.
Make, n8n, and anything else that accepts JSON POSTs work the same way.
Subscribing programmatically (REST hooks)
With the API feature also enabled, integrations can manage the same webhook rows over REST — the pattern Zapier-style platforms use to register triggers automatically:
| Endpoint | Ability |
|---|---|
GET /api/v1/webhooks |
webhooks:manage |
POST /api/v1/webhooks |
webhooks:manage |
DELETE /api/v1/webhooks/{id} |
webhooks:manage |
The create response is the only place the signing secret appears. These endpoints require both features: they 404 when either the API feature or the Webhooks feature is off.
Security notes
- Endpoints must be HTTPS; the signing secret lets receivers reject forged deliveries.
- Webhook management lives behind the admin role; managers and editors can't see or change endpoints.
- Disabling the feature 404s the settings page and stops all dispatch immediately; endpoint rows and delivery history are preserved for re-enable.