Make7 min read
Send form submissions to Make
Start a Make scenario from every Ikiform submission with a custom webhook, and add a small relay when you want each delivery verified.
Make's custom webhooks accept any JSON, so Ikiform can post to them directly. This guide sets that up first, then shows how to add signature checks with a short relay, because Make can't read Ikiform's signature on its own without extra work.
- Direct route: Ikiform posts each signed submission straight to the Make custom webhook. Make can't check the signature, so anyone who learns the URL can start the scenario.
- Verified route: Ikiform posts to a relay. The relay checks the signature, then forwards the same body to Make with the x-make-apikey header.
- Make's webhook has an API key on the verified route, so it refuses anything without that header.
Before you start
- An Ikiform form that already receives submissions.
- A Make account. Each run uses operations from your plan.
- For the verified route, somewhere to run the relay: a Cloudflare account with a domain on it, or a Next.js app.
What Ikiform sends
Every delivery is a POST with a JSON body. The body has the same shape for every endpoint, and you can't change it. A submission looks like this:
{
"id": "dlv_01k7v2d4n8r2p6s0w3y5b7c9e1",
"type": "submission.created",
"timestamp": "2026-10-23T12:00:00.000Z",
"api_version": "2026-10-17",
"data": {
"submission_id": "sub_01k7v2c9t3e8m5q4x6z0a1b2c3",
"form": { "id": "frm_xxxxxxxxxxxxxxxx", "name": "Contact" },
"fields": { "name": "Ada", "email": "ada@example.com", "message": "Hello" },
"meta": {
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"origin": "https://example.com",
"referrer": "https://example.com/contact",
"country": "GB",
"subject": null,
"reply_to": "ada@example.com"
},
"created_at": "2026-10-23T12:00:00.000Z",
"truncated": false
}
}The form's values are in data.fields, keyed by the input name. A test from the dashboard sends an endpoint.test event instead, with data.endpoint_id and data.message and no fields. The full reference is on Webhooks.
Pick a route
| Route | Setup | Who can start the scenario |
|---|---|---|
| Direct | Paste the Make URL into Ikiform | Anyone who learns the URL |
| Verified | Deploy a 30-line relay | Only requests signed with your Ikiform secret |
Start direct to build the scenario. Move to the verified route before the scenario writes anything that matters, such as CRM records or emails.
Direct route
Add a custom webhook
- Create a scenario and add the Webhooks app with the Custom webhook trigger.
- Choose Add, name the webhook, for example
Ikiform, and save. - Copy the address. It looks like
https://hook.eu1.make.com/abc123..., with the region of your Make account.
Add the endpoint in Ikiform
- In the Ikiform dashboard, open Webhooks and choose Add endpoint.
- Paste the Make webhook address into URL.
- Under Forms, pick one form, or All forms in the workspace.
- Add a Description if you like, such as "Make", then choose Add endpoint.
- Copy the signing secret. It starts with
whsec_and is shown in full only once.
There's no event picker. An endpoint gets
submission.createdfor every accepted submission on the forms you chose, andendpoint.testwhen you send a test. A workspace on Pro can have up to 3 endpoints.Teach Make the data structure
Make learns the fields from the first request it sees. With the webhook module open and waiting, send one real submission from your form, not a dashboard test, because test events have no fields. If you add fields to the form later, open the module and choose Redetermine data structure, then send another submission.
Filter and map
Add your next module, such as Google Sheets or Slack. On the link between the two, add a filter where
typeequalssubmission.created. Then map values fromdata>fields, such asemailandmessage.Turn the scenario on so it runs as soon as data arrives.
x-make-apikey header, and Ikiform can't add custom headers, so the verified route below is how you lock it down.Verified route
The relay checks Ikiform's signature, then forwards the exact same body to Make with an API key header. The scenario stays the same, and Make refuses anything that doesn't carry the key.
Add an API key to the webhook
In Make, open the webhook's settings and add an API key. Make then only accepts requests that send that key in the
x-make-apikeyheader. Copy the key.Write the relay
src/index.tsimport { verifyWebhook, type WebhookEvent, WebhookVerificationError } from "@ikiform/sdk/webhooks"; interface Env { IKIFORM_WEBHOOK_SECRET: string; MAKE_WEBHOOK_URL: string; MAKE_API_KEY: string; } function forward(url: string, apiKey: string, payload: string) { return fetch(url, { method: "POST", headers: { "content-type": "application/json", "x-make-apikey": apiKey }, body: payload, }); } export default { async fetch(request: Request, env: Env) { if (request.method !== "POST") return new Response(null, { status: 405 }); const payload = await request.text(); let event: WebhookEvent; try { event = await verifyWebhook({ payload, headers: request.headers, secret: env.IKIFORM_WEBHOOK_SECRET }); } catch (error) { if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 }); throw error; } const response = await forward(env.MAKE_WEBHOOK_URL, env.MAKE_API_KEY, payload); if (response.status === 429) { const retryAfter = response.headers.get("retry-after") ?? "30"; return new Response("Make rate limit", { status: 503, headers: { "retry-after": retryAfter } }); } if (!response.ok) return new Response(`Make answered ${response.status}`, { status: 502 }); return new Response(null, { status: 204 }); }, };- The relay forwards
payload, the raw string it verified, so Make sees exactly what Ikiform sent and the data structure doesn't change. - A
429from Make becomes a503with Make'sRetry-After, and any other error becomes a502. Ikiform retries both.
- The relay forwards
Deploy it
Cloudflare Worker
Terminal mkdir ikiform-make && cd ikiform-make npm init -y npm install @ikiform/sdk npm install -D wranglerwrangler.jsonc { "$schema": "node_modules/wrangler/config-schema.json", "name": "ikiform-make", "main": "src/index.ts", "compatibility_date": "2026-10-01", "routes": [{ "pattern": "hooks.example.com", "custom_domain": true }] }Ikiform refusesworkers.devURLs, so the Worker needs a hostname on a domain you have on Cloudflare, likehooks.example.com. Thecustom_domainroute creates the DNS record and certificate for you on deploy.Terminal npx wrangler secret put IKIFORM_WEBHOOK_SECRET npx wrangler secret put MAKE_WEBHOOK_URL npx wrangler secret put MAKE_API_KEY npx wrangler deployNext.js
Add
@ikiform/sdk, save the route handler, and setIKIFORM_WEBHOOK_SECRET,MAKE_WEBHOOK_URLandMAKE_API_KEYin your host's environment variables. Use the production domain, not a protected preview URL.Point Ikiform at the relay
Open the endpoint in Ikiform, choose Edit, and change URL to the relay URL. The signing secret stays the same; put it in
IKIFORM_WEBHOOK_SECRETon the relay.
Ikiform only delivers to public https:// URLs on port 443. IP addresses, localhost, internal hostnames, workers.dev and pages.dev are refused when you save the endpoint.
Test it
Open the endpoint in Ikiform and choose Send test. Ikiform sends one endpoint.test event with no retries, and the result shows up in the endpoint's delivery log within a few seconds. Then send a real submission from your form, or from a terminal:
curl https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
-H "Content-Type: application/json" \
-d '{"name":"Ada","email":"ada@example.com","message":"Hello from curl"}'A 201 with "ok": true means Ikiform stored it. The delivery appears on the endpoint page, and the message lands in Make's scenario History.
The test event runs the scenario and stops at the filter. A real submission continues through it.
How delivery works
| The receiver answers | Ikiform |
|---|---|
Any 2xx within 15 seconds | Marks the delivery succeeded |
| A redirect | Doesn't follow it, and counts a failure |
429 or 503 with Retry-After | Waits that long, up to the next step of the schedule |
410 Gone | Fails the delivery and disables the endpoint |
| Anything else, or no answer in 15 seconds | Retries |
Failed deliveries are retried 8 times over about 3 d 6 h, with the same webhook-id each time. If every delivery to an endpoint fails for 5 days, Ikiform disables it and emails the workspace owners.
- Make accepts the request: the relay answers 204, and Ikiform marks the delivery succeeded.
- Make is rate limited (429): the relay answers 503 with Make's Retry-After, and Ikiform waits that long before it tries again.
- Make answers with any other error: the relay answers 502, and Ikiform retries, 8 retries over about 3 d 6 h.
Without a Webhook response module, Make answers 200 Accepted as soon as the request is queued, before the scenario runs. Ikiform counts that as delivered. If a later module fails, rerun it from Make's history; Ikiform won't retry it. If you add a Webhook response module, place it early, so Make answers within Ikiform's 15 seconds.
Troubleshooting
| Problem | What to do |
|---|---|
400 with Queue is full | The scenario is off or slow, and Make's webhook queue filled up. Turn the scenario on; Ikiform retries the deliveries. |
502 with Make answered 4xx on the verified route | Make refused the request, most often because MAKE_API_KEY doesn't match the key on the webhook. Copy it again and update the relay. |
| New form fields don't show up in the mapping | Open the webhook module, choose Redetermine data structure, and send a submission that includes the new fields. |
| Endpoint disabled right after you deleted or changed the scenario | Ikiform disables an endpoint at once if it answers 410 Gone, which can happen when nothing listens on a Make address anymore. Create a new webhook, update the endpoint URL, and turn Enabled back on. |
400 no_matching_signature | The secret is wrong, or the body was parsed and re-serialized before verifying. Use the whsec_ secret of this endpoint and the raw body exactly as received. After Roll secret, update it within 24 hours. |
Delivery log shows timeout | Nothing answered within 15 seconds. Answer first and do slow work after, or make sure the tool responds right away. |
| Endpoint is disabled | Every delivery failed for 5 days, the URL answered 410, or its hostname started resolving to a private address. Fix the cause, then turn Enabled back on and Retry now the failed deliveries. |
| No delivery at all | Check that the endpoint covers this form, that it's enabled, and that the submission wasn't marked as spam or held because the workspace is over its monthly limit. |
Next steps
| Want to | Read |
|---|---|
| Add each submission as a sheet row | Send form submissions to Google Sheets |
| Verify inside the workflow tool itself | Send form submissions to n8n |
| See every header and retry rule | Webhooks |
Make's own reference: Webhooks and the Webhooks app.
Stuck on a step, or want a guide for another tool? Email hello@ikiform.com.