Pro
Вебхуки
Fairo надсилає події розіграшу на ваш HTTPS-ендпоінт — щоб підключити CRM, Zapier, власну систему видачі призів чи просто сповіщення в Slack. Адреса задається в налаштуваннях розіграшу, у блоці Pro-можливостей.
Події
participant.joined
Хтось подав заявку на участь
- handle
- — нікнейм учасника
- status
- — passed · rejected · review
- note
- — людське пояснення статусу
- botRisk
- — оцінка ризику бота, 0–100
- referredBy
- — хендл реферера або null
giveaway.launched
Збір заявок відкрито (вручну або за розкладом)
- title
- — назва розіграшу
- endsAt
- — ISO-дата фіналу або null
draw.completed
Переможців визначено
- title
- — назва розіграшу
- winners
- — масив хендлів переможців
- backups
- — масив резервних
- prizes
- — призи за місцями (Pro)
- seed
- — розкритий сід — можна перевірити самому
- verifyUrl
- — лінк на сертифікат чесності
Формат запиту
Метод POST, тіло — JSON. Заголовки: x-fairo-event (назва події) і x-fairo-signature (підпис, див. нижче).
{
"event": "draw.completed",
"giveawayId": "fa-2214",
"sentAt": "2026-07-30T12:34:56.789Z",
"data": {
"title": "Сертифікат на 2 000 грн",
"winners": ["@kateryna.art21"],
"backups": ["@olena.lviv46"],
"prizes": ["Сертифікат 2 000 грн"],
"seed": "fairo-8kd02mz1qx83",
"verifyUrl": "https://fairo.app/verify/fa-2214"
}
}Перевірка підпису
Кожен запит підписаний HMAC-SHA256 від сирого тіла, ключ — секрет вашого розіграшу (показується біля поля вебхука). Обовʼязково звіряйте підпис: інакше будь-хто, знаючи вашу адресу, зможе надсилати фейкові події.
import { createHmac, timingSafeEqual } from "node:crypto";
// Секрет розіграшу — на сторінці редагування, у блоці Pro
const SECRET = process.env.FAIRO_WEBHOOK_SECRET;
export function POST(req, rawBody) {
const signature = req.headers["x-fairo-signature"];
const expected = createHmac("sha256", SECRET)
.update(rawBody) // саме СИРЕ тіло, не JSON.stringify(parsed)
.digest("hex");
const ok =
signature?.length === expected.length &&
timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!ok) return new Response("bad signature", { status: 401 });
const { event, giveawayId, data } = JSON.parse(rawBody);
// …ваша логіка: CRM, видача призу, Slack-повідомлення
return new Response("ok");
}Те саме на Python:
import hmac, hashlib, json
SECRET = os.environ["FAIRO_WEBHOOK_SECRET"]
def handle(headers, raw_body: bytes):
expected = hmac.new(
SECRET.encode(), raw_body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(headers["x-fairo-signature"], expected):
return 401, "bad signature"
payload = json.loads(raw_body)
...
return 200, "ok"Підпис рахується від сирого тіла запиту. Якщо спершу розпарсити JSON, а потім зібрати рядок назад, підпис не зійдеться — порядок ключів і пробіли можуть відрізнятися.
Доставка й обмеження
- · Лише HTTPS і публічні адреси. Локальні й приватні мережі (localhost, 10.x, 192.168.x, 172.16–31.x, 169.254.x) відхиляються — це захист від запитів у внутрішню інфраструктуру.
- · Таймаут 5 секунд. Відповідайте швидко: важку роботу ставте в чергу вже у себе.
- · Доставка best-effort, без повторів. Недоступний ендпоінт не блокує участь чи розіграш — подія просто губиться, а помилка лишається в логах Fairo.
- · Порядок подій не гарантований. Джерело істини — завжди сторінка сертифіката.
Питання про чесність розіграшів — сторінка «Чесність».