← All posts

What is a webhook? A plain-English guide

November 11, 2026 · Ensue team

Stripe and Shopify each sending a New order message to Your app

You’ve probably used webhooks today without knowing it. When a customer pays on your website and your accounting tool updates a second later, or a teammate merges code and a Slack message pops up, a webhook did that.

This guide explains what a webhook is, how it differs from the alternatives, and where it goes wrong, using everyday examples. You don’t need to write code to follow it.

The short answer

A webhook is a message one app sends to another app, automatically, the moment something happens.

That’s it. Instead of you checking a service over and over (“any new orders yet?”), the service tells you when there’s news (“new order, here are the details”).

An everyday analogy: the pizza shop

Imagine you order a pizza and want to know when it’s ready. There are two ways to find out.

  1. You call the shop every five minutes and ask, “Is my pizza ready yet?” Most calls are wasted (“not yet”), and you might still find out late.
  2. You give them your number and they call you when it’s out of the oven. One call, at the right moment.

The first approach is called polling. The second is a webhook. The phone number you left is your webhook URL: the address where the other side should send the news.

A side-by-side comparison. On the left, polling: an app asks a service "Any new orders?" three times and gets "No", "No", then "Yes". On the right, a webhook: the service sends one message, "New order! Here are the details", the moment a customer orders, and the app replies "Got it".

Why people use them

Polling Webhook
Speed As slow as your check interval Near-instant
Wasted effort Most checks find nothing Only runs when something happens
Cost Constant traffic, even when idle Traffic matches real activity
Setup You write the checking loop You give a URL, the service does the rest

Because webhooks are fast and cheap, almost every modern service offers them.

Real examples you’d recognise

  • Stripe: a payment succeeds, so Stripe sends payment_intent.succeeded to your app, which marks the order as paid and emails the receipt.
  • Shopify: a customer places an order, and Shopify notifies your warehouse system so it can start picking and packing.
  • GitHub: someone pushes code, and your build system starts a new test run.
  • Calendly: someone books a call, and your CRM creates a lead and assigns it to a salesperson.
  • Twilio: a text message arrives, and your support tool opens a ticket.

In every case, the pattern is the same: something happens in service A, and service A tells service B.

What’s inside a webhook

A webhook is a small web request, a bit like a letter with an address on the envelope and a note inside. Here’s what a payment notification from Stripe looks like:

A webhook request shown as a code window. Callouts point to the address (POST /webhooks/stripe), the signature header, the event type payment_intent.succeeded, and the details: amount 4900, currency usd, customer cus_J3k.

Four parts matter:

  • The address is your URL. You choose it and give it to the sender once.
  • The signature is a secret stamp that proves the message really came from Stripe and not someone pretending to be them. Skipping this check is one of the most common security mistakes.
  • The event type says what happened (payment_intent.succeeded, order.created, ticket.closed).
  • The details are the facts, usually as JSON, a simple text format both humans and software can read.

The 4900 above means 4,900 cents, so $49.00. Many payment services count in the smallest currency unit to avoid rounding errors.

How to set one up

Setting up a webhook usually takes three steps, and you can do most of it from a settings screen:

  1. Get a URL that can receive messages. This is the part that needs a developer or a tool.
  2. Paste the URL into the sending service, usually under Settings → Webhooks or Developers.
  3. Choose the events you care about, like “payment succeeded” and “refund created”, so you’re not flooded with everything.

Then the service sends a test event. If your URL answers with a success code (a 200), you’re connected.

Where webhooks go wrong

Webhooks are simple on a good day. The trouble starts on a bad one. Almost every team that depends on them runs into the same four problems.

1. Your server is down when the message arrives. A deploy, a restart or an outage means the sender gets no answer. Some services retry for a while and then give up. That order is now missing from your system, and nobody tells you.

2. The same message arrives twice. Senders retry when they don’t get a quick reply, so duplicates are normal. Without protection, a customer can be charged, emailed or shipped to twice.

3. A flood arrives all at once. A flash sale or a big import can send thousands of messages in seconds, more than your system can swallow.

4. Nobody can tell what happened. When a customer says “I paid but nothing happened”, you need to know whether the message arrived, was understood, and was acted on. Without a record, you’re guessing.

How a gateway fixes this

A webhook gateway sits in the middle. Senders talk to the gateway, and the gateway talks to your app.

Stripe, Shopify and GitHub send webhooks into Ensue Gateway, which verifies the sender, drops duplicates, queues and retries, and keeps a timeline, then delivers to Your app and Your CRM.

Because the gateway is always on, it answers senders immediately and keeps every message safe, even when your own systems are down. Then it hands the messages to your app at a pace the app can handle.

That is what Ensue Gateway does. For each sender you get a unique URL. Ensue then:

  • checks the signature before anything else, and refuses fakes,
  • ignores duplicates, so a repeat creates nothing,
  • queues and retries with increasing waits when your app is unavailable,
  • pauses a failing destination instead of hammering it, and
  • records a timeline for every message.

Here is what that last part looks like when your server has a bad moment:

An Ensue event page for payment_intent.succeeded, marked Delivered. The timeline shows it was received and verified at 12:04:11, attempt 1 timed out, and attempt 2 returned 200 OK in 142 milliseconds. A note reads: your server was down for 30 seconds, the webhook was kept and delivered on retry, nothing was lost.

Without a gateway, that payment would have vanished the moment your server was restarting. With one, it was delivered 40 seconds later and you can see exactly why it was late.

Try it yourself

You can see a webhook arrive in about five minutes. Here is the shortest path:

  1. Create an Ensue account and add a destination (any URL that can receive requests).
  2. Create a source. Ensue gives you a URL like https://hooks.getensue.com/in/<token>.
  3. Connect them with a flow.
  4. Send yourself a test message:
curl -X POST https://hooks.getensue.com/in/<token> \
  -H "content-type: application/json" \
  -d '{"type":"test.ping","data":{"hello":"world"}}'

Open the event in the dashboard and you’ll see its timeline. The quickstart walks through each step.

Quick glossary

Term Meaning
Webhook An automatic message from one app to another when something happens
Webhook URL / endpoint The address that receives the messages
Event The thing that happened, like “order created”
Payload The details sent with the event
Signature A secret stamp proving the message is genuine
Retry Sending a failed message again later
Idempotent Safe to run twice with the same result, such as “mark order 1042 as paid”
Polling Repeatedly asking a service whether anything new has happened

Frequently asked questions

Is a webhook the same as an API? Not quite. With an API, you ask and the service answers. With a webhook, the service speaks first. Most services offer both, and they work well together.

Do I need to be a developer to use webhooks? To receive them, you need somewhere to point the URL. Many no-code tools (Zapier, Make and similar) do this for you. Gateways like Ensue also let you route and filter without writing a server.

Are webhooks secure? They can be, if you check the signature on every message. An unverified webhook URL accepts anything sent to it.

What happens if my system is offline? It depends on the sender. Some retry for hours, others give up quickly. A gateway removes the guesswork by holding the message until you’re back.

What does the 200 mean? It’s a standard “received, thanks” reply. If your URL doesn’t answer with a success code, the sender assumes the message failed and may try again.


Never lose a webhook again.

Ensue Gateway gives every sender its own URL, verifies and queues each event, and delivers it with retries and a full timeline.

Start the quickstart →