Skip to content

Webhooks ​

Webhooks tell your own system the moment something happens in Propool, such as a new lead or a new booking, by sending it an HTTPS request. Use them instead of checking the API over and over.

Events ​

EventWhenData
lead.createdA lead is created, from the app, the API, an import or an integrationid, reference, pipelineId, stageId, resourceUrl
lead.stage_changedA lead moves to a different stageThe same, plus previousStageId; stageId is the new stage
booking.createdA booking first appears in Propool, from a channel, your website, a manual entry or an importid, listingId, status, arrival, departure, source, imported, resourceUrl
webhook.testYou choose Send testA message; nothing is created

Changes to an existing booking don't send another booking.created. Calendar blocks and unconfirmed website requests aren't bookings.

Events carry no names, contact details, notes or amounts. To get the full record, call its resourceUrl on https://app.propool.ai with an API key that has leads:read or bookings:read.

Add an endpoint ​

Only admins can manage webhooks.

  1. Go to Settings → Webhooks and choose Add endpoint.
  2. Enter your callback URL: a public https:// address on port 443. Private networks and redirects are refused.
  3. Choose the events to send.
  4. Copy the signing secret. It starts with pwhsec_ and is shown only once.
  5. Choose Send test, then check the delivery history for your server's response.

A workspace can have up to 25 endpoints. A new endpoint receives events from then on, not earlier ones.

What you receive ​

Each event is a POST with a JSON body:

json
{
  "id": "ac757ca0-6323-47f1-9b6d-5d2d278bc187",
  "type": "lead.created",
  "occurredAt": "2026-10-04T12:00:00.000Z",
  "schemaVersion": "2026-10-01",
  "workspaceId": "ae81317d-e699-45e7-a67b-de2ac3b1d729",
  "data": {
    "id": "dc16af64-55bd-4476-a5cc-c9ea570d60be",
    "reference": "L-1042",
    "pipelineId": "018f3191-c4af-4e08-bd54-d75b3df75cd6",
    "stageId": "07fd8a32-01a6-4c90-8810-c2d38726283c",
    "resourceUrl": "/api/public/v1/pipelines/018f3191-c4af-4e08-bd54-d75b3df75cd6/leads/dc16af64-55bd-4476-a5cc-c9ea570d60be"
  }
}

and these headers:

text
X-Propool-Event-Id: <event ID>
X-Propool-Delivery-Id: <delivery ID>
X-Propool-Timestamp: <Unix seconds>
X-Propool-Signature: v1=<hex HMAC-SHA256>

New fields may be added to events, so ignore fields you don't recognise.

Check the signature ​

Anyone can send a request to your URL, so check every one came from Propool before you trust it. The signature is an HMAC-SHA256 of the timestamp, a ., and the raw request body, using your whole signing secret (including pwhsec_) as the key.

js
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, timestamp, signature, secret) {
  if (!/^\d{10,12}$/.test(timestamp ?? "")) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  if (!/^v1=[a-f0-9]{64}$/.test(signature ?? "")) return false;
  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.`)
    .update(rawBody)
    .digest();
  const actual = Buffer.from(signature.slice(3), "hex");
  return actual.length === expected.length && timingSafeEqual(actual, expected);
}
  • Check before parsing the JSON. Parsing and re-encoding changes the bytes, and the signature no longer matches.
  • Reject old timestamps, more than five minutes from your clock, so a captured request can't be replayed later.

Reply quickly, and expect repeats ​

Reply with any 2xx status as soon as you've safely stored the event, then do slower work afterwards. Propool waits at most 10 seconds and doesn't follow redirects.

  • The same event can arrive more than once. Keep the event id and skip ones you've already handled, but still reply 2xx.
  • Events can arrive out of order, even for the same lead. If order matters, fetch the current record from the API.

If your server doesn't answer 2xx, Propool tries again after 1 minute, 5 minutes, 15 minutes, 1 hour, 3 hours, 6 hours and 12 hours: eight attempts in all. After that the delivery is marked failed. In Settings → Webhooks you can see every delivery and its response code, and replay one.

Change or rotate the secret ​

Choose Rotate secret to get a new signing secret. For a few minutes, requests already on their way may still be signed with the old one, so accept both until the change settles, then remove the old one.

Disabling or deleting an endpoint stops new deliveries. Changing its URL or events cancels deliveries that were still waiting.