Form Webhooks: Forward Submissions to Any URL
Last updated: March 2026
FormWit webhooks let you forward form submissions to any URL in real-time. Every time someone submits your form, FormWit sends a POST request with the submission data as JSON to your configured endpoint. Use webhooks to pipe submissions into Slack, Discord, Zapier, a CRM, a database, or any custom API.
Webhooks are available on the Starter plan ($39/year) and above.
How form webhooks work
When a visitor submits your form, FormWit processes the submission, stores it, sends email notifications, and then queues a webhook delivery. Within seconds, your endpoint receives a POST request with the full submission data.
The flow:
- Visitor submits your HTML form
- FormWit validates, stores, and checks for spam
- FormWit sends a
POSTrequest to your webhook URL - Your server receives the JSON payload and does whatever you need
Spam submissions are filtered out automatically. Your webhook only receives clean submissions.
Configure a webhook URL
In the FormWit dashboard, open your form and go to Settings → Webhooks. Enter your HTTPS endpoint URL and an optional signing secret.
Requirements:
- Must be HTTPS (HTTP URLs are rejected)
- Must respond within 10 seconds
- Must return a 2xx status code
The signing secret is optional but recommended. It lets you verify that requests come from FormWit, not a third party.
Webhook payload format
FormWit sends a JSON POST request with Content-Type: application/json. The payload has three fields:
{
"submissionId": "019d10a6-4208-7000-9878-0d96ca3604b4",
"formId": "019d1056-0dec-7000-93fd-45df4895704d",
"data": {
"name": "Jane Smith",
"email": "jane@example.com",
"message": "I'd like to learn more about your services."
}
} | Field | Type | Description |
|---|---|---|
submissionId | string | Unique ID for this submission |
formId | string | The form that received the submission |
data | object | Key-value pairs from the form fields |
The data object contains exactly what the visitor submitted. Field names match your HTML form's name attributes. Honeypot fields and internal fields (like _gotcha) are stripped before delivery.
Headers sent with every webhook
Content-Type: application/json
X-Formwit-Timestamp: 2026-03-21T13:47:31.509Z
X-Formwit-Signature: sha256=a1b2c3... (only if a secret is configured) Verify webhook signatures
If you set a webhook secret, FormWit signs every payload with HMAC-SHA256. This lets you verify that the request actually came from FormWit and hasn't been tampered with.
The signature is computed over ${timestamp}.${body} using your secret as the HMAC key. To verify:
- Read the
X-Formwit-TimestampandX-Formwit-Signatureheaders - Compute
HMAC-SHA256(secret, timestamp + "." + rawBody) - Compare your computed signature with the one in the header
- Optionally, reject requests where the timestamp is more than 5 minutes old (replay protection)
Node.js verification example
import crypto from "node:crypto";
function verifyWebhook(req, secret) {
const timestamp = req.headers["x-formwit-timestamp"];
const signature = req.headers["x-formwit-signature"];
const body = req.body; // raw string, not parsed JSON
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${body}`)
.digest("hex");
return signature === `sha256=${expected}`;
} Webhook retry behavior
FormWit retries failed webhook deliveries automatically:
- 2xx response: Success. No retry.
- 4xx response: Client error. Marked as failed immediately. No retry (your endpoint rejected the request, retrying won't help).
- 5xx response or timeout: Server error. Retried up to 3 times with exponential backoff.
After 3 failed retries, the delivery is marked as permanently failed. You can manually retry failed deliveries from the webhook delivery log in your dashboard under Settings → Webhooks.
Receive webhooks in Node.js
A minimal Express server that receives form submissions via webhook:
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhook", (req, res) => {
const { submissionId, formId, data } = req.body;
console.log(`New submission ${submissionId} on form ${formId}`);
console.log("Name:", data.name);
console.log("Email:", data.email);
console.log("Message:", data.message);
// Save to database, send to CRM, trigger workflow, etc.
res.status(200).json({ received: true });
});
app.listen(3000); Deploy this to any Node.js host (Vercel, Railway, Render, your own server) and set the public URL as your webhook endpoint in FormWit.
Forward submissions to Slack
FormWit has built-in Slack support. When you configure a Slack incoming webhook URL in your form settings, submissions are automatically formatted as Slack Block Kit messages with field names, values, and a link to your dashboard.
To set it up:
- Create a Slack incoming webhook for your channel
- In FormWit, go to Settings → Webhooks and paste the Slack webhook URL in the Slack field
- Submit a test form. Your Slack channel receives a formatted message within seconds
"We built our site with AI and needed a form backend fast. FormWit was the easiest piece — connected it to Slack via webhooks and had leads flowing to our team in minutes." — Krishna, Founder, Adzep
Forward submissions to Discord
Similar to Slack, FormWit has native Discord support. Submissions are formatted as Discord embeds with your form data.
- In Discord, go to your channel's settings → Integrations → Create Webhook
- Copy the webhook URL (it starts with
https://discord.com/api/webhooks/) - In FormWit, paste it in the Discord field under Settings → Webhooks
Connect to Zapier or Make
Use FormWit's generic webhook to connect to automation platforms like Zapier or Make (formerly Integromat):
- In Zapier, create a new Zap with "Webhooks by Zapier" as the trigger
- Choose "Catch Hook" and copy the webhook URL Zapier gives you
- Paste that URL as your webhook endpoint in FormWit
- Send a test submission to map the fields in Zapier
- Add any action: Google Sheets, Mailchimp, HubSpot, Notion, Airtable, etc.
This lets you connect form submissions to 5,000+ apps without writing code.
Webhook delivery log
Every webhook delivery is logged in your dashboard. Go to Settings → Webhooks to see:
- Delivery status (Sent, Failed, Pending)
- HTTP response code from your endpoint
- Timestamp of each attempt
- Error details (hover the status badge for failed deliveries)
- Manual retry button for failed deliveries
Tips for reliable webhooks
- Respond fast. Return a 200 status immediately, then process the data asynchronously. FormWit times out after 10 seconds.
- Handle duplicates. Use
submissionIdas an idempotency key. In rare cases (network issues, retries), you may receive the same payload twice. - Verify signatures. If you set a secret, always verify the
X-Formwit-Signatureheader to prevent spoofed requests. - Use HTTPS. FormWit requires HTTPS for webhook URLs. This protects your submission data in transit.
- Monitor the delivery log. Check for failed deliveries periodically. Common failures: endpoint down, SSL certificate expired, response too slow.
Related guides
- Form Spam Protection — how FormWit filters spam before it reaches your webhook
- Send Form Submissions to Email — use email notifications alongside webhooks
- What Is a Form Backend? — how form backends like FormWit work under the hood
Want to skip the setup?
FormWit gives you a form endpoint in 60 seconds. Free plan, no credit card.
Need a form fast?
Build one visually with our free HTML form generator — no coding required.
Try the Form Generator →Try webhooks free
Add a contact form to your site in 30 seconds. No backend code required.
Try FormWit Free