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 actually 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 it doesn’t.
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” is doing real work here. 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. In our experience the second version always shows up after an incident, never before one, and it looks the same in every project:
- Signature verification. Anyone who learns your URL can POST to it. You need to confirm each request genuinely 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 with evidence, not a shrug. Failed deliveries need somewhere to land too, which is what a dead letter queue is for.
None of this is specific to your business. It is the same infrastructure rebuilt from scratch in service after service, and getting it wrong tends to be invisible until money or data goes missing. A webhook gateway exists so that this layer is written once, hardened, and reused, rather than reinvented per project.
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 safely stored, and delivery to your app simply 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 is not wrong. 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. They are different tools for different traffic. 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.
- Ingest and acknowledge fast. The provider POSTs to a per-source ingest URL such as
https://webhooker.eu/in/{token}. The gateway writes the event down and returns200 OKin a few milliseconds; our p99 target for that server-side acknowledgement is under 10 ms. That speed matters because many providers treat a slow response as a failure and start retrying. - Verify the signature. Before the payload is accepted, the gateway checks the provider’s signature, HMAC-SHA256 or SHA1 depending on the source. Anything that fails verification is rejected rather than stored as trusted.
- Persist durably. The accepted event goes into a queue backed by a PostgreSQL
deliveriestable. That is what makes acknowledgement and delivery independent: the event is safe on disk before anyone tries to forward it. - 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 nothing is silently dropped. 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. - 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.
And the honest inverse: if you have a single provider, no payment data, and a webhook that just refreshes a cache, a plain endpoint in your app is genuinely fine. Adding a gateway there is weight you do not need yet. The useful question is not “is a gateway good practice?” but “what does it cost me the first time I lose an event?” When that answer stops being “nothing”, it is time — and the follow-up question is whether to write one yourself, which we cost out in the real price of rolling your own webhook infrastructure.
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 real gateway from a queue with a webhook-shaped label. This is also a fair checklist for evaluating a webhook gateway with verification, retries and replay.
- 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 uses a PostgreSQL-backed queue precisely so that 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, rather than gone.
- 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, where events are stored and processed is not a detail, 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.
Those five map directly to the failure modes earlier in this article: unverified senders, lost events, cascading failures, dead ends, and compliance gaps. A gateway that covers all five turns webhook handling from a recurring source of incidents into something you mostly stop thinking about. If you are weighing specific products against that checklist, we compare Webhooker, Svix and Hookdeck side by side — they solve noticeably different problems.
If you want to try the flow end to end, you can get an ingest URL and route your first event on the free plan, which covers 10,000 events a month across 3 sources. For background on webhook security in general, Stripe’s guide to verifying webhook signatures is a good primer on why the verification step is not optional.
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. The durable queue is the foundation; the handling built on top is what makes it a gateway.
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 genuinely came from the gateway and not from someone who guessed your URL.