Receive real-time events from Zautic in minutes
Webhooks let your system react instantly to events like message delivery, incoming messages, and device status changes. This guide shows exactly how to create your webhook URL, verify signatures, and process events safely.
4-step webhook setup (Stripe-style)
You choose your webhook URL by creating a simple endpoint on your server (or serverless function). Then you paste that URL into Zautic.
1) Choose your URL
Create an endpoint like https://your-domain.com/webhooks/zautic
2) Verify signatures
Validate t=1700000000,v1=abcdef using your webhook secret
3) Subscribe to events
Select which events you want in Members → API Integration → Webhooks
4) Process asynchronously
ACK fast (2xx), enqueue work to your job queue / worker
What Zautic sends to your server
Zautic sends an HTTP POST request with a JSON body and these headers. Your server must return a 2xx quickly.
X-Zautic-Eventmessage.deliveredX-Zautic-Delivery-Idunique per delivery (idempotency key)X-Zautic-Timestampunix secondsX-Zautic-Signaturet=...,v1=... (HMAC SHA256 of t.rawBody)- • Verify signatures using the raw request body (before JSON parsing).
- • Use idempotency (store
X-Zautic-Delivery-Id) to avoid duplicate processing. - • Respond fast; do heavy work asynchronously.
{
"id": "evt_5f3c2a1b9d4e8c0a1f2b3c4d5e6f7a8b",
"type": "message.delivered",
"created": 1767432000,
"created_at": "2026-01-03T00:00:00.000Z",
"livemode": true,
"data": {
"object": {
"message_id": "3EB0DC15F6ACF859FB492F",
"phone": "919876543210",
"device_id": 114,
"status": "delivered",
"direction": "outgoing"
}
}
}Copy‑paste receiver examples
Pick your stack, deploy a public HTTPS URL, paste it into Zautic Webhooks, and click “Test”.
// Node.js (Express) - production-safe signature verification
// Install: npm i express
import crypto from "crypto";
import express from "express";
const app = express();
// IMPORTANT: we need raw body to verify the signature.
app.use("/webhooks/zautic", express.raw({ type: "application/json" }));
app.post("/webhooks/zautic", async (req, res) => {
const secret = process.env.ZAUTIC_WEBHOOK_SECRET; // from Zautic dashboard
const signatureHeader = String(req.header("X-Zautic-Signature") || "");
const deliveryId = String(req.header("X-Zautic-Delivery-Id") || "");
if (!secret) return res.status(500).send("Missing secret");
// Idempotency: store deliveryId (or event.id) and ignore duplicates.
// if (await alreadyProcessed(deliveryId)) return res.sendStatus(200);
const rawBody = req.body.toString("utf8");
const { t, v1 } = (() => {
const parts = signatureHeader.split(",").map(p => p.trim());
const map = Object.fromEntries(parts.map(p => p.split("=")));
return { t: map.t, v1: map.v1 };
})();
if (!t || !v1) return res.status(400).send("Invalid signature header");
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex"));
if (!ok) return res.status(400).send("Signature mismatch");
const event = JSON.parse(rawBody);
// Process quickly (enqueue work) and ACK with 2xx.
switch (event.type) {
case "message.delivered":
// enqueueJob("message.delivered", event);
break;
case "message.received":
// enqueueJob("message.received", event);
break;
default:
break;
}
// Mark deliveryId as processed (idempotency)
// await markProcessed(deliveryId);
return res.sendStatus(200);
});
app.listen(3000, () => console.log("Listening on http://localhost:3000"));Supported events
Subscribe only to what you need. You can update subscriptions anytime from the Members dashboard.
Reliability best practices
Webhooks are delivered asynchronously and may be retried. Your receiver should be designed for retries and duplicates.
How to test your receiver
- 1. Deploy your endpoint publicly via HTTPS (or use ngrok/cloudflared for local dev).
- 2. In Zautic Members → API Integration → Webhooks, create a webhook with your URL.
- 3. Click Test to receive a
webhook.testevent. - 4. Trigger real events by sending a message and watching delivery/read updates.
- 5. (Optional) Use our Postman Collection → Webhooks (Simulator) folder to send signed sample events to your server.
Use webhooks with Zapier, Make, or n8n
These platforms can act as your webhook receiver. They generate an HTTPS URL; paste it into Zautic and build workflows without writing backend code.
- 1. Create a Zap with trigger: Webhooks by Zapier → Catch Hook.
- 2. Copy the webhook URL Zapier gives you.
- 3. In Zautic → Members → API Integration → Webhooks, create a webhook using that URL and select events.
- 4. Click Test in Zautic (or send a message) to capture the first sample in Zapier.
- 5. Add actions (Sheets/CRM/Slack) and branch on
type.
Signature verification: use Catch Raw Hook + a code step (or forward via your own endpoint) if you want strict verification.
- 1. Create a Scenario and add Webhooks → Custom webhook.
- 2. Copy the webhook URL that Make generates.
- 3. Add it in Zautic Webhooks and select events.
- 4. Run the Scenario once to let Make “listen”, then trigger Zautic Test or send a message.
- 5. Map fields into other modules (CRM, Sheets, email) and branch on
type.
If you need signature verification inside Make, use a code step to HMAC t.rawBody and compare with v1.
- 1. Create a workflow with a Webhook node (method: POST).
- 2. Copy the Production URL from n8n.
- 3. Paste it into Zautic Webhooks and select events.
- 4. Use Zautic Test to confirm the workflow triggers.
- 5. Add nodes to route by
typeand processdata.object.
n8n is great if you want full control (including signature verification) while staying mostly no-code.