Developers
Webhooks
Get a POST request on your server the moment something happens: a booking is made, moved, cancelled or paid, a form is submitted, someone registers for an event.
Set one up#
Go to Settings → Developer → Webhooks, add your server's public URL (use https://), choose the triggers and set a secret (one is generated for you if you leave it empty). Use Ping to send a test, and Deliveries to see every request and your server's reply. Your plan needs Webhooks.
Triggers#
| Trigger | Sent when |
|---|---|
BOOKING_CREATED | A booking is made (or a pending one is confirmed). |
BOOKING_REQUESTED | A booking needs your confirmation. |
BOOKING_RESCHEDULED | A booking moves to a new time. |
BOOKING_CANCELLED | A booking is cancelled, or you ask the person to reschedule. |
BOOKING_REJECTED | You decline a booking. |
BOOKING_PAID | Payment for a booking succeeds. |
BOOKING_NO_SHOW_UPDATED | You mark (or unmark) a no-show. |
FORM_SUBMITTED | Someone submits a routing form. |
EVENT_REGISTRATION_CREATED | Someone registers for one of your events. |
EVENT_REGISTRATION_CANCELLED | A registration is cancelled. |
EVENT_CANCELLED | You cancel an event. |
What you receive#
A JSON POST with the trigger in the X-Scheduler-Trigger header. Reply with any 2xx status within a few seconds; do slow work after replying.
BOOKING_CREATED
{
"triggerEvent": "BOOKING_CREATED",
"createdAt": "2026-10-12T14:03:11.000Z",
"payload": {
"uid": "bk_7h2k9…",
"title": "Consultation between Ada Obi and Tunde Bello",
"type": "consultation",
"eventTypeId": "evt_abc123",
"startTime": "2026-10-15T08:30:00.000Z",
"endTime": "2026-10-15T09:30:00.000Z",
"status": "accepted",
"organizer": { "name": "Ada Obi", "email": "[email protected]", "timeZone": "Africa/Lagos" },
"attendees": [{ "name": "Tunde Bello", "email": "[email protected]", "timeZone": "Africa/Lagos" }],
"responses": { "topic": "Pricing" },
"additionalNotes": "Booked from our app",
"location": { "type": "google-meet", "url": "https://meet.google.com/abc-defg-hij" },
"payment": { "amount": 2500000, "currency": "NGN", "status": "paid", "provider": "paystack" }
}
}You can change the body's shape per webhook with a custom payload: write your own JSON and use variables like
{{title}}, {{startTime}}, {{attendeeName}}, {{attendeeEmail}}, {{organizerName}} or any payload field with dots, e.g. {{location.url}}.Check the signature#
Every request has an X-Scheduler-Signature-256 header: the HMAC-SHA256 of the raw request body, keyed with your webhook's secret, as lowercase hex. Compute it yourself and compare before trusting the request.
import crypto from "node:crypto";
import express from "express";
const app = express();
// Use the raw body: re-serialising the JSON changes it and breaks the signature.
app.post("/webhooks/zylux-meet", express.raw({ type: "application/json" }), (req, res) => {
const expected = crypto.createHmac("sha256", process.env.WEBHOOK_SECRET).update(req.body).digest("hex");
const given = req.get("X-Scheduler-Signature-256") ?? "";
const ok = given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!ok) return res.status(401).end();
const event = JSON.parse(req.body.toString("utf8"));
if (event.triggerEvent === "BOOKING_CREATED") {
// save event.payload ...
}
res.sendStatus(200);
});Manage webhooks with the API#
GET
/api/webhooksAPI keyYour webhooks.
POST
/api/webhooksAPI keyCreate one. Body:
{ "subscriberUrl": "https://…", "triggers": ["BOOKING_CREATED"], "secret": "…" }. Optional: eventTypeId (only that link), payloadTemplate, active.PATCH
/api/webhooks/{id}API keyChange it.
DELETE
/api/webhooks/{id}API keyDelete it.
POST
/api/webhooks/{id}/pingAPI keySend a test request.
GET
/api/webhooks/{id}/deliveriesAPI keyRecent requests and your server's replies.
cURL
curl -X POST https://meet.zyluxmedia.app/api/webhooks \
-H "Authorization: Bearer $ZYLUX_MEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "subscriberUrl": "https://your-app.com/webhooks/zylux-meet", "triggers": ["BOOKING_CREATED", "BOOKING_CANCELLED"], "secret": "a-long-random-string" }'