Your automation ran 15 minutes after the order came in. Or it ran 288 times today and found nothing on most of them.
The fix is a webhook: a URL your app calls the moment something happens, so the workflow runs once, instantly. Use one whenever the app offers it. In n8n that’s the Webhook node, in Make a Custom webhook, in Zapier a paid-plan Catch Hook.
Below: the setup in each tool, what polling really costs, and the two security checks most tutorials skip.
What is a webhook, in plain English?
A webhook is an HTTP request one app sends to another app’s URL when an event happens. Your store sends “order paid” to your automation tool, with the order details attached.
There are four parts, and you’ll meet all of them in every tool:
- The URL. Your automation tool gives you one. You paste it into the sending app’s webhook settings.
- The event. What makes the app fire: a new order, a form submission, a failed payment.
- The payload. The data in the request body, almost always JSON sent with a POST request. It’s the same plumbing our REST vs GraphQL guide covers, pointed the other way.
- The response. Your tool answers with a status code, usually 200. That answer tells the sender the message arrived.
Think of the direction. With a normal API call, you ask an app for data. With a webhook, the app tells you, without being asked.

That flip sounds small. On the bill, it isn’t.
Webhooks vs polling: what does checking every 5 minutes cost?
On Make and n8n, polling costs you something on every check, even the empty ones. On Zapier it costs nothing, but it’s slow.
Take a small online shop with 40 orders a day. Each order goes to a Google Sheet and a Slack channel, so that’s two actions per order and 1,200 orders a month.
| Same shop, 30 days | Polling every 5 minutes | Webhook |
|---|---|---|
| Make (credits) | 8,640 trigger checks + 2,400 actions = 11,040 | 1,200 trigger runs + 2,400 actions = 3,600 |
| n8n Cloud (executions) | About 8,640 | 1,200 |
| Zapier (tasks) | 2,400, but each order waits up to 2 minutes on Pro | 2,400, and each order arrives in seconds |
Make charges one credit every time a trigger checks for new data, and its own help docs work the maths: every 5 minutes is 288 credits a day. The polling version burns about 7,400 extra credits a month on checks that mostly come back empty.
n8n counts every run of the workflow. Its Starter plan includes 2,500 executions a month for €20, billed yearly. A workflow that checks the shop every 5 minutes eats that in under nine days. The webhook version fits with room to spare.
Zapier is the twist. Triggers and polling don’t count as tasks there, so a webhook saves you nothing. What it buys is speed: Zapier checks every 15 minutes on Free and every 2 minutes on Pro.
Our take: on Make and n8n, a webhook is a cost decision. On Zapier, it’s a speed decision. Either way, if the app you’re watching offers webhooks, use them.
How we checked: every limit and price here comes from the official docs and pricing pages of n8n, Make, Zapier, Stripe and GitHub. We checked them on October 18, 2026. We didn’t build these three workflows on live accounts for this guide. The curl command and the Python check below were tested against a local test server.
Heads-up: we earn a commission if you sign up for n8n or Make through links on this page. It doesn’t change what we recommend.
How to set up a webhook in n8n
Add a Webhook node, test with its test URL, then publish and switch the sending app to the production URL. The trap is that n8n gives you two URLs.
n8n Webhook node, step by step
From a blank workflow to a live production URL
-
Step 1 of 5
Add the Webhook node as your trigger
Start a new workflow and pick Webhook as the first node. Set HTTP Method to POST, which is what most apps send. Change the random Path to something readable, like new-order.
-
Step 2 of 5
Pick how n8n should answer
Set Respond to Immediately if the workflow is slow or calls an AI model. The sender gets a quick reply and n8n keeps working. Choose When Last Node Finishes only when the caller needs the result back.
-
Step 3 of 5
Add authentication
Under Authentication, choose Header Auth and create a credential with a header name such as X-Webhook-Secret and a long random value. Requests without it are rejected before your workflow runs.
-
Step 4 of 5
Listen with the test URL
Click Listen for test event, then fire a real event from the sending app, or send the curl request below. The payload appears on the canvas so you can map fields into the next nodes.
-
Step 5 of 5
Swap in the production URL and publish
Copy the Production URL, paste it into the sending app in place of the test one, and publish the workflow. Production runs don’t show on the canvas. Find them in the Executions tab.
Most beginners get this wrong. The test URL contains /webhook-test/ and only listens while you’re watching. Leave it in Stripe or your form tool and every event after your session fails.
Two options under Add Option save real money. Only Run If takes an expression, and requests that don’t match get a 200 reply without creating an execution. IP(s) Allowlist returns a 403 to anyone outside your list.
Payloads can be up to 16 MB. New to the tool? Our n8n review covers the plans. Our n8n AI agent tutorial builds a full workflow from the trigger up.
How to set up a webhook in Make
Start the scenario with a Custom webhook, click Add to create the URL, then send one sample request. Make uses it to learn your data structure.
Make Custom webhook, step by step
From an empty scenario to an instant trigger
-
Step 1 of 4
Add Custom webhook as the trigger
Create a scenario, search for Webhooks and choose Custom webhook. Click Add, give it a name you’ll recognise in six months, and save.
-
Step 2 of 4
Copy the URL and send a sample
Copy the address Make shows and paste it into the sending app. Make waits for a first request and uses it to learn the fields, so send a real event, not an empty test ping.
-
Step 3 of 4
Check for your secret header
In the webhook’s advanced settings, switch on Get request headers. Then add a filter after the trigger that only lets requests carrying your secret header through.
-
Step 4 of 4
Leave the schedule on Immediately
Instant webhooks run each request as it arrives, in parallel. Turn on Process data in order in the scenario settings if order matters, such as stock updates.
Here’s the catch with scheduling a webhook instead. Make then processes only the Maximum number of results per run, and the default is 2. Schedule it hourly and 40 orders a day turns into a queue that never empties.
That queue has a ceiling, too. You get 667 queue items for every 10,000 credits you license, up to 10,000. When it’s full, Make answers new requests with a 400 “Queue is full” and drops them.
Two more limits. Make accepts 300 webhook requests per 10 seconds and returns 429 above that. A webhook that isn’t attached to any scenario for 5 days is switched off and starts answering 410 Gone.
Your filter catches fakes, but each rejected request still costs the trigger’s credit. Choosing between Make and n8n for this kind of work? Our Make vs n8n comparison goes feature by feature.
How to set up a webhook in Zapier
Pick Webhooks by Zapier as the trigger and choose Catch Hook. Copy the URL from the Test tab into the sending app. You need a paid plan: webhooks start on Professional, from $19.99 a month billed yearly.
Catch Hook parses the request body into fields you can map. Catch Raw Hook gives you the unparsed body plus the headers, capped at 2 MB. Use Raw when you need to check a secret header with a Filter step, since filters don’t use tasks.
Watch three things.
- Arrays multiply runs. If the sender batches 50 orders into one JSON array, the Zap runs 50 times. Every action step counts a task on each run.
- Turning a Zap off isn’t instant. Zapier starts returning 404 for a paused Zap, but the change can take several hours. Until then, requests still get a 200.
- The URL belongs to the owner. Transfer the Zap to a teammate and the URL changes, because it carries the owner’s Zapier ID. Update the sending app or the Zap goes quiet.
Zapier also starts throttling with 429 errors above 20,000 instant-trigger requests every 5 minutes per user. Few small businesses ever get close. Our Zapier vs n8n breakdown covers when that per-task pricing starts to sting.
How do you test a webhook before connecting the real app?
Send it a fake event yourself with curl. It’s faster than placing a real order, and you control every field.
curl -X POST "https://your-n8n-domain/webhook-test/new-order" \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: change-me" \
-d '{"order_id": 1042, "total": 59.00, "email": "[email protected]"}'
Swap in your own URL. A 200 reply, plus the data showing up in your tool, means the plumbing works. A 401 or 403 means the secret header is wrong or missing. That’s exactly what a stranger should see.
Test the ugly cases too: a missing field, an empty body, the same order sent twice. Real senders do all three eventually.
How do you keep a webhook URL safe?
Treat the URL like a password, and don’t trust it on its own. Anyone who finds it can send your workflow fake orders.
Your first layer is a shared secret in a header, set up in the n8n, Make and Zapier steps above. It stops random traffic, but anyone who sees one request can copy the header.
The stronger layer is a signature. Apps like Stripe sign every request with HMAC SHA-256 using a secret only you and they know. Change one byte of the body and the signature fails.
Stripe also puts a timestamp inside the signed data, and its libraries reject anything older than 5 minutes. That stops someone replaying a real request they captured. Here’s the same check in plain Python, if you run your own receiver:
import hashlib
import hmac
import time
SECRET = b"whsec_your_signing_secret"
def is_genuine(raw_body: bytes, timestamp: str, signature: str) -> bool:
# Reject anything older than 5 minutes (stops replayed requests)
if abs(time.time() - int(timestamp)) > 300:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(SECRET, signed, hashlib.sha256).hexdigest()
# Constant-time compare, never ==
return hmac.compare_digest(expected, signature)
Two details break most home-made versions. You must sign the raw body exactly as it arrived, before any JSON parsing. And you compare with compare_digest, never ==, so timing can’t leak the answer.

