# Webhooks (/docs/plugins/webhooks)



The **Webhooks** plugin sends your booking events to another system the moment they happen. You register an HTTPS URL, tick the events you care about, and Resytech POSTs each one to it — a partner platform, your own back office, or anything that can accept an HTTPS request.

Every request is cryptographically signed so the receiver can prove it came from Resytech, failed deliveries are retried automatically for about 45 hours, and every attempt shows up in a delivery log you can inspect and resend from.

This is a **feature** plugin — there is nothing to connect and no credentials to enter. Install it, add an endpoint, and enable it.

<Callout type="info">
  This page covers setting webhooks up from the dashboard. If you're the developer **building the receiver**, see the [Webhooks developer reference](/docs/plugins/webhooks-reference) for the payload format, signature verification, retry schedule, and the full event catalog.
</Callout>

Setup [#setup]

1. Open **Plugins → Browse Plugins** and click **Install** on **Webhooks**.
2. On the setup page, add your first endpoint under **Configuration** (see below).
3. Copy the **signing secret** and give it to whoever runs the receiving system.
4. Click **Send test** to push a test event through the real signing and delivery path — confirm the receiver gets it before any real booking depends on it.
5. Click **Enable**. Events start flowing.

Webhooks is configured entirely from its setup page — it doesn't add a page of its own to the Plugins menu.

Adding an endpoint [#adding-an-endpoint]

An endpoint is one receiving URL plus the list of events it should get:

* **Endpoint URL** — must be HTTPS, and must be a publicly reachable address. Private or internal addresses are rejected.
* **Description*&#x2A; &#x2A;(optional)* — a note about what the URL is connected to.
* **Events to send** — tick only what the receiver actually needs. The event picker shows a sample payload for each type, so you can see exactly which fields will be sent.
* **Send events from all locations** — see [Scope](#scope) below.
* **Include customer contact details** — see [Customer contact details](#customer-contact-details) below.

You can add multiple endpoints — each has its own secret, its own event list, and its own delivery log.

Scope [#scope]

Each endpoint receives events from either **one location** or **every location in your company** — you choose when you create it. By default a new endpoint is scoped to the location you're working in; ticking **Send events from all locations** makes it company-wide, including locations you may not manage yourself. The endpoint list shows each endpoint's scope as a badge.

The signing secret [#the-signing-secret]

Every endpoint gets its own signing secret (it starts with `rwhk_`). Resytech signs every request with it, and the receiver uses it to verify authenticity — treat it like a password.

* **Reveal** — the secret stays retrievable, so an integrator who loses it can recover it without re-registering. Anyone with plugin-management access can reveal it.
* **Rotate** — generates a new secret. **The old secret stops working immediately** — there is no grace period where both are valid — so coordinate the swap with the receiver before rotating.

The delivery log [#the-delivery-log]

Expand **Recent deliveries** on any endpoint to see its recent events: the event type, delivery status, the HTTP response code, and when it happened. Each row shows the event's `evt_…` id with a copy button — that id is the handle to quote when troubleshooting with an integrator, and it stays the same across retries and resends.

A delivery is one of:

* **Succeeded** — the receiver answered with a 2xx response.
* **Retrying** — the last attempt failed; another is scheduled. Failed deliveries are retried up to 8 times over roughly 45 hours, with increasing gaps.
* **Exhausted** — every attempt failed. Nothing more will be sent automatically, but you can **Resend** it once the receiver is fixed.

**Resend** creates a fresh delivery of the same event (same `evt_` id, same payload). It's available on finished deliveries — succeeded or exhausted — and only while the endpoint is enabled.

When an endpoint keeps failing [#when-an-endpoint-keeps-failing]

Two protections stop a dead receiver from being hammered forever:

* If a receiver responds **410 Gone**, Resytech takes it at its word and disables the endpoint immediately.
* If **20 deliveries in a row** exhaust their retries without a single success, the endpoint is **automatically disabled**. Any successful delivery resets the count.

An auto-disabled endpoint shows as disabled in the endpoint list. Once the receiver is fixed, re-enable it — the failure count is cleared and delivery resumes with new events (past exhausted deliveries can be resent manually).

Customer contact details [#customer-contact-details]

By default, webhook payloads are **thin**: IDs, times, amounts, and statuses — no customer names, emails, or phone numbers. This is deliberate; the receiver can look further details up in Resytech if it needs them.

If the receiving system genuinely needs contact info (for example, a partner that must email the customer directly), tick **Include customer contact details** on the endpoint. Booking events then include the booking customer's name, email, and phone number.

<Callout type="warn">
  Enabling this shares your customers' contact details with the third party behind that URL. Only turn it on for receivers you trust with customer data, and only where they truly need it.
</Callout>

Disabling and removing [#disabling-and-removing]

* **Disabling an endpoint** stops its deliveries but keeps its configuration, secret, and log.
* **Disabling the plugin** stops all recording and delivery for the company; endpoints are preserved and everything resumes when you re-enable.
* **Removing an endpoint** deletes it. Its delivery history remains readable but nothing more is sent.

Permissions [#permissions]

Managing webhooks — adding endpoints, revealing or rotating secrets, resending deliveries — requires the **Plugins** permission (administrators have it automatically). There is no separate webhook permission: anyone who can manage plugins can see signing secrets and point company events at a new URL, so grant that permission accordingly.

Good to know [#good-to-know]

* Delivery is **at least once**: the same event can occasionally arrive twice (and always does after a resend). Receivers should treat the `evt_` id as an idempotency key — the [developer reference](/docs/plugins/webhooks-reference) covers this.
* Events are not guaranteed to arrive in order, especially when retries are involved.
* A **test event** (type `Webhook Test`) goes through the real signing and delivery path, and requires the endpoint to be enabled.
