What Is a Webhook? A Plain-English Explanation
The Short Version
A webhook is an HTTP request that one service sends to another when something happens. Instead of you asking "did anything change?" over and over, the service tells you the moment it does.
Think of it like a doorbell. Without one, you would have to keep opening the door to check if someone is there. With a doorbell, you just wait and get notified.
How It Works
The setup is straightforward. You give a service a URL — your webhook endpoint. When a specific event occurs, the service sends an HTTP POST request to that URL with a JSON payload describing what happened. Your server receives the request, reads the payload, and does whatever it needs to do: update a database, send an email, trigger a deploy, or anything else.
The flow looks like this:
- You register a webhook URL with the sending service.
- An event happens (a payment succeeds, a commit is pushed, a message is posted).
- The service sends a POST request to your URL with event data.
- Your server processes the request and returns a 200 status to acknowledge receipt.
If your server does not return a 200 (or returns nothing because it is down), most services will retry the delivery several times over the next few hours.
Real Examples
Webhooks are everywhere in modern software. Here are three you have probably encountered:
Stripe sends a webhook when a payment succeeds, fails, or is refunded. Your application receives the event and updates the customer's subscription status, sends a receipt, or flags the account. Without webhooks, you would have to poll Stripe's API repeatedly to check if anything changed — wasteful and slow.
GitHub sends a webhook when code is pushed, a pull request is opened, or an issue is created. CI/CD systems like GitHub Actions, Jenkins, and Vercel all rely on these webhooks to trigger builds and deployments automatically.
Slack sends webhooks when users interact with your app — slash commands, button clicks, message actions. Your server receives the interaction payload and responds with updated content.
Webhooks vs. Polling
The alternative to webhooks is polling: making repeated API calls on a schedule to check for changes. Polling works, but it has clear downsides:
- Latency — If you poll every 60 seconds, you could be up to 59 seconds behind. Webhooks deliver in near real-time.
- Wasted requests — Most poll responses will be "nothing changed." Webhooks only fire when there is something to report.
- Rate limits — Frequent polling eats into API rate limits. Webhooks do not count against your quota.
Polling still makes sense when the sending service does not support webhooks, or when you need to pull data that does not map to discrete events (like fetching an analytics report). For everything else, webhooks are the better choice.
Common Gotchas
A few things to watch for when building webhook handlers:
- Verify signatures. Most services sign webhook payloads with a secret so you can confirm the request actually came from them. Always verify this. Skipping it opens you up to spoofed requests.
- Respond fast. Return a 200 as quickly as possible. If your handler takes too long, the sender may time out and retry, causing duplicate processing. Do heavy work asynchronously.
- Handle duplicates. Retries mean you might receive the same event more than once. Use the event ID to deduplicate.
Test Your Webhooks
Before writing handler code, it helps to see what the actual payloads look like. HookTest gives you a public URL instantly — point any webhook sender at it and inspect every request in real-time. No signup, no installation.
For a deeper dive on local testing, read How to Test Webhooks Locally Without ngrok. Working with Stripe? Check out How to Debug Stripe Webhooks.