[{"data":1,"prerenderedAt":733},["ShallowReactive",2],{"content-query-IOfrr2H0aw":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"crumb":11,"term":11,"summary":12,"group":13,"order":14,"updated":15,"cta":16,"related":24,"faq":43,"body":56,"_type":726,"_id":727,"_source":728,"_file":729,"_stem":730,"_extension":731,"sitemap":732},"/glossary/webhook-gateway","glossary",false,"","What is a webhook gateway? Definition and features","A webhook gateway sits between webhook senders and your endpoints: it authenticates, stores, retries, routes and fans out webhooks. What it does, when you need one, and how it differs from an API gateway.","reference","Webhook gateway","A layer that receives, stores, retries and routes webhooks for you.","Infrastructure",31,"2026-10-28",{"eyebrow":17,"title":18,"text":19,"to":20,"label":21,"secondaryTo":22,"secondaryLabel":23},"Webhook Relay","A webhook gateway that also reaches private servers","Webhook Relay authenticates, stores, retries, throttles and fans out webhooks, and delivers them to public endpoints or to localhost and on-prem servers with no public IP, through an outbound agent. Free plan available.","/webhook-gateway/","See the webhook gateway","/features/durable-retries/","Durable retries",[25,28,31,34,37,40],{"title":26,"to":27},"Webhook forwarding","/glossary/webhook-forwarding/",{"title":29,"to":30},"Webhook fan-out","/glossary/webhook-fan-out/",{"title":32,"to":33},"Webhook retries","/glossary/webhook-retries/",{"title":35,"to":36},"Reverse proxy","/glossary/reverse-proxy/",{"title":38,"to":39},"Dead-letter queue","/glossary/dead-letter-queue/",{"title":41,"to":42},"Webhook system design","/blog/webhook-system-design/",[44,47,50,53],{"q":45,"a":46},"What is a webhook gateway?","A webhook gateway is a service that sits between the systems sending webhooks and the endpoints that process them. It gives providers a stable URL, verifies and stores each incoming webhook, then delivers it to one or more destinations with retries, rate limiting, filtering, transformation and logging, so your application code doesn't have to handle delivery concerns.",{"q":48,"a":49},"What is the difference between a webhook gateway and an API gateway?","An API gateway handles synchronous request and response traffic: it authenticates callers, routes the request and returns your service's response immediately. A webhook gateway handles asynchronous events: it acknowledges the sender, stores the event, and delivers it later with retries, fan-out and replay. API gateways generally don't persist and redeliver requests.",{"q":51,"a":52},"When do I need a webhook gateway?","When webhooks matter enough that losing one is a problem, when several services need the same events, when the receiving server is on a private network or localhost, when bursts overwhelm your endpoint, or when you want one place to see and replay every webhook instead of each provider's dashboard.",{"q":54,"a":55},"Is a webhook gateway the same as webhooks as a service?","They are mirror images. An inbound webhook gateway receives webhooks from providers and delivers them to your systems. Webhooks as a service, or an outbound webhook gateway, sends your own events to your customers' endpoints with signing, retries and per-customer endpoint management. Some products, Webhook Relay among them, do both.",{"type":57,"children":58,"toc":717},"root",[59,81,91,98,308,314,477,497,503,568,581,587,644,650],{"type":60,"tag":61,"props":62,"children":63},"element","p",{},[64,71,73,79],{"type":60,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":69,"value":70},"text","A webhook gateway is a service that sits between the systems sending webhooks and the endpoints that process them.",{"type":69,"value":72}," It gives providers one stable URL, verifies and stores every incoming webhook, then delivers it to one or more destinations with ",{"type":60,"tag":74,"props":75,"children":76},"a",{"href":33},[77],{"type":69,"value":78},"retries",{"type":69,"value":80},", rate limiting, filtering, transformation and logs. Your application receives clean, reliable deliveries and doesn't have to solve delivery problems itself.",{"type":60,"tag":82,"props":83,"children":85},"pre",{"code":84},"Stripe ─┐                                   ┌──▶ billing service      (retries, 30 days)\nGitHub ─┼──▶ webhook gateway ──store──route─┼──▶ localhost / on-prem   (via agent)\nShopify ┘    verify · log · throttle        └──▶ Slack #alerts         (transformed)\n",[86],{"type":60,"tag":87,"props":88,"children":89},"code",{"__ignoreMap":7},[90],{"type":69,"value":84},{"type":60,"tag":92,"props":93,"children":95},"h2",{"id":94},"what-a-webhook-gateway-does",[96],{"type":69,"value":97},"What a webhook gateway does",{"type":60,"tag":99,"props":100,"children":101},"table",{},[102,121],{"type":60,"tag":103,"props":104,"children":105},"thead",{},[106],{"type":60,"tag":107,"props":108,"children":109},"tr",{},[110,116],{"type":60,"tag":111,"props":112,"children":113},"th",{},[114],{"type":69,"value":115},"Capability",{"type":60,"tag":111,"props":117,"children":118},{},[119],{"type":69,"value":120},"What it solves",{"type":60,"tag":122,"props":123,"children":124},"tbody",{},[125,142,158,182,206,229,260,284],{"type":60,"tag":107,"props":126,"children":127},{},[128,137],{"type":60,"tag":129,"props":130,"children":131},"td",{},[132],{"type":60,"tag":65,"props":133,"children":134},{},[135],{"type":69,"value":136},"Stable ingestion URL",{"type":60,"tag":129,"props":138,"children":139},{},[140],{"type":69,"value":141},"Providers point at the gateway once. You move or add backends without touching their settings.",{"type":60,"tag":107,"props":143,"children":144},{},[145,153],{"type":60,"tag":129,"props":146,"children":147},{},[148],{"type":60,"tag":65,"props":149,"children":150},{},[151],{"type":69,"value":152},"Persistence",{"type":60,"tag":129,"props":154,"children":155},{},[156],{"type":69,"value":157},"Each webhook is stored before delivery, so a crash or outage on your side doesn't lose it.",{"type":60,"tag":107,"props":159,"children":160},{},[161,169],{"type":60,"tag":129,"props":162,"children":163},{},[164],{"type":60,"tag":65,"props":165,"children":166},{},[167],{"type":69,"value":168},"Retries with backoff",{"type":60,"tag":129,"props":170,"children":171},{},[172,174,180],{"type":69,"value":173},"Failed deliveries are retried with ",{"type":60,"tag":74,"props":175,"children":177},{"href":176},"/glossary/exponential-backoff/",[178],{"type":69,"value":179},"exponential backoff",{"type":69,"value":181}," on a schedule you control, not the provider's.",{"type":60,"tag":107,"props":183,"children":184},{},[185,193],{"type":60,"tag":129,"props":186,"children":187},{},[188],{"type":60,"tag":65,"props":189,"children":190},{},[191],{"type":69,"value":192},"Authentication",{"type":60,"tag":129,"props":194,"children":195},{},[196,198,204],{"type":69,"value":197},"Verify each provider's ",{"type":60,"tag":74,"props":199,"children":201},{"href":200},"/glossary/webhook-signature/",[202],{"type":69,"value":203},"signature",{"type":69,"value":205}," at the edge and drop forged requests.",{"type":60,"tag":107,"props":207,"children":208},{},[209,217],{"type":60,"tag":129,"props":210,"children":211},{},[212],{"type":60,"tag":65,"props":213,"children":214},{},[215],{"type":69,"value":216},"Fan-out and routing",{"type":60,"tag":129,"props":218,"children":219},{},[220,222,227],{"type":69,"value":221},"Deliver one event to several destinations, or route by event type. See ",{"type":60,"tag":74,"props":223,"children":224},{"href":30},[225],{"type":69,"value":226},"webhook fan-out",{"type":69,"value":228},".",{"type":60,"tag":107,"props":230,"children":231},{},[232,240],{"type":60,"tag":129,"props":233,"children":234},{},[235],{"type":60,"tag":65,"props":236,"children":237},{},[238],{"type":69,"value":239},"Throttling",{"type":60,"tag":129,"props":241,"children":242},{},[243,245,251,253,259],{"type":69,"value":244},"Release events at a rate or concurrency your endpoint can handle, so bursts don't turn into ",{"type":60,"tag":74,"props":246,"children":248},{"href":247},"/http-errors/429-too-many-requests/",[249],{"type":69,"value":250},"429s",{"type":69,"value":252}," or ",{"type":60,"tag":74,"props":254,"children":256},{"href":255},"/http-errors/503-service-unavailable/",[257],{"type":69,"value":258},"503s",{"type":69,"value":228},{"type":60,"tag":107,"props":261,"children":262},{},[263,271],{"type":60,"tag":129,"props":264,"children":265},{},[266],{"type":60,"tag":65,"props":267,"children":268},{},[269],{"type":69,"value":270},"Transformation and filtering",{"type":60,"tag":129,"props":272,"children":273},{},[274,276,282],{"type":69,"value":275},"Reshape the ",{"type":60,"tag":74,"props":277,"children":279},{"href":278},"/glossary/webhook-payload/",[280],{"type":69,"value":281},"payload",{"type":69,"value":283}," for the destination, or drop events nobody needs.",{"type":60,"tag":107,"props":285,"children":286},{},[287,295],{"type":60,"tag":129,"props":288,"children":289},{},[290],{"type":60,"tag":65,"props":291,"children":292},{},[293],{"type":69,"value":294},"Observability and replay",{"type":60,"tag":129,"props":296,"children":297},{},[298,300,306],{"type":69,"value":299},"One log of every request and response, with ",{"type":60,"tag":74,"props":301,"children":303},{"href":302},"/glossary/webhook-replay/",[304],{"type":69,"value":305},"replay",{"type":69,"value":307}," after an incident.",{"type":60,"tag":92,"props":309,"children":311},{"id":310},"webhook-gateway-vs-api-gateway-vs-reverse-proxy",[312],{"type":69,"value":313},"Webhook gateway vs API gateway vs reverse proxy",{"type":60,"tag":99,"props":315,"children":316},{},[317,342],{"type":60,"tag":103,"props":318,"children":319},{},[320],{"type":60,"tag":107,"props":321,"children":322},{},[323,326,333,338],{"type":60,"tag":111,"props":324,"children":325},{},[],{"type":60,"tag":111,"props":327,"children":328},{},[329],{"type":60,"tag":74,"props":330,"children":331},{"href":36},[332],{"type":69,"value":35},{"type":60,"tag":111,"props":334,"children":335},{},[336],{"type":69,"value":337},"API gateway",{"type":60,"tag":111,"props":339,"children":340},{},[341],{"type":69,"value":11},{"type":60,"tag":122,"props":343,"children":344},{},[345,368,390,411,432,454],{"type":60,"tag":107,"props":346,"children":347},{},[348,353,358,363],{"type":60,"tag":129,"props":349,"children":350},{},[351],{"type":69,"value":352},"Traffic",{"type":60,"tag":129,"props":354,"children":355},{},[356],{"type":69,"value":357},"Any HTTP",{"type":60,"tag":129,"props":359,"children":360},{},[361],{"type":69,"value":362},"Synchronous API calls",{"type":60,"tag":129,"props":364,"children":365},{},[366],{"type":69,"value":367},"Asynchronous events",{"type":60,"tag":107,"props":369,"children":370},{},[371,376,381,385],{"type":60,"tag":129,"props":372,"children":373},{},[374],{"type":69,"value":375},"Stores requests",{"type":60,"tag":129,"props":377,"children":378},{},[379],{"type":69,"value":380},"No",{"type":60,"tag":129,"props":382,"children":383},{},[384],{"type":69,"value":380},{"type":60,"tag":129,"props":386,"children":387},{},[388],{"type":69,"value":389},"Yes",{"type":60,"tag":107,"props":391,"children":392},{},[393,398,402,406],{"type":60,"tag":129,"props":394,"children":395},{},[396],{"type":69,"value":397},"Retries later",{"type":60,"tag":129,"props":399,"children":400},{},[401],{"type":69,"value":380},{"type":60,"tag":129,"props":403,"children":404},{},[405],{"type":69,"value":380},{"type":60,"tag":129,"props":407,"children":408},{},[409],{"type":69,"value":410},"Yes, for hours or days",{"type":60,"tag":107,"props":412,"children":413},{},[414,419,423,428],{"type":60,"tag":129,"props":415,"children":416},{},[417],{"type":69,"value":418},"Fan-out",{"type":60,"tag":129,"props":420,"children":421},{},[422],{"type":69,"value":380},{"type":60,"tag":129,"props":424,"children":425},{},[426],{"type":69,"value":427},"Rarely",{"type":60,"tag":129,"props":429,"children":430},{},[431],{"type":69,"value":389},{"type":60,"tag":107,"props":433,"children":434},{},[435,440,445,449],{"type":60,"tag":129,"props":436,"children":437},{},[438],{"type":69,"value":439},"Response to caller",{"type":60,"tag":129,"props":441,"children":442},{},[443],{"type":69,"value":444},"Your server's",{"type":60,"tag":129,"props":446,"children":447},{},[448],{"type":69,"value":444},{"type":60,"tag":129,"props":450,"children":451},{},[452],{"type":69,"value":453},"Usually an immediate acknowledgement",{"type":60,"tag":107,"props":455,"children":456},{},[457,462,467,472],{"type":60,"tag":129,"props":458,"children":459},{},[460],{"type":69,"value":461},"Examples",{"type":60,"tag":129,"props":463,"children":464},{},[465],{"type":69,"value":466},"nginx, Caddy, Traefik",{"type":60,"tag":129,"props":468,"children":469},{},[470],{"type":69,"value":471},"Kong, AWS API Gateway, Apigee",{"type":60,"tag":129,"props":473,"children":474},{},[475],{"type":69,"value":476},"Webhook Relay, Hookdeck, Convoy",{"type":60,"tag":61,"props":478,"children":479},{},[480,482,488,489,495],{"type":69,"value":481},"A reverse proxy or API gateway in front of your webhook endpoint helps with TLS and routing, but if your service is down, the request fails with a ",{"type":60,"tag":74,"props":483,"children":485},{"href":484},"/http-errors/502-bad-gateway/",[486],{"type":69,"value":487},"502",{"type":69,"value":252},{"type":60,"tag":74,"props":490,"children":492},{"href":491},"/http-errors/504-gateway-timeout/",[493],{"type":69,"value":494},"504",{"type":69,"value":496}," and you depend on the provider to try again. A webhook gateway accepts the event and takes over responsibility for delivering it.",{"type":60,"tag":92,"props":498,"children":500},{"id":499},"when-you-need-one",[501],{"type":69,"value":502},"When you need one",{"type":60,"tag":504,"props":505,"children":506},"ul",{},[507,518,528,538,548,558],{"type":60,"tag":508,"props":509,"children":510},"li",{},[511,516],{"type":60,"tag":65,"props":512,"children":513},{},[514],{"type":69,"value":515},"Lost webhooks are expensive.",{"type":69,"value":517}," Payments, orders, provisioning and security alerts.",{"type":60,"tag":508,"props":519,"children":520},{},[521,526],{"type":60,"tag":65,"props":522,"children":523},{},[524],{"type":69,"value":525},"Provider retry windows are too short.",{"type":69,"value":527}," GitHub doesn't retry automatically, and many providers give up after minutes or a few days.",{"type":60,"tag":508,"props":529,"children":530},{},[531,536],{"type":60,"tag":65,"props":532,"children":533},{},[534],{"type":69,"value":535},"Several services need the same events",{"type":69,"value":537},", but the provider allows one URL.",{"type":60,"tag":508,"props":539,"children":540},{},[541,546],{"type":60,"tag":65,"props":542,"children":543},{},[544],{"type":69,"value":545},"The receiver has no public IP",{"type":69,"value":547},": on-prem systems, Kubernetes clusters, CI servers or a developer laptop.",{"type":60,"tag":508,"props":549,"children":550},{},[551,556],{"type":60,"tag":65,"props":552,"children":553},{},[554],{"type":69,"value":555},"Bursts overload the endpoint",{"type":69,"value":557}," during sales, batch jobs or replays.",{"type":60,"tag":508,"props":559,"children":560},{},[561,566],{"type":60,"tag":65,"props":562,"children":563},{},[564],{"type":69,"value":565},"You want one place to debug",{"type":69,"value":567}," instead of a dashboard per provider.",{"type":60,"tag":61,"props":569,"children":570},{},[571,573,579],{"type":69,"value":572},"If you only receive a handful of low-stakes webhooks on a public server that's always up, a gateway is optional. An ",{"type":60,"tag":74,"props":574,"children":576},{"href":575},"/glossary/idempotency/",[577],{"type":69,"value":578},"idempotent",{"type":69,"value":580}," endpoint that queues events may be enough.",{"type":60,"tag":92,"props":582,"children":584},{"id":583},"inbound-vs-outbound-gateways",[585],{"type":69,"value":586},"Inbound vs outbound gateways",{"type":60,"tag":61,"props":588,"children":589},{},[590,592,597,599,604,606,612,614,619,621,627,629,634,636,642],{"type":69,"value":591},"An ",{"type":60,"tag":65,"props":593,"children":594},{},[595],{"type":69,"value":596},"inbound",{"type":69,"value":598}," webhook gateway receives webhooks from third parties for your systems. An ",{"type":60,"tag":65,"props":600,"children":601},{},[602],{"type":69,"value":603},"outbound",{"type":69,"value":605}," gateway, often called webhooks as a service, sends ",{"type":60,"tag":607,"props":608,"children":609},"em",{},[610],{"type":69,"value":611},"your",{"type":69,"value":613}," events to ",{"type":60,"tag":607,"props":615,"children":616},{},[617],{"type":69,"value":618},"your customers'",{"type":69,"value":620}," endpoints, handling signing (often with ",{"type":60,"tag":74,"props":622,"children":624},{"href":623},"/glossary/standard-webhooks/",[625],{"type":69,"value":626},"Standard Webhooks",{"type":69,"value":628},"), per-customer retries, endpoint health and replay. Webhook Relay does both: the ",{"type":60,"tag":74,"props":630,"children":631},{"href":20},[632],{"type":69,"value":633},"webhook gateway",{"type":69,"value":635}," for inbound, and the ",{"type":60,"tag":74,"props":637,"children":639},{"href":638},"/outbound-webhooks/",[640],{"type":69,"value":641},"Outbound Gateway",{"type":69,"value":643}," for sending.",{"type":60,"tag":92,"props":645,"children":647},{"id":646},"webhook-relay-as-a-webhook-gateway",[648],{"type":69,"value":649},"Webhook Relay as a webhook gateway",{"type":60,"tag":61,"props":651,"children":652},{},[653,655,660,662,668,670,676,678,684,686,692,694,700,702,708,710,715],{"type":69,"value":654},"Webhook Relay persists every event the moment it arrives and retries with exponential backoff for up to 30 days (",{"type":60,"tag":74,"props":656,"children":657},{"href":22},[658],{"type":69,"value":659},"durable retries",{"type":69,"value":661},"). It can verify signatures, ",{"type":60,"tag":74,"props":663,"children":665},{"href":664},"/features/throttling/",[666],{"type":69,"value":667},"throttle",{"type":69,"value":669}," delivery, deliver one webhook to up to 200 ",{"type":60,"tag":74,"props":671,"children":673},{"href":672},"/features/webhook-multiple-destinations/",[674],{"type":69,"value":675},"destinations",{"type":69,"value":677},", reshape payloads with ",{"type":60,"tag":74,"props":679,"children":681},{"href":680},"/features/transform-webhooks/",[682],{"type":69,"value":683},"transform functions",{"type":69,"value":685},", and log every delivery with one-click resend and replay. Its distinguishing feature is delivery to ",{"type":60,"tag":74,"props":687,"children":689},{"href":688},"/features/webhook-to-internal-server/",[690],{"type":69,"value":691},"internal servers",{"type":69,"value":693},": ",{"type":60,"tag":87,"props":695,"children":697},{"className":696},[],[698],{"type":69,"value":699},"relay forward",{"type":69,"value":701}," runs an agent that opens an outbound connection, so webhooks reach localhost, on-prem and private Kubernetes services with no public IP or open port. See ",{"type":60,"tag":74,"props":703,"children":705},{"href":704},"/docs/webhooks/internal/localhost/",[706],{"type":69,"value":707},"receiving webhooks on localhost",{"type":69,"value":709}," to try it, or the ",{"type":60,"tag":74,"props":711,"children":712},{"href":20},[713],{"type":69,"value":714},"webhook gateway overview",{"type":69,"value":716}," for the full feature set and a comparison with other gateways.",{"title":7,"searchDepth":718,"depth":718,"links":719},3,[720,722,723,724,725],{"id":94,"depth":721,"text":97},2,{"id":310,"depth":721,"text":313},{"id":499,"depth":721,"text":502},{"id":583,"depth":721,"text":586},{"id":646,"depth":721,"text":649},"markdown","content:glossary:webhook-gateway.md","content","glossary/webhook-gateway.md","glossary/webhook-gateway","md",{"loc":4},1793199807532]