Back to blog
TutorialwebhooksSlackZapier

How to Set Up Webhooks: Forward Form Submissions to Slack, Zapier, and More

7 min read

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 /slack to 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.

Ready to try InputHaven?

500 free submissions/month. No credit card required.

Get Started Free