Skip to content

Zapier and webhooks

Webhooks let you send Formkove submissions to any HTTP endpoint, which means you can connect to Zapier, Make, Pipedream, n8n, CRMs, databases, or your own backend.

This is a Pro and Agency feature.

When a submission comes in, Formkove queues a POST to your configured URL with the submission as JSON. Delivery is asynchronous: your visitor gets their response immediately, and failed deliveries (network errors, timeouts, 5xx responses) are retried automatically. Every attempt appears in the form’s Delivery history tab for 30 days.

If AI classification is on, Formkove classifies the submission before delivering it. Spam is held back and never delivered, and everything else arrives with its AI result attached.

  1. Open app.formkove.com and select your form
  2. Go to the Integrations tab → Webhook
  3. Paste your endpoint URL
  4. Optionally add a signing secret (recommended; see Webhook Security)
  5. Save

Webhook URLs must be public internet addresses. Private/internal IPs, localhost, and Formkove’s own domains are rejected.

Every webhook POST delivers a JSON body. The submitted form data is nested under data, while metadata is at the root:

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"formId": "form1_f1fbfb94b460156e219597a494aeee7f_24c9c626b2e8e1081b2b4ba0de841ed0",
"formName": "Contact Form",
"data": {
"name": "Jane Smith",
"email": "[email protected]",
"message": "Hello, I would like to learn more."
},
"createdAt": 1720725336000,
"ai": {
"sentiment": "positive",
"tags": ["sales"],
"spam_score": 0.04
}
}
  • Custom fields come through as-is inside data. Configured honeypot fields and the Turnstile token are stripped.
  • createdAt is a Unix timestamp in milliseconds.
  • ai is only present when AI classification is on for the form and finished successfully. spam_score runs from 0 (clean) to 1 (spam).

Each connection (webhook, Slack, Discord, Google Sheets, or Zapier) can be limited to certain AI results. Open Integrations → Connections and use the Routing column to require:

  • a sentiment (for example, only negative),
  • any of a set of tags (for example, support or bug), and/or
  • a maximum spam score.

All rules on a connection must match. Connections without rules receive every non-spam submission. A routed connection receives nothing when there is no AI result, so keep at least one unrouted connection (or email) as a catch-all.

If your webhook has a signing secret, every delivery includes these headers:

Header Value
X-Formkove-Delivery-Id A UUID for this delivery. It stays the same across retries, so use it to de-duplicate.
X-Formkove-Timestamp Unix seconds when this attempt was signed
X-Formkove-Signature-256 v1= + hex HMAC-SHA256 of {deliveryId}.{timestamp}.{rawBody} using your secret
X-Formkove-Signature Deprecated. Hex HMAC-SHA256 of the raw body only. Still sent for now; switch to X-Formkove-Signature-256, as this header will be removed in a future release.

To verify a delivery: recompute the signature over the raw request body, compare in constant time, reject timestamps more than 5 minutes old, and ignore delivery IDs you have already processed.

import crypto from 'node:crypto';
function verifyFormkove(headers, rawBody, secret) {
const id = headers['x-formkove-delivery-id'];
const ts = headers['x-formkove-timestamp'];
const expected = 'v1=' + crypto
.createHmac('sha256', secret)
.update(`${id}.${ts}.${rawBody}`)
.digest('hex');
const received = headers['x-formkove-signature-256'] ?? '';
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) <= 300;
return fresh
&& expected.length === received.length
&& crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}

Use Zapier’s Webhooks by Zapier trigger to route Formkove submissions to thousands of apps.

A native Formkove app for Zapier (API-key login with a form picker and flat ai_* fields) is coming soon. Until it’s listed in Zapier, use the Catch Hook method below.

  1. Create a new Zap in Zapier
  2. Choose Webhooks by Zapier → Catch Hook as the trigger
  3. Copy the webhook URL Zapier gives you
  4. Paste it into Formkove (Integrations → Webhook)
  5. Submit a test entry through your form. Zapier will capture it
  6. Continue building your Zap (Slack, Google Sheets, Mailchimp, etc.)

Zapier receives the webhook payload above. It flattens nested keys for you, so form fields show up as Data Name, Data Email, and so on, and AI results as Ai Sentiment, Ai Tags and Ai Spam Score. Use them in Zapier Filters or Paths, or use AI routing rules so Formkove only sends the submissions you want.

  1. Catch Hook captures the submission
  2. Create Spreadsheet Row action
  3. Map form fields to columns (Data Name → Column A, Data Email → Column B, etc.)
  1. Catch Hook captures the submission
  2. Send Channel Message action
  3. Insert the Data … fields into the message
  1. Create a new Scenario in Make
  2. Add a Webhooks module → Custom webhook as the trigger
  3. Copy the webhook URL into Formkove
  4. Submit a test entry so Make can learn the data structure
  5. Continue building your workflow
  1. Create a new Workflow in Pipedream
  2. Select HTTP / Webhook as the trigger
  3. Copy the endpoint URL into Formkove
  4. Submit a test entry
  5. Add actions: send to Slack, store in a database, run custom Node.js code
  1. Create a new Workflow in n8n
  2. Add a Webhook node (method POST)
  3. Copy the production webhook URL into Formkove
  4. Submit a test entry
  5. Connect to any node: HTTP Request, Google Sheets, Slack, etc.

Use webhook.site to get a temporary URL you can test with before connecting your real automation platform.

Event When it fires
submission.created New accepted, non-spam submission
Problem Fix
Webhook not firing Check the URL is correct and public, and that the form is on a Pro or Agency workspace
Only some submissions arrive Check the connection’s Routing rules, and whether AI marked the others as spam
4xx or 5xx in Delivery history Your endpoint returned an error. Check its logs
Signature doesn’t match Sign the raw body exactly as received, before any JSON parsing
Zapier didn’t catch the test Submit a real form entry after adding the Catch Hook URL