Webhook signatures are one more flavour of the keys and tokens in our API authentication explainer. Same idea: prove who’s calling before you act on it.
Why do webhooks arrive twice, or not at all?
Because senders retry, and some don’t. Your workflow has to cope with both.
Stripe retries a failed delivery for up to three days in live mode, with growing gaps. Its docs say plainly that you may get the same event more than once, and that events can arrive out of order.
GitHub does the opposite. If your endpoint takes longer than 10 seconds to answer, GitHub marks the delivery failed and doesn’t retry it on its own. That event is gone unless you redeliver it.
The rules are simple, even if building them isn’t:
- Answer fast. Reply 200 first, then do the slow work. In n8n, that’s Respond Immediately.
- Store the event ID. Before acting, check whether you’ve seen it. If you have, reply 200 and stop.
- Don’t trust the order. If “paid” arrives before “created”, fetch the latest state from the app’s API instead of guessing.
A duplicate “order paid” that sends two receipts or ships two parcels is how most webhook horror stories start. Our guide to idempotency and retries shows the pattern in more depth.
Which tool handles webhooks best?
n8n, for most people who’ll run more than a handful of events a day. The rest depends on your volume and skills.
Pick n8n if you want the most control per euro, because every execution counts once however many steps it has. It also has built-in header, basic and JWT auth, an IP allowlist and response control, plus a free self-hosted edition.
Pick Make if you like visual scenarios and your events arrive in steady volumes. Webhooks there cost a credit per run, not per check, and the queue gives you a buffer when your credits run out.
Pick Zapier if your team already lives in it and speed matters more than cost. Webhooks won’t lower your task bill there, but they’ll cut the wait from minutes to seconds.
Skip webhooks if the source app doesn’t offer them, or the data only changes once a day. A daily poll is 30 checks a month on any plan. It isn’t worth the security work.
Frequently asked questions
Can I use webhooks on a free plan?
On n8n, yes, if you self-host the free Community Edition; n8n Cloud starts with a free trial. On Make, webhooks work on the Free plan, within its 1,000 credits a month. Zapier is the exception: Webhooks by Zapier needs the Professional plan or higher.
Do webhooks work on localhost?
Not directly. The sending app needs a public HTTPS address it can reach, and your laptop isn’t one. For testing, use a tunnelling tool such as ngrok, or the sender’s own CLI, like Stripe’s. In production, use the URL your n8n, Make or Zapier account gives you.
What happens to Make webhooks when I run out of credits?
Your scenarios stop, but incoming webhook requests wait in the queue up to your queue limit. When you add credits or the month resets, Make works through them. Anything that arrives after the queue is full gets a 400 and is lost unless the sender retries.
Can one webhook event trigger several workflows?
In Zapier, yes. Join the last part of several Catch Hook URLs with commas into one URL, as long as one user owns all the Zaps. In n8n or Make, give the sending app several URLs if it allows that, or have one workflow call the others.
Should a webhook use GET or POST?
Use POST whenever the request carries data, which is almost always. GET requests put data in the URL, where it ends up in server logs. n8n and Zapier both accept GET for simple pings, which is handy for a quick test from a browser.
How big can a webhook payload be?
n8n accepts up to 16 MB, and you can raise that if you self-host. Zapier allows 10 MB for Catch Hook and 2 MB for Catch Raw Hook. For files, send a download link in the payload instead of the file itself.
Where can I see webhooks that failed?
In n8n, open the workflow’s Executions tab. In Make, go to Webhooks in the sidebar and open the Logs tab, which keeps 3 days of history, or 30 days on Enterprise. In Zapier, check Zap History. The sending app usually has its own delivery log too.
The bottom line
Webhooks are the cheapest and fastest trigger in automation, as long as the app you’re watching sends them. Use the Webhook node in n8n if cost per run matters most. Use a Custom webhook in Make for visual scenarios, and a Catch Hook in Zapier when your team is already there and needs speed.
One warning: never leave a test URL in production, and never act on a request you haven’t verified.
Start with one workflow you’re polling today. Swap its trigger for a webhook, send the curl test, and watch the execution count drop.



