Вебхуки
Замість того щоб постійно опитувати API — налаштуйте вебхуки, і Zapys24 сам надішле вам повідомлення, коли щось відбудеться: новий запис, скасування, відгук тощо.
Як це працює
- Ви створюєте URL на вашому сервері, який прийматиме POST-запити (наприклад,
https://your-site.com/webhooks/zapys24) - Через API реєструєте цей URL та обираєте потрібні події
- Коли подія відбувається — Zapys24 надсилає POST-запит на ваш URL з даними
Scope: webhooks:manage
Доступні події
| Подія | Коли спрацьовує |
|---|---|
booking.created | Клієнт створив новий запис |
booking.confirmed | Запис підтверджено |
booking.cancelled | Запис скасовано |
booking.completed | Візит завершено |
booking.no_show | Клієнт не з'явився |
booking.rescheduled | Запис перенесено на інший час |
client.created | З'явився новий клієнт |
client.updated | Дані клієнта змінено |
review.created | Клієнт залишив відгук |
payment.received | Отримано оплату |
payment.refunded | Здійснено повернення коштів |
staff.schedule_updated | Змінено розклад майстра |
service.updated | Оновлено послугу |
service.deleted | Видалено послугу |
Отримати список подій через API
GET /v1/integration/webhooks/events
Створити вебхук
POST /v1/integration/webhooks
Ліміт: до 10 активних вебхуків на один API-ключ.
curl -X POST \
-H "X-API-Key: ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"targetUrl": "https://your-site.com/webhooks/zapys24",
"events": ["booking.created", "booking.cancelled"],
"description": "Сповіщення про записи"
}' \
https://api.zapys24.com/v1/integration/webhooks
Відповідь 201 Created:
{
"id": 1,
"targetUrl": "https://your-site.com/webhooks/zapys24",
"events": ["booking.created", "booking.cancelled"],
"description": "Сповіщення про записи",
"status": "active",
"consecutiveFailures": 0,
"lastTriggeredAt": null,
"createdAt": "2026-03-03T10:00:00.000Z",
"updatedAt": "2026-03-03T10:00:00.000Z",
"secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6..."
}
Поле secret показується лише при створенні вебхуку. Вам він потрібен для перевірки підпису вхідних запитів — зберігайте його у змінних оточення вашого серверу.
Формат вхідного повідомлення
Коли подія відбувається, Zapys24 надсилає POST-запит на ваш URL:
{
"id": "whdel_abc123def456ghi789",
"event": "booking.created",
"timestamp": "2026-03-03T10:00:00.000Z",
"apiVersion": "1.0",
"data": {
"bookingId": 123,
"status": "confirmed",
"serviceName": "Стрижка чоловіча",
"staffName": "Олена Коваль",
"startTime": "2026-03-15T14:00:00.000Z"
}
}
Заголовки запиту:
| Заголовок | Опис |
|---|---|
Content-Type | application/json |
X-Webhook-Event | Тип події, напр. booking.created |
X-Webhook-Delivery | Унікальний ID доставки |
X-Webhook-Signature | Підпис для верифікації: sha256=<hex> |
X-Webhook-Timestamp | Час відправки (ISO 8601) |
Верифікація підпису
Обов'язково перевіряйте підпис — це захищає вас від підроблених запитів. Zapys24 підписує кожне повідомлення за допомогою секрету, який ви отримали при створенні вебхуку.
const crypto = require("crypto");
function verifySignature(payload, signature, secret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(payload).digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// Express приклад:
app.post("/webhooks/zapys24", (req, res) => {
const payload = JSON.stringify(req.body);
const signature = req.headers["x-webhook-signature"];
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature");
}
const { event, data } = req.body;
switch (event) {
case "booking.created":
// Новий запис — наприклад, надіслати SMS клієнту
console.log(`Новий запис #${data.bookingId}`);
break;
case "booking.cancelled":
// Скасування — оновити ваш календар
console.log(`Скасовано запис #${data.bookingId}`);
break;
}
// Завжди відповідайте 200, щоб Zapys24 знав що повідомлення отримано
res.status(200).send("OK");
});
Повторні спроби (Retry Policy)
Якщо ваш сервер не відповідає або повертає помилку (не 2xx), Zapys24 спробує відправити повідомлення кілька разів:
| Спроба | Через скільки |
|---|---|
| 1 | Негайно |
| 2 | 1 хвилина |
| 3 | 5 хвилин |
| 4 | 15 хвилин |
| 5 | 1 година |
| 6 (остання) | 4 години |
Таймаут на відповідь — 10 секунд. Якщо ваш обробник потребує більше часу — збережіть дані та обробіть асинхронно.
Після 5 послідовних невдач вебхук автоматично вимикається (статус failed). Ви можете повторно активувати його через API.
Управління вебхуками
Список вебхуків
GET /v1/integration/webhooks
Оновити вебхук
PATCH /v1/integration/webhooks/:id
{
"events": ["booking.created", "booking.cancelled", "review.created"],
"status": "active"
}
При зміні status на active лічильник невдач автоматично скидається.
Видалити вебхук
DELETE /v1/integration/webhooks/:id
Ротація секрету
Якщо секрет скомпрометовано — згенеруйте новий:
POST /v1/integration/webhooks/:id/rotate-secret
Старий секрет стає недійсним негайно.
Тестовий Ping
Перевірте, чи ваш endpoint доступний:
POST /v1/integration/webhooks/:id/ping
Історія доставок
Подивіться статус останніх відправок:
GET /v1/integration/webhooks/:id/deliveries?page=1&limit=20
Відповідь:
{
"data": [
{
"id": 1,
"event": "booking.created",
"deliveryId": "whdel_abc123def456",
"responseStatusCode": 200,
"responseTimeMs": 45,
"deliveryStatus": "success",
"attemptNumber": 1,
"errorMessage": null,
"createdAt": "2026-03-03T10:05:00.000Z"
}
],
"total": 156
}
| Статус | Що означає |
|---|---|
pending | Очікує відправки |
success | Доставлено (ваш сервер відповів 2xx) |
failed | Усі спроби вичерпано |
retrying | Попередня спроба невдала, чекає на ретрай |