Integrations
Send form responses via webhooks
Webhooks are YeetForm's general-purpose way to send response data anywhere: your own backend, a database sync job, or another integration platform. Add an HTTPS endpoint under a form's Integrations tab and YeetForm POSTs a signed JSON payload on every new response, with a secret you can verify against using HMAC-SHA256. Failed deliveries retry automatically. This page covers the exact signature format, the payload shape, and the retry schedule so you can build a receiver with confidence.
Setup
Add an endpoint
In the form's Integrations tab, paste your HTTPS endpoint URL under Webhooks and click Add webhook. YeetForm generates a signing secret (whsec_...) for that endpoint.
Verify the signature
Every delivery carries an X-YeetForm-Signature header: t=<unix ts>,v1=<hex hmac-sha256 of `${t}.${body}`>. Verify it against the raw request body before trusting the payload.
import { createHmac, timingSafeEqual } from "crypto";
function verify(secret, signatureHeader, rawBody) {
const [tPart, v1Part] = signatureHeader.split(",");
const timestamp = tPart.split("=")[1];
const signature = v1Part.split("=")[1];
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const a = Buffer.from(signature, "hex");
const b = Buffer.from(expected, "hex");
if (a.length !== b.length) return false;
return timingSafeEqual(a, b);
}Read the payload
POSTs fire on response.created (and webhook.test for the manual test button), with the form id, response id, response count, and answers keyed by field id, plus a fields array with each field's label.
{
"event": "response.created",
"form_id": "<uuid>",
"form_title": "Customer Feedback",
"response_id": "<uuid>",
"response_count": 42,
"answers": { "fld_x": "..." },
"submitted_at": "2026-09-13T12:00:00.000Z"
}Handle retries
A non-2xx response (or a timeout) triggers a retry: immediately, then after 30 seconds, then after 5 minutes - 3 attempts total before YeetForm marks the delivery failed. Redirects aren't followed, so point the URL straight at your endpoint.
Tips
- →Field labels are included in the payload's fields array (id, label, type) so you don't have to hardcode field ids downstream.
- →Every response carries a stable response_id - use it as your idempotency key, since a retried delivery reuses the same id.
- →A failed delivery retries up to 3 times total (immediately, 30s, 5 min) before it's marked failed - a 2xx response is required to count as success, and redirects aren't followed.