Webhooks
Register an endpoint to get a POST request whenever something happens in Threadliner.
A webhook is an account-wide subscription: pick the event types you care about, and every matching event across your whole workspace gets POSTed to your URL — not scoped to one form, list, or pipeline.
This is different from the send_webhook automation action
— that's a one-off POST from a single rule, only firing for events matching that
rule's trigger and conditions. Registering a webhook here is broader and standing:
every event of the chosen types, for as long as the webhook exists.
Registering an endpoint
- Go to Settings → Webhooks.
- Fill in Endpoint URL and check the Events you want to subscribe to.
- Click Create webhook.
- Copy the signing secret shown immediately after — it's shown exactly once and used to verify deliveries.
Payload shape
Every delivery is a POST with this JSON body:
{ "type": "<event type>", "data": { /* event-specific payload */ } }And these headers:
Content-Type: application/json
X-Threadliner-Event: <event type>
X-Threadliner-Signature: sha256=<hex-encoded HMAC>The 10 event types and their data payload shapes are documented in the
automation trigger reference (which covers 9 of them —
the 10th, campaign.sent, is webhook-only, not available as an automation trigger):
{ "campaignId": "…", "listId": "…", "sentCount": 42, "failedCount": 1 }Verifying a delivery
The signature is an HMAC-SHA256 of the raw request body, using your webhook's signing secret, hex-encoded:
const crypto = require("node:crypto");
function isValidSignature(rawBody, signatureHeader, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}Compute the HMAC over the raw, unparsed request body — not a re-serialized version of the parsed JSON, which can differ in whitespace/key order and produce a mismatch.
Retries
There's no automatic retry. Each delivery is attempted once — if your endpoint is down or times out (10 second timeout), that event is gone as far as the webhook system is concerned. Design your endpoint to respond quickly and reliably, and check View deliveries on the webhook (under Settings → Webhooks) periodically if you need to catch gaps.
Viewing delivery history
Each registered webhook has a View deliveries toggle showing recent attempts: event type, timestamp, and either the HTTP status code, or an error message (a network failure, or a timeout) if the request never got a response at all.
Deleting a webhook
Click Delete next to the endpoint under Settings → Webhooks. There's no pause/ disable — only delete.
Last updated on