Webhooks: The "Don't Call Us, We'll Call You" Pattern

Normal API calls work like checking your mailbox — you walk to the mailbox, look inside, walk back. If there's nothing there, you wasted a trip. If you want to know the moment something arrives, you'd have to check every five minutes. Webhooks flip this model. Instead of you asking "did anything happen?" over and over, you give the service a URL and say "call me when something happens." The service does the work. You just listen. This is how most automation tools get triggered by real-world events, and understanding webhooks is what makes the jump from "I can schedule things" to "I can react to things."

What The Docs Say

A webhook is an HTTP callback. You register a URL with a service — "when event X happens, send an HTTP POST request to this URL with the event data." When the event occurs, the service constructs a request containing the event details (the payload) and sends it to your URL. Your endpoint receives the request, processes the data, and responds with a 200 status code to confirm receipt.

The documentation for webhook-enabled services typically covers: which events you can subscribe to (Stripe offers webhooks for payment_intent.succeeded, customer.created, invoice.paid, and dozens more), what the payload looks like for each event (the JSON structure of the data sent with the webhook), how to register your endpoint URL (usually through a dashboard or an API call), and how to verify that the webhook is legitimate (security).

The registration process varies by service. Stripe has a webhook section in its dashboard where you paste your endpoint URL and select which events to listen for. Ghost lets you set up webhooks in the integrations settings — you specify a URL and choose the trigger event (post published, member added, etc.). GitHub has webhook settings per repository where you configure a URL and select event types (push, pull request, issue, etc.). The concept is always the same: you tell the service where to send data and what events should trigger the delivery.

What Actually Happens

The first question everyone asks is: "Where does the webhook send data to?" The answer depends on your setup. If you're using n8n, you create a Webhook node, and n8n gives you a URL — something like https://your-n8n-instance.com/webhook/abc123. That URL is your endpoint. When the service sends a POST to that URL, it triggers your n8n workflow. Zapier works similarly — "Webhooks by Zapier" creates a unique URL that triggers a Zap when data arrives. Make has a webhook module that does the same thing.

For these automation tools, the URL problem is solved for you. You don't need your own server. The platform provides the endpoint. This is the most common way non-developers use webhooks — through an automation tool that handles the endpoint hosting.

If you're not using an automation platform, you need something listening at the URL. That means a server — a small application running somewhere that can receive HTTP requests. This could be a serverless function on AWS Lambda, a simple Express.js app on Railway, or a Python Flask app on Render. Setting up a webhook receiver from scratch is where this topic crosses from "API literacy" into "light programming," and for most non-developers, an automation tool is the right answer.

The webhook payload — the data that arrives with the POST request — is the part that matters for your workflow. When Stripe sends a payment_intent.succeeded webhook, the payload contains the payment amount, currency, customer ID, payment method, and metadata. When Ghost sends a post.published webhook, the payload contains the post object with its title, content, tags, author, and URL. The payload is how you know what happened and extract the data you need for subsequent workflow steps.

Here's a practical example. You want to automatically post to Slack whenever someone subscribes to your Ghost newsletter. You set up a webhook in Ghost triggered by member.added, pointing to your n8n webhook URL. When someone subscribes, Ghost sends a POST to n8n with the new member's data — name, email, subscription date. Your n8n workflow receives that data, extracts the member's name, and sends a message to your Slack channel: "New subscriber: Jane Doe." No polling. No scheduled checks. It happens in real time because the webhook fires the instant the event occurs.

Webhook security is the thing the tutorials skim past and the production deployment teaches you the hard way. The problem: anyone who knows your webhook URL could send fake data to it. If your n8n workflow processes whatever data arrives at the webhook URL without verification, an attacker could trigger your workflow with fabricated event data. The solution is webhook signature verification — most services include a cryptographic signature in the webhook request headers, generated using a shared secret. Your endpoint can verify that signature to confirm the request actually came from the service and wasn't spoofed.

In practice, the signature verification looks like this: the service hashes the request body using HMAC-SHA256 with a shared secret (provided when you set up the webhook) and includes the hash in a header like X-Hub-Signature-256 (GitHub) or Stripe-Signature (Stripe). Your endpoint performs the same hash operation and compares the result. If they match, the request is legitimate. n8n's Webhook node supports header-based authentication and can be configured to validate signatures — it's an option in the node settings that's worth enabling for any production workflow.

Common webhook problems worth knowing about:

Your endpoint is unreachable. If the webhook URL returns an error or doesn't respond, most services will retry — typically with exponential backoff over hours or days. After enough failures, they'll disable the webhook and notify you (by email, usually). If your n8n instance goes down, you'll miss webhooks until it comes back up. Some services replay failed webhooks. Others don't.

Duplicate events. Services sometimes send the same webhook more than once — network hiccups, retry logic, or the service's own infrastructure can cause duplicates. Your workflow should handle this gracefully, ideally by checking an event ID to see if you've already processed it. For simple workflows, duplicates might not matter. For workflows that create records or send emails, they definitely matter.

Timeout errors. Most services expect your endpoint to respond within 5-30 seconds [VERIFY — timeout thresholds vary by service]. If your workflow takes longer to process, the service might consider the delivery failed and retry. The best practice is to respond with 200 immediately (acknowledging receipt) and process the data asynchronously.

Payload size. Some webhook payloads are small (a few hundred bytes for a simple event notification). Others are large — a Ghost post.published webhook includes the full post content, which could be several kilobytes. This usually isn't a problem, but if you're logging webhook data or passing it through multiple steps, be aware that payload size affects performance.

When To Use This

Webhooks are the right choice when your workflow needs to react to events in real time — or close to real time. Payment received, form submitted, post published, member signed up, code pushed, issue created. Any "when X happens, do Y" workflow is a webhook use case. This is the bread and butter of automation platforms, and understanding the mechanism makes you better at building and debugging these workflows.

The alternative to webhooks is polling — making periodic API calls to check if something changed. "Every 5 minutes, check if there's a new post." Polling works, but it's wasteful (you make many requests that return nothing new), it's delayed (you only find out about events at the polling interval), and it consumes your API rate limit quota. Webhooks are immediate, efficient, and don't consume rate limits because the service initiates the request, not you.

In automation tools, the webhook trigger is the real-time trigger. When Zapier says a trigger runs "instantly" (as opposed to every 15 minutes), it usually means it's using a webhook rather than polling. The same is true in n8n — the Webhook node triggers immediately when data arrives, while the Schedule Trigger node runs at intervals. Knowing this distinction helps you choose the right trigger and understand why some Zaps react instantly while others have a delay.

When To Skip This

If your workflow doesn't need real-time triggering — a daily report, a weekly sync, a scheduled batch process — polling or scheduled triggers are simpler and don't require setting up webhook endpoints. Not everything needs to be instant. A workflow that syncs your CRM contacts to a spreadsheet once a day doesn't benefit from a webhook trigger. A scheduled run at midnight is simpler and achieves the same result.

Also skip webhooks if the service you're connecting to doesn't support them. Not every API offers webhooks — some only support polling. In that case, scheduled API calls are your only option, and that's fine. The automation tool handles the scheduling and the API calls. You just set the interval and move on.


This is part of CustomClanker's API Literacy series — the thing nobody explains before you try to connect two tools.