Imagine refreshing your email inbox manually every 30 seconds to see if anything new arrived. Exhausting, wasteful — and yet that's exactly how a lot of software checks for updates: it polls, asking "anything new yet? anything new yet?" over and over.
Webhooks flip that around. Instead of you constantly asking, the other service just tells you the moment something happens. They're one of the most useful glue mechanisms on the web, and they're refreshingly simple once they click.
What a webhook actually is
A webhook is just an HTTP request that one service sends to a URL you provide, when an event happens.
You say: "When X happens, POST the details to https://my-app.com/hook." From then on, the moment X occurs, the service fires off a request to your URL with a payload describing the event:
POST https://my-app.com/hook
{ "event": "payment.succeeded", "amount": 4200 }
That's it. It's sometimes called a "reverse API": with a normal API you call them; with a webhook they call you.
Webhooks vs. polling
The alternative to webhooks is polling — repeatedly asking an API "anything new?" The difference is stark:
| Polling | Webhooks | |
|---|---|---|
| Who initiates | You ask, repeatedly | They notify you |
| Timeliness | Delayed (between checks) | Near-instant |
| Efficiency | Wasteful (mostly empty checks) | Efficient (only when there's news) |
| Load | Constant requests | Only on events |
| Best when | You need data on your schedule | You need to react to their events |
For "tell me when something happens," webhooks win on every axis. Polling still has its place (when you need a full sync, or the other side has no webhooks), but for event reactions, webhooks are the right tool.
What you'll do with them
Webhooks power a huge amount of everyday automation:
- A payment provider tells your app a charge succeeded or failed.
- A git host tells your CI to start a build on push.
- A monitoring tool tells your systems an incident fired (so you can auto-create a ticket, post to chat, or trigger a runbook).
- A form tool tells your CRM a new lead arrived.
Receiving a webhook well
The "receiving" side is a small endpoint on your server. A few practices keep it robust:
1. Respond fast — do work later
Reply with a 200 quickly (within a couple of seconds). If there's heavy processing to do, queue it and handle it after responding. Senders often treat a slow response as a failure and retry.
2. Verify it's genuine
Your webhook URL is public, so anyone could POST to it. Reputable senders sign their requests (usually an HMAC signature in a header). Verify that signature so you only act on real events — and always serve the endpoint over HTTPS.
3. Expect duplicates — be idempotent
Webhooks can arrive more than once (retries, network hiccups). Design your handler so processing the same event twice is harmless — for example, check an event ID you've already seen. (Idempotency is a recurring theme in reliable systems.)
4. Handle retries and failures
If your endpoint is down, good senders retry with backoff. Make sure a brief outage on your side doesn't mean lost events — and log what you receive so you can replay if needed.
Sending webhooks well
If you're the one sending webhooks to your users:
- Sign your payloads so receivers can verify them.
- Retry on failure with exponential backoff.
- Keep payloads stable and documented — people build on them.
- Send over HTTPS only.
The bottom line
| Idea | In one line |
|---|---|
| What | An HTTP POST sent to your URL when an event happens. |
| vs polling | Push, not pull — instant and efficient. |
| Receiving | Respond fast, verify signatures, be idempotent. |
| Sending | Sign, retry, document, HTTPS. |
Webhooks are the quiet workhorses of integration — the reason your tools "just know" when something happened elsewhere. Once you start thinking in events-pushed-to-you instead of constantly-asking, a lot of automation gets simpler and faster.
WatchFor uses webhooks as one of its notification channels — sending a structured payload to your endpoint the instant an incident fires. And if you build APIs, don't forget to monitor them too.