What Is a Webhook? How It Works and How It Differs From an API

What is a webhook, in one sentence?
A webhook is an automatic HTTP request that one system sends to a URL you choose the moment a specific event happens. In other words, you do not ask for the data; the other side tells you when something changes. Payment confirmations, new form entries and code pushes often travel this way.
Here is a simple analogy. Calling the courier every hour to ask whether your parcel has arrived is polling. The courier texting you when the parcel reaches your door is a webhook. With the second approach, you stop wasting effort and the courier stops answering pointless calls.
In this guide, Talha Aslan and team answer the question "what is a webhook" at a conceptual level, yet with enough depth for real projects. First, we explain the event-driven push model. Then we compare webhooks with API polling and WebSocket in one table. Finally, we cover signature checks, retries, idempotency and security. We skip long code blocks on purpose; the goal is to make the logic click.
What is a webhook doing when we call it "event-driven push"?
Event-driven push means data moves when an event occurs, not when someone requests it. In a classic API call, the client goes to the server and says "give me the latest orders." With a webhook, the direction flips. The server goes to the client's address as soon as the event happens.
The model has three parts. First, there is the system that produces the event, such as a payment provider. Second, there is the event definition, for example "payment succeeded" or "subscription canceled." Third, there is the listener URL on your server, also called the endpoint. When the event fires, the provider usually sends a POST request with a JSON body to that endpoint.
So a webhook is not a new protocol. It is an agreement that runs over plain HTTP: "If this event happens, notify that address in this format." That simplicity explains why it is everywhere. Payment platforms, code hosts, form tools, email services and CRM systems offer it almost by default.
How does a webhook work, step by step?
To make the flow concrete, let us walk through a typical webhook lifecycle. Details vary between providers. Still, the skeleton stays nearly the same.
- You prepare a public listener URL on your server that runs over HTTPS.
- You register this URL in the provider's dashboard or API and pick the events you want.
- The provider gives you a shared secret, or you set one yourself.
- When the event occurs, the provider packages it as JSON, signs it with the secret and POSTs it to your URL.
- You verify the signature, queue the request and quickly reply with a 2xx status code.
- The real work, such as updating an order or sending an email, then runs in a separate background job.
- If no reply arrives or an error comes back, the provider may retry later under its own policy.
Teams skip step five more than any other. Many try to finish all the work inside the request. The reply then gets slow, and the provider marks the delivery as failed. The official Stripe webhook documentation also advises you to return a successful status quickly, before any complex logic runs.
What is the difference between a webhook and an API?
Put simply, an API is a door and a webhook is the doorbell that rings from the other side. An API is a set of rules one piece of software offers so others can talk to it. You call it whenever you want. A webhook usually ships as part of an API, but the provider starts the conversation.
Therefore, "webhook or API?" is a slightly misleading question. Most integrations use both. For example, a payment provider says "this payment succeeded" through a webhook. Then you call the same provider's API with the payment ID to fetch the trusted details.
If you want the basics of APIs from scratch, our guide to what an API is covers endpoints, requests and responses. For the flexible query model, see our GraphQL vs REST article. Here, we focus only on the webhook side.
So what is a webhook good for, compared with a plain call? A practical rule helps. If you need "tell me when something changes," think webhook. If you need "let me pull data whenever I want," a direct API call is enough.
How do you choose between polling and webhooks?
Polling means the client asks the server at fixed intervals whether anything is new. Setup is easy because you do not need a public URL. However, most requests come back empty and waste resources on both sides.
In addition, polling delay depends on your interval. If you ask every five minutes, you may notice a payment up to five minutes late. If you shorten the interval, request volume grows. Then you may hit the provider's rate limit.
A webhook, on the other hand, arrives at event time and creates no empty requests. That said, you must publish a listener, secure it and plan for missed events. In practice, the most robust approach is often a hybrid. You use webhooks for instant updates and a scheduled reconciliation job that polls now and then.
Example scenario: an online store receives payment confirmations by webhook. Once a night, it also pulls the day's payments from the provider's API and compares them with its own records. As a result, even a notification missed during server maintenance gets caught the next morning.
Webhook vs API polling vs WebSocket: comparison table
If you still wonder what is a webhook compared with its neighbors, this table helps, because people mix these three approaches up all the time. The table below sums up which one answers which question. The values are conceptual; real performance depends on your infrastructure.
| Feature | Webhook | API polling | WebSocket |
|---|---|---|---|
| Who starts the exchange? | The server that produces the event | The client, at regular intervals | The client opens it, then both sides talk |
| Connection type | One HTTP request per event | One HTTP request per check | Long-lived open connection |
| Latency | Close to event time | Depends on the interval | Very low, real time |
| Empty requests | None | Many | None, but the link stays open |
| Typical use | Server-to-server notifications | Simple integrations, reconciliation | Live chat and dashboards in the browser |
| Needs a public URL? | Yes | No | Yes, on the server side |
| Handling missed data | Retries plus reconciliation | Naturally asks again | Needs reconnect logic |
For a deeper look at WebSocket, read our WebSocket guide. In short, WebSocket streams live data to a user interface. A webhook carries event news between two servers.
What does a webhook request contain?
In practice, a webhook request is an ordinary HTTP POST. Even so, its content follows a pattern. The body is usually JSON and carries the event type, a unique ID, a creation time and the related object.
- Event type: A field such as "payment succeeded" or "push" that says what happened.
- Event ID: A unique value per event, which is critical for filtering duplicates.
- Timestamp: When the event occurred, which helps you block replayed requests.
- Data object: The actual content, such as a payment, a form entry or a repository change.
- Signature header: A signature of the body made with the secret, which proves the sender.
Specifically, header names differ between providers. For example, GitHub sends the signature in its own header as an HMAC based on SHA-256. Stripe, in contrast, puts the signature and a timestamp together in its header. So always follow the current documentation of the service you use.
If payload formats confuse you, our YAML vs JSON article is a good place to start.
Why is webhook signature verification essential?
Because your listener URL is public, risk starts at once. Anyone who learns it can send a fake "payment succeeded" request. Without signature checks, your system might confirm an order nobody paid for. This is the most basic rule of webhook security.
The fix is a method called HMAC. HMAC (Hash-based Message Authentication Code) combines the message with a secret key and runs both through a hash function to produce a check value. The method is defined in RFC 2104. Because only you and the provider know the secret, nobody else can produce a valid signature.
The logic works like this. The provider signs the body with the key and places the signature in a header. Next, you sign the raw incoming body with the same key. If the two values match, the request is genuine; otherwise, you reject it.
Two subtle points matter here. First, compute the signature over the raw body. If you parse and re-serialize the JSON, whitespace changes and the signature fails. Second, compare the values with a constant-time function. GitHub's guide to validating deliveries also recommends this over a plain equality check.
Which HMAC verification mistakes happen most often?
The mistakes we see in the field fall into a few patterns. You can use the list below as a checklist while you review your own code.
- Losing access to the raw body because the framework parses it automatically.
- Using the test secret in production, or the other way around.
- Hard-coding the secret and pushing it to the repository.
- Comparing without stripping the prefix in the signature header, such as the algorithm name.
- Never checking the timestamp, which leaves the door open to replay attacks.
- Returning 200 even when the signature fails, which silently hides the problem.
Above all, choose a long, random value for the secret. If you want a strong one quickly, try our password generator. Store the secret in an environment variable or a secrets manager. Also rotate it from time to time; many providers accept two secrets at once during rotation.
Do not confuse signature checks with token-based login. User sessions rely on the structure we explain in our JWT guide. With webhooks, the goal is to verify the source and integrity of a message, not a user.
How do webhook retries work?
However, the internet is not perfect. Your server may be down for maintenance, the network may drop, or your code may throw an error. For that reason, serious providers retry failed deliveries under a defined policy.
The general rule goes like this. If the provider gets a non-2xx reply, or no reply in time, it treats the delivery as failed. Then it tries again with growing gaps, a pattern known as exponential backoff. Stripe's documentation says it retries failed events in live mode for up to several days. GitHub, by contrast, does not redeliver failed deliveries automatically; you redeliver them by hand from the dashboard or the API.
As you can see, policies differ a lot between services. Do not memorize retry counts, intervals or timeouts as fixed numbers. Instead, check the current values in the provider's official documentation.
Your side of the job is clear. Accept the request fast, push the work into a queue and return 2xx. That way, a slow database query will not trigger needless retries. Also choose error codes on purpose. A 4xx for a bad signature and a 5xx for a temporary outage send the provider the right signal.
Why is idempotency vital for webhooks?
Retries have a natural side effect: the same event can reach you more than once. Stripe states plainly that an endpoint might occasionally receive the same event more than once. If your code creates an order on every request, your customer may get two shipments or two invoices.
Idempotency means doing the same operation once or ten times gives the same result. For webhooks, the most practical method is to store the event ID. When a new request arrives, check the ID first. If you already handled it, do nothing and return 2xx.
To make this solid, add a unique constraint on the event ID column in your database. Then, even if two requests land at the same moment, only one write succeeds. We cover the concept in full in our idempotency guide, so we will not repeat it here.
Ordering is also a subtle point. Events do not always arrive in the order they happened. For instance, "subscription updated" may land before "subscription created." So when you change state, rely on the event timestamp, or fetch the current object from the API.
What security measures should you take for webhooks?
Signature checks are a good start, but they are not enough on their own. You need layers. Review the checklist below with your team before go-live.
- Publish the listener only over HTTPS; never carry secrets over plain HTTP.
- Verify every signature over the raw body with a constant-time comparison.
- Check the timestamp and reject requests outside a reasonable window.
- Store event IDs and filter out duplicates.
- Do not trust the body blindly; for critical actions, fetch the latest object from the provider's API.
- Validate incoming data and ignore unexpected fields.
- Use a hard-to-guess path for the URL, but never treat it as your only layer.
- If the provider publishes IP ranges, consider an allowlist as an extra layer.
- Keep logs, but mask sensitive fields such as card data or personal data.
When webhooks carry personal data, remember your GDPR duties as well. This article is not legal advice; ask your legal counsel about data processing.
How do webhooks handle payment notifications?
If someone asks what is a webhook most useful for, the answer is usually payments, because they are the most critical use case. Example scenario: a customer enters card details on the checkout page, completes the 3D Secure step and then closes the browser. If you rely only on the browser redirect, you will never confirm that order.
The payment provider, however, sends your server a webhook once the transaction completes. You verify the signature, check the event ID and move the order to "paid." After that, the confirmation email and stock update run from the queue.
Hence the golden rule for payment integrations: tie the final order status to the server-to-server notification, not to the browser redirect. If checkout keeps failing at the verification step, our 3D Secure troubleshooting article may help.
In addition, refunds, disputes and subscription renewals usually arrive by webhook too. If you ignore them, your accounting records quietly drift away from reality.
What do webhooks add to form and CRM integrations?
The second common scenario involves forms and customer relationship management. For example, when someone fills in the quote form on your website, the form tool fires a webhook. That request writes the entry into your CRM at once, and your sales team gets an alert.
With polling, the same lead might appear minutes later. In many industries, a lead you call back fast behaves very differently from one you call hours later. Moreover, a webhook can carry the ad source, UTM tags and page details along with the entry.
We explain how to design this flow end to end in our website CRM integration guide. You can also use webhooks in the other direction. When a deal turns "won" in the CRM, a record can open in your accounting or project tool automatically.
Code hosting likewise follows a similar pattern. GitHub triggers your build server through a webhook when someone pushes a new commit. Then the continuous integration pipeline starts without anyone pressing a button.
How do you test a webhook endpoint?
Testing webhooks is tricky, because the other side sends the request, not you. Still, most providers make it easier. Their dashboards usually include an option to send a test event, a list of past deliveries and the response code of each one.
- Start in a sandbox with a separate endpoint and a separate secret.
- For local development, use the provider's official CLI if it offers one to forward events to your machine.
- Try valid signatures, invalid signatures, stale timestamps and duplicate deliveries one by one.
- Watch response times in the provider's delivery history.
- After launch, track the error rate closely during the first days.
If you set up a local Python environment for testing, you may run into environment errors. We solve one common case in our pip externally managed environment fix. That way, you can install your test tools without breaking the system Python.
How do you keep webhook processing fast at scale?
When traffic grows, the biggest risk is a listener that handles every request synchronously. Picture a campaign day with hundreds of payment events per minute. If each one writes to the database, sends an email and updates stock in line, replies slow down. The provider retries, and the load multiplies.
For that reason, a solid design keeps the listener to three jobs. It verifies the signature, writes the event to a queue and returns 2xx. Separate worker processes then consume the queue at their own pace. As a result, one slowdown does not block the listener.
A dead letter queue for events that fail processing is also a good habit. Once you fix the bug, you replay those events. Caching frequently read reference data reduces the load too; we touch on this in our caching guide.
Finally, set up monitoring. Track incoming event counts, signature failure rates, queue length and processing time on one dashboard. Then you spot problems before customers feel them.
Are there cases where you should not use webhooks?
Yes, because webhooks do not fit every need. For example, if the provider offers no webhooks, polling is your only option. Likewise, if you cannot expose your server, say on a closed corporate network, you cannot receive incoming requests.
A webhook is also not a direct answer for showing live data to a user in the browser. The browser is not an HTTP server and cannot accept incoming requests. In that case, the webhook reaches your server, and you forward the data to the interface over WebSocket or a similar channel.
For very high-volume data flows, one HTTP request per event can become inefficient. Message queues or event streaming platforms may suit those scenarios better. In short, webhooks are the simplest and most common path for low and medium-volume, server-to-server event notifications.
Which terms do people confuse with webhooks?
Many readers who search for this topic treat a few neighboring terms as the same thing. That confusion can lead to poor architecture choices. So let us separate the pairs we see most often.
- Callback: A general programming idea, a function that runs when a task finishes. A webhook applies this idea between systems over HTTP.
- Push notification: The alert you see on your phone, aimed at an end user. A webhook goes to a server, and no user sees it.
- Reverse API: Some sources use this phrase for webhooks. It refers to the flipped direction of communication.
- Event stream: A continuous, ordered log of events. Webhooks, instead, are single and independent deliveries.
Meanwhile, automation tools often include a "webhook trigger" step. That step simply means the tool generates a listener URL for you. The logic stays exactly the same; only the tool hosts the endpoint instead of you.
How do you keep webhook subscriptions lean and maintainable?
First, many providers offer an "all events" option. It looks handy at first, but it creates trouble in the field. Your listener starts receiving, verifying and storing hundreds of events it never uses.
So subscribe only to events your workflow truly needs. For a subscription site, payment succeeded, payment failed, subscription canceled and refund events are often enough. You then grow the list on purpose as you add features.
Separate endpoints for separate purposes also make maintenance easier. Payment events can go to one URL and CRM events to another. Then a failure on one side does not affect the other, and log reviews go much faster.
Next, plan for change. Providers add fields and release new API versions over time. If your code does not ignore unknown fields, it may break one day without warning. Also update the endpoint in the provider dashboard whenever your domain or server changes. Give each webhook an owner, a monitoring view and a review schedule.
What is a webhook checklist for your business?
We have covered what a webhook is, how it works and where the risks sit. Now let us gather the questions to ask before any integration goes live.
- Which events do we really need, and do we have needless subscriptions?
- Does the endpoint run over HTTPS, and do we verify signatures over the raw body?
- Is the secret stored safely, outside the code?
- Do we filter duplicates by event ID?
- Do we queue the work and return 2xx quickly?
- Have we read the provider's retry policy in its documentation?
- Do we run periodic reconciliation for missed events?
- Do our logs mask sensitive data?
Each item also looks simple on paper. However, in linked systems such as payments, stock and CRM, one missing item can cause days of data mismatch. If you want to design your integration end to end, our team can plan it with you through our custom software development service.
What should you remember about webhooks?
To sum up, a webhook is a "notify me when it happens" agreement. It does not replace an API; it completes it. It is faster and leaner than polling, and simpler than WebSocket for notifications between servers.
That simplicity comes with responsibility, though. Verifying signatures, filtering duplicates, replying fast and catching missed events are your job. Build these four habits, and your webhook setup can run smoothly for years.
Our last tip: read each provider's documentation separately. Header names, retry windows and signature formats all differ. The general answer stays the same, but the details change from service to service.



