How to Set Up Webhooks: Forward Form Submissions to Slack, Zapier, and More
What are webhooks?
Webhooks are HTTP callbacks. When an event happens (like a form submission), InputHaven sends a POST request to a URL you specify. The request body contains the submission data as JSON.
This lets you connect form submissions to virtually any service without writing polling logic.
Setting up a webhook
- Go to Dashboard → Forms → [Your Form] → Settings
- In the Webhook URL field, enter the URL that should receive submissions
- Save
That's it. Every new submission will now trigger a POST request to your webhook URL.
Webhook payload
The webhook sends a JSON payload like this:
{
"event": "submission.created",
"form_id": "clx1234567890",
"form_name": "Contact Form",
"submission_id": "clx0987654321",
"timestamp": "2025-01-15T10:30:00.000Z",
"data": {
"name": "Jane Doe",
"email": "jane@example.com",
"message": "I'd like to learn more about your enterprise plan."
},
"metadata": {
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0...",
"referer": "https://yoursite.com/contact"
}
}Verifying webhook signatures
InputHaven signs every webhook payload with HMAC-SHA256. This lets you verify that the payload was sent by InputHaven and hasn't been tampered with.
The signature is included in the X-InputHaven-Signature header.
To verify in Node.js:
import crypto from "crypto";
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post("/webhook", (req, res) => {
const signature = req.headers["x-inputhaven-signature"];
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}
// Process the submission...
console.log("New submission:", req.body.data);
res.json({ ok: true });
});Integration: Slack
To send form submissions to a Slack channel:
- Create a Slack Incoming Webhook at api.slack.com/messaging/webhooks
- Copy the webhook URL (looks like
https://hooks.slack.com/services/T.../B.../...) - Paste it as your InputHaven webhook URL
InputHaven formats the submission data as a readable Slack message automatically.
For custom formatting, use Zapier or a small serverless function as middleware.
Integration: Discord
Discord supports Slack-compatible webhooks:
- Go to your Discord channel → Edit Channel → Integrations → Webhooks
- Create a new webhook and copy the URL
- Append
/slackto the URL (Discord's Slack compatibility endpoint) - Paste as your InputHaven webhook URL
Integration: Zapier
Zapier can receive webhooks and connect to 5,000+ services:
- Create a new Zap with "Webhooks by Zapier" as the trigger
- Choose "Catch Hook"
- Copy the webhook URL Zapier provides
- Paste as your InputHaven webhook URL
- Submit a test form to trigger the webhook
- In Zapier, add an action (send email, add to Google Sheet, create CRM contact, etc.)
Common Zapier workflows:
- Form → Google Sheets — log all submissions in a spreadsheet
- Form → Mailchimp — add email to a mailing list
- Form → HubSpot — create a CRM contact
- Form → Notion — add a database entry
Integration: Make (Integromat)
Similar to Zapier:
- Create a new scenario with "Webhooks" module
- Choose "Custom webhook"
- Copy the URL and paste as your InputHaven webhook URL
- Add processing modules for your desired workflow
Integration: n8n (self-hosted)
If you're self-hosting n8n:
- Add a Webhook node as the trigger
- Set method to POST
- Copy the production webhook URL
- Paste as your InputHaven webhook URL
Building your own webhook receiver
For a custom Node.js receiver:
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhook/inputhaven", (req, res) => {
const { event, data, form_name } = req.body;
if (event === "submission.created") {
console.log(`New submission on "${form_name}":`);
console.log(data);
// Your custom logic here:
// - Save to your database
// - Trigger a notification
// - Update a CRM record
// - Send a custom email
}
res.json({ received: true });
});
app.listen(3001, () => console.log("Webhook receiver running on :3001"));Retry policy
If your webhook endpoint returns a non-2xx status code, InputHaven retries:
- 1st retry: 1 minute later
- 2nd retry: 5 minutes later
- 3rd retry: 30 minutes later
After 3 failed attempts, the webhook is marked as failed. You can view failed webhooks in the dashboard.
Plan requirements
Webhooks are available on Starter ($5/mo) plans and above.