A webhook gateway is a service that sits between the apps that send you webhooks and the code that reads them. It accepts each incoming event, verifies its signature, stores it durably, and then forwards it to your systems with retries and a full delivery history, so your own application never has to handle that plumbing.
That definition covers a lot of moving parts, so this article unpacks each one: what the gateway does, how it differs from a plain webhook receiver, and how to tell whether your project has reached the point where you need one.
What is a webhook gateway?
Providers like Stripe, GitHub, and Shopify tell you about events by sending an HTTP POST to a URL you give them. A payment succeeded, a pull request merged, an order shipped. This is the direction that makes webhooks different from an API you call, and the reversal moves the availability requirement onto you. The naive way to receive those is a single route in your application that reads the request and does something with it. That works until the app is mid-deploy when an event arrives, or the provider sends the same event twice.
A webhook gateway is the durable middleman in that exchange. Instead of pointing a provider at your app, you point it at the gateway. The gateway owns the ingest URL, takes responsibility for every event that lands on it, and becomes the system of record for what came in and what happened next. Your application stops being the thing that catches raw webhooks and becomes a consumer of events that are already verified and stored.
The word “gateway” fits. It is the single controlled entry point for inbound events, the same way a door is the controlled entry point to a building. Everything that comes in passes through it, gets checked, gets recorded, and only then moves further in.
The problem it solves
Receiving a webhook well is harder than receiving one at all. The first version anyone writes looks trivial: parse the JSON, update a row, return 200. The second version usually gets written after an incident, and it looks much the same in every project:
- Signature verification. Anyone who learns your URL can POST to it. You need to confirm each request came from the provider before you trust a byte of it, which is the full webhook security model in one line. Every provider spells it differently. Stripe hands you a per-endpoint signing secret, and when the check fails the message rarely says why, which is its own debugging exercise.
- Retries and backoff. Your downstream service will be down at some point. When it is, events need to wait and try again later instead of vanishing, on a backoff schedule with jitter rather than a fixed interval.
- Idempotency and duplicates. Providers resend. The same event can arrive twice, and processing it twice can double-charge a customer or duplicate an order unless the consumer dedupes on a stable event id.
- Delivery history. When a teammate asks “did we get the refund event for order 4471?”, you need an answer backed by a record of the delivery. Failed deliveries need somewhere to land too, which is what a dead letter queue is for.
None of this is specific to your business. Teams rebuild the same infrastructure in service after service, and mistakes in it tend to stay invisible until money or data goes missing. A webhook gateway puts this layer in one place so each new project can reuse it.
Gateway vs a plain webhook receiver
A plain webhook receiver is a route in your application: POST /webhooks/stripe. A gateway is a dedicated ingest, storage, and delivery layer that runs in front of your application. The difference matters most on a bad day. If the mechanics of that POST are the part you want first, how webhooks work walks through one request header by header.
Consider what happens when your app is down for a two-minute deploy. With a plain receiver, the provider’s POST hits a dead endpoint. Some providers retry a few times, some give up quickly, and a few do not retry at all. Events sent during that window can be lost with no record that they ever existed. With a gateway in front, the provider’s request still gets a fast 200, the event is stored, and delivery to your app waits until the app is back.
The table below sketches where the two approaches diverge.
| Concern | Plain receiver in your app | Webhook gateway |
|---|---|---|
| App is down | Events may be lost | Events stored, delivered when you recover |
| Duplicate events | You handle idempotency yourself | Retries and delivery are tracked centrally |
| Signature checks | Reimplemented per endpoint | Verified per source before acceptance |
| Failed deliveries | Often invisible | Land in a dead-letter queue for replay |
| Audit trail | Whatever you happen to log | Full per-attempt history and response logs |
A plain receiver has its place. For a side project with one provider and no money changing hands, it is the right amount of engineering. The gateway earns its place once losing an event has a real cost.
It is not an API gateway
One clarification, because the names collide. An API gateway sits in front of your outbound-facing API and manages requests your clients make to you: routing, authentication, rate limiting for callers, and so on. A webhook gateway handles the opposite direction: unsolicited events that other companies send to you. If you already run an API gateway such as Kong or AWS API Gateway, it does not remove the need for inbound webhook handling, because it was never designed for the retry, replay, and delivery-history problems that inbound events create.
What a webhook gateway does, step by step
Here is the path a single event takes through a gateway like Webhooker, from the provider’s POST to your application acting on it.
- Verify the signature. The provider POSTs to a per-source ingest URL such as
https://app.webhooker.eu/in/{token}. Before the payload is accepted, the gateway checks the provider’s signature, HMAC-SHA256 or SHA1 depending on the source. A request that fails verification gets401and is never delivered as trusted. - Persist durably. The accepted event goes into a durable queue. That is what makes acknowledgement and delivery independent: the event is safe on disk before anyone tries to forward it.
- Acknowledge fast. Only after the write does the gateway return
200 OK. Webhooker acknowledges 99% of inbound webhooks in under 10 ms, measured server-side. That speed matters because many providers treat a slow response as a failure and start retrying. - Fan out to destinations. Delivery happens out of band. Workers pull rows with
SELECT ... FOR UPDATE SKIP LOCKED, apply any per-destination transformation and header injection, sign the outbound request, and forward it. Because delivery never sits on the ingest request path, a slow destination can’t slow down the provider. - Retry with backoff. If a destination returns an error or times out, the gateway retries with exponential backoff, using conditional rules based on the HTTP status. A per-destination circuit breaker stops hammering an endpoint that is clearly down.
- Dead-letter and replay. Events that exhaust their retries land in a dead-letter queue. From there you get one-click resend, bulk replay, and the full per-attempt history, so a failed event stays visible until someone deals with it. A live tail lets you watch events arrive and forward in real time while you debug.
The design goal running through all of that is at-least-once delivery: every accepted event reaches your destination at least once, which is why idempotency on your side still matters. More detail on how an inbound webhook gateway ingests and forwards events is on the product pages.
When you need one (and when you don’t)
You do not need a gateway for every webhook. Reach for one when the cost of a missed or mishandled event stops being theoretical. Concrete signals:
- Money is involved. Payment and billing webhooks from Stripe, PayPal, or a similar provider are the clearest case. A dropped
payment_succeededmeans someone paid and your system never noticed, and Stripe’s own retries stop after three days, which is shorter than it sounds. - You have several providers. Once you receive from Stripe and GitHub and Shopify and a shipping provider, per-source verification and monitoring in your own code turns into a maintenance burden that a gateway absorbs.
- One event feeds several systems. If an incoming order needs to reach your database, your analytics, and a Slack alert, a gateway fans a single event out to all of them with independent retries per destination. Watch which unit gets billed here, because some pricing models charge per delivery rather than per event and fan-out multiplies the invoice.
- You have compliance obligations. When you need an audit trail of what arrived and where it went, or you have to keep event data in a specific region, ad hoc logging does not cut it.
The inverse holds too: if you have a single provider, no payment data, and a webhook that just refreshes a cache, a plain endpoint in your app is fine. Adding a gateway there is weight you do not need yet. A better test than “is a gateway good practice?” is “what does it cost me the first time I lose an event?” Once the answer is more than “nothing”, the next question is whether to write the gateway yourself, which build vs buy for webhook infrastructure costs out.
What to look for in a gateway
If you decide you want one, whether you build or buy, these are the properties that separate a gateway from a queue with a webhook-shaped label. The same list applies when you read through Webhooker’s features.
- Inbound verification per source. Signatures should be checked against each provider’s own scheme before the payload is accepted, not after it has been trusted and stored.
- At-least-once durability. The event must be persisted before acknowledgement, on storage you trust. Webhooker writes every event to a durable queue before answering, so an accepted event survives a crash.
- Retries with a circuit breaker. Backoff alone can turn a struggling destination into a downed one. Per-destination circuit breaking protects the endpoints you are delivering to. Backoff also reorders traffic, so if one destination needs its events in sequence, check that ordered delivery is a per-destination setting rather than a global switch.
- Replay from a dead-letter queue. Retries eventually run out. When they do, you want failed events parked somewhere you can inspect and resend, individually or in bulk.
- Predictable outbound addresses. If any destination sits behind a corporate firewall, delivery only works when the gateway sends from a stable set of outbound IPs you can hand to their security team. Serverless egress ranges change without notice, which is a slow-burning reason self-built delivery breaks.
- Data residency you can name. If you operate under GDPR, you need to know where events are stored and processed, and the retry queue is the leg most people forget to check. Webhooker keeps ingest, storage, delivery workers, and backups in the EU, enforces retention limits, and offers a DPA on every paid plan.
Each property maps to a failure mode from earlier in this article: unverified senders, lost events, cascading failures, dead ends, firewall-blocked deliveries and compliance gaps. A gateway missing one of them leaves that failure mode in your own code.
For background on the verification step, Stripe’s guide to verifying webhook signatures is a good external primer. Webhooker’s free plan covers 10,000 events a month across 3 sources, enough to route a first event through the steps above. If you are weighing specific products against this checklist, the side-by-side comparison of Webhooker, Svix and Hookdeck shows how differently they approach it, and if EU data residency is a hard requirement, start from the checklist for EU-hosted Hookdeck alternatives instead.
Frequently asked questions
Is a webhook gateway the same as an API gateway?
No. An API gateway manages outbound-facing traffic: the requests your clients make to your API, handling routing, authentication, and caller rate limits. A webhook gateway handles the reverse direction, the unsolicited events that services like Stripe or GitHub send to you, and focuses on verification, durable storage, retries, and replay. Running one does not replace the other.
Is it just a queue?
A queue is one part of it, but not the whole. A gateway adds the pieces around the queue: a fast ingest endpoint that returns 200 in milliseconds, per-source signature verification before anything is stored, retries with backoff and a circuit breaker, a dead-letter queue with one-click and bulk replay, and full per-attempt history. Without those, you have a queue that you still have to wrap in your own receiving code.
Do I still verify signatures if I use one?
The gateway verifies the inbound signature from the provider for you, before it accepts the payload, so you do not re-check the provider’s signature yourself. What you should still do is trust the connection between the gateway and your app. Webhooker signs the requests it forwards to you, so your endpoint can confirm each delivery came from the gateway and not from someone who guessed your URL.