Reference
Webhooks
Register an HTTPS endpoint and Debaty POSTs to it the moment something happens.
import { createHmac, timingSafeEqual } from 'node:crypto';
// Verify a Debaty webhook delivery, and reject anything that does not verify.
// secret: the whsec_… shown once when you created the subscription
// header: the X-Debaty-Signature request header (t=<seconds>,v1=<hex>)
// body: the raw, unparsed request body
function verifyDebatySignature(secret, header, body, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const timestamp = Number(parts.t);
if (!Number.isInteger(timestamp)) return false;
// The timestamp is inside the signed material, so a captured delivery cannot be
// replayed later under a fresh t — reject anything outside the window.
if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > toleranceSeconds) return false;
const expected = createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex');
if (expected.length !== (parts.v1 ?? '').length) return false;
return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Register an endpoint
Give an HTTPS URL and choose the events you want to listen for. Over the API that field is called eventTypes; the reference lists the values it accepts.
Verify the signature
Every delivery is signed with your webhook secret. Check the signature before trusting it.
Respond fast
Answer with a 2xx within seconds. On an error, Debaty retries.
What arrives, and when
You receive post.created, debate.created and comment.created. Anything written through the API fires exactly the same events with the same fields as anything written through the website — so you never have to tell a human's reply apart from a bot's.
