Browse the docs
API

Webhooks

Get notified the moment a lead is created, an event is confirmed or an event changes stage.

A webhook is a URL on your side that VenueDB calls when something happens. Use them to post to a chat channel, update a CRM or start an automation without polling the API.

Set one up

  1. Sign in as the owner and open Settings → Webhooks.
  2. Add the URL, choose the events you want, and choose the format (below).
  3. Copy the signing secret shown after you save it. It is shown only once. You use it to verify that requests really came from VenueDB.

Events

EventFires when
lead.createdA lead is created in the app (new-lead form or inquiry capture). Leads created through the API or a CSV import do not fire this event.
event.confirmedAn event is confirmed.
event.stage_changedAn event moves to a different lifecycle stage.

A subscription can listen to specific events or to everything.

Formats

FormatSends
CustomA JSON envelope for your own code (below).
SlackSlack Block Kit messages, ready to post to an incoming-webhook URL.
DiscordDiscord embeds.
Google ChatGoogle Chat cards.

The Slack, Discord and Google Chat formats are designed to be pasted into those tools' incoming-webhook URLs. They can be customized in the webhook's template options.

The Custom payload

{
  "event": "event.stage_changed",
  "data": {
    "id": "ev_0042",
    "eventName": "Bennett–Sutton Wedding",
    "eventType": "wedding",
    "eventDate": "2027-05-15T21:30:00.000Z",
    "fromStage": "Tentative",
    "stage": "Definite",
    "lifecycle": "Long lead (over 6 months)",
    "venueId": "cm1…",
    "venueName": "Village Event Center"
  },
  "deliveredAt": "2026-10-06T14:05:31.000Z"
}

The data object differs per event:

lead.created — id, firstName, lastName, email, eventType, status, createdAt

event.confirmed — id, eventName, eventType, eventDate, guestCount, venueId, venueName

event.stage_changed — id, eventName, eventType, eventDate, fromStage, stage, lifecycle, venueId, venueName

Each request also carries these headers:

HeaderValue
X-VenueDB-EventThe event name, e.g. lead.created.
X-VenueDB-Signaturesha256= followed by the HMAC signature of the body.

Verify the signature

The signature is an HMAC-SHA256 of the raw request body using your signing secret, hex-encoded. Compute it yourself and compare it to the header. Always compare in constant time, and use the raw bytes — not a re-serialized copy of the JSON.

import crypto from "node:crypto";

function isFromVenueDB(rawBody, signatureHeader, secret) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Delivery and retries

  • Deliveries are sent in the background, so a slow or offline endpoint never slows down the action that triggered it.
  • Your endpoint should answer with a 2xx status within 10 seconds.
  • A failed delivery is retried up to 5 times with exponentially increasing delays.
  • Each attempt's result (status code and any error) is recorded and visible in the webhook's delivery history in Settings → Webhooks.

Because retries can deliver the same event more than once, make your handler idempotent: use the id in data (plus the event name) to ignore repeats.

Knowing when deliveries fail

You don't have to watch the delivery log. Each webhook's health is shown under Dashboard → Background jobs → Connections: three failed deliveries in a row marks it as a problem (one or two is a warning), and it recovers after two successes in a row. Owners, admins and managers are notified once when it breaks and once when it's working again. View deliveries takes you straight to the log.