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.
How Webhooks Work
Section titled “How Webhooks Work”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.
Setting Up a Webhook
Section titled “Setting Up a Webhook”- Open app.formkove.com and select your form
- Go to the Integrations tab → Webhook
- Paste your endpoint URL
- Optionally add a signing secret (recommended; see Webhook Security)
- Save
Webhook URLs must be public internet addresses. Private/internal IPs, localhost, and Formkove’s own domains are rejected.
Webhook Payload Structure
Section titled “Webhook Payload Structure”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", "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. createdAtis a Unix timestamp in milliseconds.aiis only present when AI classification is on for the form and finished successfully.spam_scoreruns from0(clean) to1(spam).
AI Routing Rules
Section titled “AI Routing Rules”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,
supportorbug), 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.
Webhook Security (Signatures)
Section titled “Webhook Security (Signatures)”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));}Connecting via Zapier
Section titled “Connecting via Zapier”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.
- Create a new Zap in Zapier
- Choose Webhooks by Zapier → Catch Hook as the trigger
- Copy the webhook URL Zapier gives you
- Paste it into Formkove (Integrations → Webhook)
- Submit a test entry through your form. Zapier will capture it
- Continue building your Zap (Slack, Google Sheets, Mailchimp, etc.)
What Gets Passed to Zapier
Section titled “What Gets Passed to Zapier”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.
Zapier Example: Route to Google Sheets
Section titled “Zapier Example: Route to Google Sheets”- Catch Hook captures the submission
- Create Spreadsheet Row action
- Map form fields to columns (
Data Name→ Column A,Data Email→ Column B, etc.)
Zapier Example: Notify Slack
Section titled “Zapier Example: Notify Slack”- Catch Hook captures the submission
- Send Channel Message action
- Insert the
Data …fields into the message
Connecting via Make
Section titled “Connecting via Make”- Create a new Scenario in Make
- Add a Webhooks module → Custom webhook as the trigger
- Copy the webhook URL into Formkove
- Submit a test entry so Make can learn the data structure
- Continue building your workflow
Connecting via Pipedream
Section titled “Connecting via Pipedream”- Create a new Workflow in Pipedream
- Select HTTP / Webhook as the trigger
- Copy the endpoint URL into Formkove
- Submit a test entry
- Add actions: send to Slack, store in a database, run custom Node.js code
Connecting via n8n
Section titled “Connecting via n8n”- Create a new Workflow in n8n
- Add a Webhook node (method
POST) - Copy the production webhook URL into Formkove
- Submit a test entry
- Connect to any node: HTTP Request, Google Sheets, Slack, etc.
Testing Webhooks
Section titled “Testing Webhooks”Use webhook.site to get a temporary URL you can test with before connecting your real automation platform.
Events
Section titled “Events”| Event | When it fires |
|---|---|
submission.created |
New accepted, non-spam submission |
Troubleshooting
Section titled “Troubleshooting”| 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 |