Skip to main content

Webhooks

What It Is

Webhooks are a communication technique where one system sends real-time data to another system using an HTTP callback when an event happens.

Instead of asking again and again for updates, the receiving system waits for the sender to call its webhook URL.

Webhook = Event happens -> Sender calls receiver URL

Simple Meaning

Think of webhooks like this:

Don’t call me, I’ll call you.

Instead of continuously checking whether something happened, you provide a callback URL.

When the event happens, the other system sends data to that URL automatically.


How Webhooks Work

A webhook flow is event-driven.

1. Client registers a callback URL
2. Sender stores that URL
3. Event happens on sender system
4. Sender sends HTTP POST request to callback URL
5. Receiver processes the event

Example:

Payment succeeds -> Payment provider calls your webhook endpoint

Flow Diagram

Your App                         External System
| |
| ---- Register callback URL -------> |
| |
| | Event happens
| |
| <---- POST /webhook --------------- |
| |
| ---- 200 OK ----------------------> |
| |

Webhook vs Polling

Polling means the client repeatedly asks for updates.

Client repeatedly asks -> inefficient

Webhook means the sender notifies the receiver when something happens.

Server sends automatically when event happens -> efficient

This makes webhooks more efficient for event-based communication.


Real-World Example

A payment gateway like Stripe can send webhook events to your backend.

You provide a webhook URL:

https://yourapp.com/webhook

When payment succeeds, the payment system sends:

POST /webhook
Content-Type: application/json

Payload example:

{
"event": "payment.success",
"amount": 1000
}

Your backend receives this event and updates the payment status.


Receiver Example

This Express server receives webhook events.

const express = require("express");

const app = express();

app.use(express.json());

app.post("/webhook", (req, res) => {
const event = req.body;

console.log("Webhook received:", event);

if (event.event === "payment.success") {
console.log("Payment successful");
}

res.status(200).send("OK");
});

app.listen(3000, () => {
console.log("Webhook server running");
});

The receiver should return a success response after processing the webhook.

Receiver gets event -> processes it -> returns 200 OK

Sender Example

This example simulates a webhook sender using Axios.

const axios = require("axios");

axios.post("http://localhost:3000/webhook", {
event: "payment.success",
amount: 1000,
});

In real systems, this sender is usually an external service like a payment provider, GitHub, CI/CD system, or email provider.


Key Characteristics

Webhooks are commonly used for backend-to-backend communication.

CharacteristicMeaning
Event-drivenRuns only when an event happens
HTTP basedUsually sends HTTP POST requests
Near real-timeReceiver gets updates quickly
Decoupled systemsSender and receiver work independently
No pollingNo repeated checking required

Payload Format

Webhook payloads are usually sent as JSON.

{
"event": "user.created",
"data": {
"id": 1,
"name": "Aman"
}
}

A good payload should include enough information for the receiver to identify and process the event.

Common fields:

  • event type
  • event id
  • timestamp
  • related data
  • status

Webhooks vs Polling

FeatureWebhooksPolling
ApproachPushPull
EfficiencyHighLow
LatencyLowHigh
Server LoadLowHigh
Request PatternOnly when event happensRepeated requests

Webhooks are better when updates are event-based.

Polling is simpler, but it creates unnecessary requests when nothing changes.


Webhooks vs SSE

FeatureWebhooksSSE
DirectionServer -> ServerServer -> Browser
ConnectionShort-livedLong-lived
Use CaseBackend eventsUI updates
TriggerEvent occursContinuous server updates
Typical PayloadJSON bodyText event stream

Use webhooks for backend system events.

Use SSE when a browser UI needs a live stream of updates from the server.


Security

Webhooks should be protected because the endpoint is publicly reachable.

Signature Verification

The sender signs the payload using a shared secret.

The receiver verifies the signature before trusting the request.

const crypto = require("crypto");

const expectedSignature = crypto
.createHmac("sha256", SECRET)
.update(JSON.stringify(req.body))
.digest("hex");

This helps confirm that the request came from a trusted sender.

HTTPS Only

Always use HTTPS for webhook endpoints.

HTTPS helps prevent man-in-the-middle attacks.

IP Whitelisting

Some systems allow accepting requests only from trusted IP addresses.

This is optional, but it can add another layer of protection.


Retry Mechanism

Webhook delivery may fail if the receiver is down or returns a non-success response.

If webhook delivery fails, the sender may retry.

Common retry strategy:

Exponential backoff

This means retries happen with increasing delay.

Example:

Retry after 1 second
Retry after 5 seconds
Retry after 30 seconds
Retry after 2 minutes

The receiver should be ready to handle repeated delivery attempts.


Idempotency

A webhook event may be delivered more than once.

So the receiver should be idempotent.

Idempotent handler = processing the same event multiple times does not create duplicate side effects

Example:

if (alreadyProcessed(event.id)) {
return;
}

This prevents problems like:

  • duplicate payments
  • duplicate emails
  • duplicate database updates
  • duplicate order status changes

Challenges

Webhooks are useful, but they need careful handling.

Common challenges:

  • duplicate events
  • retry handling
  • failed deliveries
  • signature validation
  • debugging difficulty
  • no guarantee of delivery order
  • network failures
  • receiver downtime
  • endpoint must be publicly accessible
  • payload versioning issues
  • local testing needs tunneling tools
Webhook receivers must be secure, reliable, and idempotent.

Use Cases

Common webhook use cases:

  • payment notifications
  • GitHub push events
  • GitHub pull request events
  • CI/CD triggers
  • email delivery updates
  • Slack bot events

Webhook is a good choice when one system needs to notify another system after an important event.


Webhook Table

AreaExplanation
Communication typeEvent-driven
DirectionServer to server
ProtocolHTTP, usually POST
ConnectionShort-lived
EfficiencyHigh
PayloadUsually JSON
Security needSignature verification and HTTPS
Main riskDuplicate events and delivery failures

Basic Checklist

Create a public webhook endpoint
Accept HTTP POST requests
Parse JSON payload
Validate event type
Verify webhook signature
Use HTTPS
Return 200 OK after successful processing
Handle retries safely
Make the handler idempotent
Avoid duplicate processing
Log webhook events for debugging
Handle payload version changes carefully

Interview Style Answer

Webhooks are an event-driven communication technique where one system sends data to another system using an HTTP callback when an event occurs. Instead of polling repeatedly, the receiver provides a callback URL, and the sender calls that URL using an HTTP POST request when something happens, such as a payment success, GitHub push, CI/CD trigger, or email delivery update. Webhooks are efficient, near real-time, and decouple systems, but they require security and reliability handling. A production webhook receiver should use HTTPS, verify signatures, handle retries, process duplicate events safely using idempotency, and log events for debugging.


One-Line Summary

Webhook = A server-to-server HTTP callback triggered automatically when an event happens.

Final Mental Model

Polling -> You keep asking
Webhook -> They call you when it happens

Efficient for backend events, but must be secure and idempotent.