[{"data":1,"prerenderedAt":1954},["ShallowReactive",2],{"content-query-GWU0mL47qz":3,"search-blog":1311,"search-docs":1661,"search-features":1903},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"author":11,"tags":12,"categories":17,"date":19,"faq":20,"body":30,"_type":1304,"_id":1305,"_source":1306,"_file":1307,"_stem":1308,"_extension":1309,"sitemap":1310},"/blog/webhook-to-email","blog",false,"","Send a Webhook as Email: Forward Any Event to Your Inbox","Turn incoming webhooks into email notifications. Forward an event through Webhook Relay, transform it in flight, and send a formatted email — using a built-in send-email capability or an API like SendGrid, Mailgun or Postmark.","post","Karolis Rusenas",[13,14,15,16],"email","webhooks","transform","notifications",[18],"integrations","2026-06-10 13:17:00",[21,24,27],{"q":22,"a":23},"How do I send a webhook as an email?","Create a Webhook Relay endpoint, then attach a transform function that formats the incoming payload into a readable message and sends it as an email. The function can use a built-in send-email capability or call an email API like Mailgun, SendGrid or Postmark. Point your source service at the Webhook Relay URL and every event lands in your inbox.",{"q":25,"a":26},"Do I need to run a server to turn webhooks into email?","No. Webhook Relay receives the webhook and runs your transform function in the cloud, including the email send. There's nothing to host or keep online — you only supply the function and your email provider's API key.",{"q":28,"a":29},"Can I filter which webhooks become emails?","Yes. Inside the transform function you can inspect the payload and only send an email when it matters — for example skip a 'free' plan, ignore noisy event types, or call StopForwarding to drop the request entirely so you only get the notifications you care about.",{"type":31,"children":32,"toc":1293},"root",[33,48,79,86,91,121,155,161,190,195,201,214,220,247,280,285,977,982,1014,1020,1025,1108,1126,1132,1145,1151,1214,1220,1230,1246,1256,1262,1287],{"type":34,"tag":35,"props":36,"children":37},"element","p",{},[38,41,46],{"type":39,"value":40},"text","You have a service that fires webhooks — a payment provider, a CI pipeline, a form, a monitor, an alerting tool — and you'd rather get a plain ",{"type":34,"tag":42,"props":43,"children":44},"strong",{},[45],{"type":39,"value":13},{"type":39,"value":47}," than wire up yet another dashboard or chat integration. Email is universal: everyone has an inbox, it's searchable, and it's easy to forward to a teammate.",{"type":34,"tag":35,"props":49,"children":50},{},[51,53,62,64,69,71,77],{"type":39,"value":52},"The catch is that webhooks aren't emails. A provider POSTs a JSON payload to a URL; turning that into a nicely formatted message in your inbox normally means standing up a small server with SMTP or an email API. ",{"type":34,"tag":54,"props":55,"children":59},"a",{"href":56,"rel":57},"https://webhookrelay.com",[58],"nofollow",[60],{"type":39,"value":61},"Webhook Relay",{"type":39,"value":63}," removes that step: it receives the webhook at a stable public URL, runs a ",{"type":34,"tag":42,"props":65,"children":66},{},[67],{"type":39,"value":68},"transform function",{"type":39,"value":70}," that formats ",{"type":34,"tag":72,"props":73,"children":74},"em",{},[75],{"type":39,"value":76},"and sends",{"type":39,"value":78}," the email, and you host nothing.",{"type":34,"tag":80,"props":81,"children":83},"h2",{"id":82},"how-it-works",[84],{"type":39,"value":85},"How it works",{"type":34,"tag":35,"props":87,"children":88},{},[89],{"type":39,"value":90},"The flow is a single hop with a transform that sends the email:",{"type":34,"tag":92,"props":93,"children":96},"pre",{"className":94,"code":95,"language":39,"meta":7,"style":7},"language-text shiki shiki-themes github-dark","Your service  ──▶  Webhook Relay  ──▶  transform: format + send email  ──▶  your inbox\n (raw webhook)      (public URL)        (serverless function)              (email arrives)\n",[97],{"type":34,"tag":98,"props":99,"children":100},"code",{"__ignoreMap":7},[101,112],{"type":34,"tag":102,"props":103,"children":106},"span",{"class":104,"line":105},"line",1,[107],{"type":34,"tag":102,"props":108,"children":109},{},[110],{"type":39,"value":111},"Your service  ──▶  Webhook Relay  ──▶  transform: format + send email  ──▶  your inbox\n",{"type":34,"tag":102,"props":113,"children":115},{"class":104,"line":114},2,[116],{"type":34,"tag":102,"props":117,"children":118},{},[119],{"type":39,"value":120}," (raw webhook)      (public URL)        (serverless function)              (email arrives)\n",{"type":34,"tag":35,"props":122,"children":123},{},[124,126,132,134,139,141,146,148,153],{"type":39,"value":125},"The ",{"type":34,"tag":54,"props":127,"children":129},{"href":128},"/features/transform-webhooks",[130],{"type":39,"value":131},"transformation function",{"type":39,"value":133}," does two jobs: it shapes the payload into a human-readable message, and it dispatches that message as an email — either through a built-in send-email capability or by calling an email API such as ",{"type":34,"tag":42,"props":135,"children":136},{},[137],{"type":39,"value":138},"Mailgun",{"type":39,"value":140},", ",{"type":34,"tag":42,"props":142,"children":143},{},[144],{"type":39,"value":145},"SendGrid",{"type":39,"value":147}," or ",{"type":34,"tag":42,"props":149,"children":150},{},[151],{"type":39,"value":152},"Postmark",{"type":39,"value":154},".",{"type":34,"tag":80,"props":156,"children":158},{"id":157},"step-1-create-a-webhook-relay-endpoint",[159],{"type":39,"value":160},"Step 1: Create a Webhook Relay endpoint",{"type":34,"tag":35,"props":162,"children":163},{},[164,166,173,175,180,182,188],{"type":39,"value":165},"Create a bucket and input at ",{"type":34,"tag":54,"props":167,"children":170},{"href":168,"rel":169},"https://my.webhookrelay.com/buckets",[58],[171],{"type":39,"value":172},"my.webhookrelay.com/buckets",{"type":39,"value":174},". Copy the ",{"type":34,"tag":42,"props":176,"children":177},{},[178],{"type":39,"value":179},"input URL",{"type":39,"value":181}," (it looks like ",{"type":34,"tag":98,"props":183,"children":185},{"className":184},[],[186],{"type":39,"value":187},"https://xyz.hooks.webhookrelay.com",{"type":39,"value":189},") — that's the public address you'll point your source service at.",{"type":34,"tag":35,"props":191,"children":192},{},[193],{"type":39,"value":194},"You don't need a forwarding destination here: the function itself sends the email, so the input alone is enough.",{"type":34,"tag":80,"props":196,"children":198},{"id":197},"step-2-inspect-what-your-source-sends",[199],{"type":39,"value":200},"Step 2: Inspect what your source sends",{"type":34,"tag":35,"props":202,"children":203},{},[204,206,212],{"type":39,"value":205},"Before writing the function, capture a real payload so you know the field names. Point your source at a free ",{"type":34,"tag":54,"props":207,"children":209},{"href":208},"/webhook-bin",[210],{"type":39,"value":211},"Webhook Bin",{"type":39,"value":213}," (or temporarily at the input URL and read the request log) and trigger one event. Now you can see the exact JSON and write your formatting around the real structure instead of guessing.",{"type":34,"tag":80,"props":215,"children":217},{"id":216},"step-3-add-a-transform-that-formats-and-sends-the-email",[218],{"type":39,"value":219},"Step 3: Add a transform that formats and sends the email",{"type":34,"tag":35,"props":221,"children":222},{},[223,225,232,234,238,240,245],{"type":39,"value":224},"Open the ",{"type":34,"tag":54,"props":226,"children":229},{"href":227,"rel":228},"https://my.webhookrelay.com/functions",[58],[230],{"type":39,"value":231},"Functions",{"type":39,"value":233}," page, create a function \"from scratch\", and attach it to your input. The example below uses ",{"type":34,"tag":42,"props":235,"children":236},{},[237],{"type":39,"value":138},{"type":39,"value":239},". First, on the function's ",{"type":34,"tag":42,"props":241,"children":242},{},[243],{"type":39,"value":244},"config variables",{"type":39,"value":246}," tab, set:",{"type":34,"tag":248,"props":249,"children":250},"ul",{},[251,262],{"type":34,"tag":252,"props":253,"children":254},"li",{},[255,260],{"type":34,"tag":42,"props":256,"children":257},{},[258],{"type":39,"value":259},"api_key",{"type":39,"value":261}," — your Mailgun API key",{"type":34,"tag":252,"props":263,"children":264},{},[265,270,272,278],{"type":34,"tag":42,"props":266,"children":267},{},[268],{"type":39,"value":269},"domain",{"type":39,"value":271}," — your Mailgun sending domain (e.g. ",{"type":34,"tag":98,"props":273,"children":275},{"className":274},[],[276],{"type":39,"value":277},"mg.example.com",{"type":39,"value":279},")",{"type":34,"tag":35,"props":281,"children":282},{},[283],{"type":39,"value":284},"Then paste the function body, replacing the sender and recipient addresses:",{"type":34,"tag":92,"props":286,"children":290},{"className":287,"code":288,"language":289,"meta":7,"style":7},"language-lua shiki shiki-themes github-dark","local mailgun = require(\"mailgun\")\nlocal json = require(\"json\")\n\n-- Decode the incoming webhook so we can pull out fields\nlocal event, err = json.decode(r.RequestBody)\nif err then error(err) end\n\n-- Build a readable message from whatever your source sent\nlocal subject = \"Webhook: \" .. (event.type or \"new event\")\nlocal text = string.format([[\nA new event arrived.\n\nType:    %s\nMessage: %s\n\nRaw payload:\n%s\n]], event.type or \"unknown\", event.message or \"(none)\", r.RequestBody)\n\n-- Initialise Mailgun with your config variables\nerr = mailgun.initialize(cfg:GetValue(\"domain\"), cfg:GetValue(\"api_key\"), \"us\")\nif err then error(err) end\n\n-- Send the email\nerr = mailgun.send(\n    \"from-address@example.com\",\n    subject,\n    text,\n    \"to-address@example.com\"\n)\nif err then error(err) end\n\nr:SetRequestBody(\"email sent\")\n","lua",[291],{"type":34,"tag":98,"props":292,"children":293},{"__ignoreMap":7},[294,336,369,379,389,431,465,473,482,533,564,573,581,590,599,607,616,625,683,691,700,790,818,826,835,861,875,884,893,902,910,938,946],{"type":34,"tag":102,"props":295,"children":296},{"class":104,"line":105},[297,303,309,314,320,325,331],{"type":34,"tag":102,"props":298,"children":300},{"style":299},"--shiki-default:#F97583",[301],{"type":39,"value":302},"local",{"type":34,"tag":102,"props":304,"children":306},{"style":305},"--shiki-default:#E1E4E8",[307],{"type":39,"value":308}," mailgun ",{"type":34,"tag":102,"props":310,"children":311},{"style":299},[312],{"type":39,"value":313},"=",{"type":34,"tag":102,"props":315,"children":317},{"style":316},"--shiki-default:#79B8FF",[318],{"type":39,"value":319}," require",{"type":34,"tag":102,"props":321,"children":322},{"style":305},[323],{"type":39,"value":324},"(",{"type":34,"tag":102,"props":326,"children":328},{"style":327},"--shiki-default:#9ECBFF",[329],{"type":39,"value":330},"\"mailgun\"",{"type":34,"tag":102,"props":332,"children":333},{"style":305},[334],{"type":39,"value":335},")\n",{"type":34,"tag":102,"props":337,"children":338},{"class":104,"line":114},[339,343,348,352,356,360,365],{"type":34,"tag":102,"props":340,"children":341},{"style":299},[342],{"type":39,"value":302},{"type":34,"tag":102,"props":344,"children":345},{"style":305},[346],{"type":39,"value":347}," json ",{"type":34,"tag":102,"props":349,"children":350},{"style":299},[351],{"type":39,"value":313},{"type":34,"tag":102,"props":353,"children":354},{"style":316},[355],{"type":39,"value":319},{"type":34,"tag":102,"props":357,"children":358},{"style":305},[359],{"type":39,"value":324},{"type":34,"tag":102,"props":361,"children":362},{"style":327},[363],{"type":39,"value":364},"\"json\"",{"type":34,"tag":102,"props":366,"children":367},{"style":305},[368],{"type":39,"value":335},{"type":34,"tag":102,"props":370,"children":372},{"class":104,"line":371},3,[373],{"type":34,"tag":102,"props":374,"children":376},{"emptyLinePlaceholder":375},true,[377],{"type":39,"value":378},"\n",{"type":34,"tag":102,"props":380,"children":382},{"class":104,"line":381},4,[383],{"type":34,"tag":102,"props":384,"children":386},{"style":385},"--shiki-default:#6A737D",[387],{"type":39,"value":388},"-- Decode the incoming webhook so we can pull out fields\n",{"type":34,"tag":102,"props":390,"children":392},{"class":104,"line":391},5,[393,397,402,406,411,416,421,427],{"type":34,"tag":102,"props":394,"children":395},{"style":299},[396],{"type":39,"value":302},{"type":34,"tag":102,"props":398,"children":399},{"style":305},[400],{"type":39,"value":401}," event, err ",{"type":34,"tag":102,"props":403,"children":404},{"style":299},[405],{"type":39,"value":313},{"type":34,"tag":102,"props":407,"children":408},{"style":305},[409],{"type":39,"value":410}," json.",{"type":34,"tag":102,"props":412,"children":413},{"style":316},[414],{"type":39,"value":415},"decode",{"type":34,"tag":102,"props":417,"children":418},{"style":305},[419],{"type":39,"value":420},"(r.",{"type":34,"tag":102,"props":422,"children":424},{"style":423},"--shiki-default:#B392F0",[425],{"type":39,"value":426},"RequestBody",{"type":34,"tag":102,"props":428,"children":429},{"style":305},[430],{"type":39,"value":335},{"type":34,"tag":102,"props":432,"children":434},{"class":104,"line":433},6,[435,440,445,450,455,460],{"type":34,"tag":102,"props":436,"children":437},{"style":299},[438],{"type":39,"value":439},"if",{"type":34,"tag":102,"props":441,"children":442},{"style":305},[443],{"type":39,"value":444}," err ",{"type":34,"tag":102,"props":446,"children":447},{"style":299},[448],{"type":39,"value":449},"then",{"type":34,"tag":102,"props":451,"children":452},{"style":316},[453],{"type":39,"value":454}," error",{"type":34,"tag":102,"props":456,"children":457},{"style":305},[458],{"type":39,"value":459},"(err) ",{"type":34,"tag":102,"props":461,"children":462},{"style":299},[463],{"type":39,"value":464},"end\n",{"type":34,"tag":102,"props":466,"children":468},{"class":104,"line":467},7,[469],{"type":34,"tag":102,"props":470,"children":471},{"emptyLinePlaceholder":375},[472],{"type":39,"value":378},{"type":34,"tag":102,"props":474,"children":476},{"class":104,"line":475},8,[477],{"type":34,"tag":102,"props":478,"children":479},{"style":385},[480],{"type":39,"value":481},"-- Build a readable message from whatever your source sent\n",{"type":34,"tag":102,"props":483,"children":485},{"class":104,"line":484},9,[486,490,495,499,504,509,514,519,524,529],{"type":34,"tag":102,"props":487,"children":488},{"style":299},[489],{"type":39,"value":302},{"type":34,"tag":102,"props":491,"children":492},{"style":305},[493],{"type":39,"value":494}," subject ",{"type":34,"tag":102,"props":496,"children":497},{"style":299},[498],{"type":39,"value":313},{"type":34,"tag":102,"props":500,"children":501},{"style":327},[502],{"type":39,"value":503}," \"Webhook: \" ",{"type":34,"tag":102,"props":505,"children":506},{"style":299},[507],{"type":39,"value":508},"..",{"type":34,"tag":102,"props":510,"children":511},{"style":305},[512],{"type":39,"value":513}," (event.",{"type":34,"tag":102,"props":515,"children":516},{"style":423},[517],{"type":39,"value":518},"type",{"type":34,"tag":102,"props":520,"children":521},{"style":299},[522],{"type":39,"value":523}," or",{"type":34,"tag":102,"props":525,"children":526},{"style":327},[527],{"type":39,"value":528}," \"new event\"",{"type":34,"tag":102,"props":530,"children":531},{"style":305},[532],{"type":39,"value":335},{"type":34,"tag":102,"props":534,"children":536},{"class":104,"line":535},10,[537,541,546,550,555,559],{"type":34,"tag":102,"props":538,"children":539},{"style":299},[540],{"type":39,"value":302},{"type":34,"tag":102,"props":542,"children":543},{"style":305},[544],{"type":39,"value":545}," text ",{"type":34,"tag":102,"props":547,"children":548},{"style":299},[549],{"type":39,"value":313},{"type":34,"tag":102,"props":551,"children":552},{"style":316},[553],{"type":39,"value":554}," string.format",{"type":34,"tag":102,"props":556,"children":557},{"style":305},[558],{"type":39,"value":324},{"type":34,"tag":102,"props":560,"children":561},{"style":327},[562],{"type":39,"value":563},"[[\n",{"type":34,"tag":102,"props":565,"children":567},{"class":104,"line":566},11,[568],{"type":34,"tag":102,"props":569,"children":570},{"style":327},[571],{"type":39,"value":572},"A new event arrived.\n",{"type":34,"tag":102,"props":574,"children":576},{"class":104,"line":575},12,[577],{"type":34,"tag":102,"props":578,"children":579},{"emptyLinePlaceholder":375},[580],{"type":39,"value":378},{"type":34,"tag":102,"props":582,"children":584},{"class":104,"line":583},13,[585],{"type":34,"tag":102,"props":586,"children":587},{"style":327},[588],{"type":39,"value":589},"Type:    %s\n",{"type":34,"tag":102,"props":591,"children":593},{"class":104,"line":592},14,[594],{"type":34,"tag":102,"props":595,"children":596},{"style":327},[597],{"type":39,"value":598},"Message: %s\n",{"type":34,"tag":102,"props":600,"children":602},{"class":104,"line":601},15,[603],{"type":34,"tag":102,"props":604,"children":605},{"emptyLinePlaceholder":375},[606],{"type":39,"value":378},{"type":34,"tag":102,"props":608,"children":610},{"class":104,"line":609},16,[611],{"type":34,"tag":102,"props":612,"children":613},{"style":327},[614],{"type":39,"value":615},"Raw payload:\n",{"type":34,"tag":102,"props":617,"children":619},{"class":104,"line":618},17,[620],{"type":34,"tag":102,"props":621,"children":622},{"style":327},[623],{"type":39,"value":624},"%s\n",{"type":34,"tag":102,"props":626,"children":628},{"class":104,"line":627},18,[629,634,639,643,647,652,656,661,665,670,675,679],{"type":34,"tag":102,"props":630,"children":631},{"style":327},[632],{"type":39,"value":633},"]]",{"type":34,"tag":102,"props":635,"children":636},{"style":305},[637],{"type":39,"value":638},", event.",{"type":34,"tag":102,"props":640,"children":641},{"style":423},[642],{"type":39,"value":518},{"type":34,"tag":102,"props":644,"children":645},{"style":299},[646],{"type":39,"value":523},{"type":34,"tag":102,"props":648,"children":649},{"style":327},[650],{"type":39,"value":651}," \"unknown\"",{"type":34,"tag":102,"props":653,"children":654},{"style":305},[655],{"type":39,"value":638},{"type":34,"tag":102,"props":657,"children":658},{"style":423},[659],{"type":39,"value":660},"message",{"type":34,"tag":102,"props":662,"children":663},{"style":299},[664],{"type":39,"value":523},{"type":34,"tag":102,"props":666,"children":667},{"style":327},[668],{"type":39,"value":669}," \"(none)\"",{"type":34,"tag":102,"props":671,"children":672},{"style":305},[673],{"type":39,"value":674},", r.",{"type":34,"tag":102,"props":676,"children":677},{"style":423},[678],{"type":39,"value":426},{"type":34,"tag":102,"props":680,"children":681},{"style":305},[682],{"type":39,"value":335},{"type":34,"tag":102,"props":684,"children":686},{"class":104,"line":685},19,[687],{"type":34,"tag":102,"props":688,"children":689},{"emptyLinePlaceholder":375},[690],{"type":39,"value":378},{"type":34,"tag":102,"props":692,"children":694},{"class":104,"line":693},20,[695],{"type":34,"tag":102,"props":696,"children":697},{"style":385},[698],{"type":39,"value":699},"-- Initialise Mailgun with your config variables\n",{"type":34,"tag":102,"props":701,"children":703},{"class":104,"line":702},21,[704,709,713,718,723,727,732,737,742,746,751,756,760,764,768,772,777,781,786],{"type":34,"tag":102,"props":705,"children":706},{"style":305},[707],{"type":39,"value":708},"err ",{"type":34,"tag":102,"props":710,"children":711},{"style":299},[712],{"type":39,"value":313},{"type":34,"tag":102,"props":714,"children":715},{"style":305},[716],{"type":39,"value":717}," mailgun.",{"type":34,"tag":102,"props":719,"children":720},{"style":316},[721],{"type":39,"value":722},"initialize",{"type":34,"tag":102,"props":724,"children":725},{"style":305},[726],{"type":39,"value":324},{"type":34,"tag":102,"props":728,"children":729},{"style":423},[730],{"type":39,"value":731},"cfg",{"type":34,"tag":102,"props":733,"children":734},{"style":305},[735],{"type":39,"value":736},":",{"type":34,"tag":102,"props":738,"children":739},{"style":316},[740],{"type":39,"value":741},"GetValue",{"type":34,"tag":102,"props":743,"children":744},{"style":305},[745],{"type":39,"value":324},{"type":34,"tag":102,"props":747,"children":748},{"style":327},[749],{"type":39,"value":750},"\"domain\"",{"type":34,"tag":102,"props":752,"children":753},{"style":305},[754],{"type":39,"value":755},"), ",{"type":34,"tag":102,"props":757,"children":758},{"style":423},[759],{"type":39,"value":731},{"type":34,"tag":102,"props":761,"children":762},{"style":305},[763],{"type":39,"value":736},{"type":34,"tag":102,"props":765,"children":766},{"style":316},[767],{"type":39,"value":741},{"type":34,"tag":102,"props":769,"children":770},{"style":305},[771],{"type":39,"value":324},{"type":34,"tag":102,"props":773,"children":774},{"style":327},[775],{"type":39,"value":776},"\"api_key\"",{"type":34,"tag":102,"props":778,"children":779},{"style":305},[780],{"type":39,"value":755},{"type":34,"tag":102,"props":782,"children":783},{"style":327},[784],{"type":39,"value":785},"\"us\"",{"type":34,"tag":102,"props":787,"children":788},{"style":305},[789],{"type":39,"value":335},{"type":34,"tag":102,"props":791,"children":793},{"class":104,"line":792},22,[794,798,802,806,810,814],{"type":34,"tag":102,"props":795,"children":796},{"style":299},[797],{"type":39,"value":439},{"type":34,"tag":102,"props":799,"children":800},{"style":305},[801],{"type":39,"value":444},{"type":34,"tag":102,"props":803,"children":804},{"style":299},[805],{"type":39,"value":449},{"type":34,"tag":102,"props":807,"children":808},{"style":316},[809],{"type":39,"value":454},{"type":34,"tag":102,"props":811,"children":812},{"style":305},[813],{"type":39,"value":459},{"type":34,"tag":102,"props":815,"children":816},{"style":299},[817],{"type":39,"value":464},{"type":34,"tag":102,"props":819,"children":821},{"class":104,"line":820},23,[822],{"type":34,"tag":102,"props":823,"children":824},{"emptyLinePlaceholder":375},[825],{"type":39,"value":378},{"type":34,"tag":102,"props":827,"children":829},{"class":104,"line":828},24,[830],{"type":34,"tag":102,"props":831,"children":832},{"style":385},[833],{"type":39,"value":834},"-- Send the email\n",{"type":34,"tag":102,"props":836,"children":838},{"class":104,"line":837},25,[839,843,847,851,856],{"type":34,"tag":102,"props":840,"children":841},{"style":305},[842],{"type":39,"value":708},{"type":34,"tag":102,"props":844,"children":845},{"style":299},[846],{"type":39,"value":313},{"type":34,"tag":102,"props":848,"children":849},{"style":305},[850],{"type":39,"value":717},{"type":34,"tag":102,"props":852,"children":853},{"style":316},[854],{"type":39,"value":855},"send",{"type":34,"tag":102,"props":857,"children":858},{"style":305},[859],{"type":39,"value":860},"(\n",{"type":34,"tag":102,"props":862,"children":864},{"class":104,"line":863},26,[865,870],{"type":34,"tag":102,"props":866,"children":867},{"style":327},[868],{"type":39,"value":869},"    \"from-address@example.com\"",{"type":34,"tag":102,"props":871,"children":872},{"style":305},[873],{"type":39,"value":874},",\n",{"type":34,"tag":102,"props":876,"children":878},{"class":104,"line":877},27,[879],{"type":34,"tag":102,"props":880,"children":881},{"style":305},[882],{"type":39,"value":883},"    subject,\n",{"type":34,"tag":102,"props":885,"children":887},{"class":104,"line":886},28,[888],{"type":34,"tag":102,"props":889,"children":890},{"style":305},[891],{"type":39,"value":892},"    text,\n",{"type":34,"tag":102,"props":894,"children":896},{"class":104,"line":895},29,[897],{"type":34,"tag":102,"props":898,"children":899},{"style":327},[900],{"type":39,"value":901},"    \"to-address@example.com\"\n",{"type":34,"tag":102,"props":903,"children":905},{"class":104,"line":904},30,[906],{"type":34,"tag":102,"props":907,"children":908},{"style":305},[909],{"type":39,"value":335},{"type":34,"tag":102,"props":911,"children":913},{"class":104,"line":912},31,[914,918,922,926,930,934],{"type":34,"tag":102,"props":915,"children":916},{"style":299},[917],{"type":39,"value":439},{"type":34,"tag":102,"props":919,"children":920},{"style":305},[921],{"type":39,"value":444},{"type":34,"tag":102,"props":923,"children":924},{"style":299},[925],{"type":39,"value":449},{"type":34,"tag":102,"props":927,"children":928},{"style":316},[929],{"type":39,"value":454},{"type":34,"tag":102,"props":931,"children":932},{"style":305},[933],{"type":39,"value":459},{"type":34,"tag":102,"props":935,"children":936},{"style":299},[937],{"type":39,"value":464},{"type":34,"tag":102,"props":939,"children":941},{"class":104,"line":940},32,[942],{"type":34,"tag":102,"props":943,"children":944},{"emptyLinePlaceholder":375},[945],{"type":39,"value":378},{"type":34,"tag":102,"props":947,"children":949},{"class":104,"line":948},33,[950,955,959,964,968,973],{"type":34,"tag":102,"props":951,"children":952},{"style":423},[953],{"type":39,"value":954},"r",{"type":34,"tag":102,"props":956,"children":957},{"style":305},[958],{"type":39,"value":736},{"type":34,"tag":102,"props":960,"children":961},{"style":316},[962],{"type":39,"value":963},"SetRequestBody",{"type":34,"tag":102,"props":965,"children":966},{"style":305},[967],{"type":39,"value":324},{"type":34,"tag":102,"props":969,"children":970},{"style":327},[971],{"type":39,"value":972},"\"email sent\"",{"type":34,"tag":102,"props":974,"children":975},{"style":305},[976],{"type":39,"value":335},{"type":34,"tag":35,"props":978,"children":979},{},[980],{"type":39,"value":981},"That's the whole integration. Every webhook that hits the input is decoded, formatted, and emailed — no server, no SMTP setup, no cron.",{"type":34,"tag":983,"props":984,"children":985},"blockquote",{},[986],{"type":34,"tag":35,"props":987,"children":988},{},[989,991,997,998,1004,1006,1012],{"type":39,"value":990},"Prefer a different provider? The same pattern works by POSTing to an email API from the function. Build the request body for ",{"type":34,"tag":54,"props":992,"children":995},{"href":993,"rel":994},"https://sendgrid.com",[58],[996],{"type":39,"value":145},{"type":39,"value":140},{"type":34,"tag":54,"props":999,"children":1002},{"href":1000,"rel":1001},"https://postmarkapp.com",[58],[1003],{"type":39,"value":152},{"type":39,"value":1005}," or another service, set the ",{"type":34,"tag":98,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":39,"value":1011},"Authorization",{"type":39,"value":1013}," header from a config variable, and the function delivers it. The structure (decode → format → send) is identical.",{"type":34,"tag":80,"props":1015,"children":1017},{"id":1016},"step-4-filter-so-you-only-get-useful-email",[1018],{"type":39,"value":1019},"Step 4: Filter so you only get useful email",{"type":34,"tag":35,"props":1021,"children":1022},{},[1023],{"type":39,"value":1024},"The fastest way to ruin email notifications is to send too many. Filter inside the function. For example, skip low-value events and drop the request entirely:",{"type":34,"tag":92,"props":1026,"children":1028},{"className":287,"code":1027,"language":289,"meta":7,"style":7},"-- Only email on the events you care about\nif event.type ~= \"payment.succeeded\" then\n    r:StopForwarding()\n    return\nend\n",[1029],{"type":34,"tag":98,"props":1030,"children":1031},{"__ignoreMap":7},[1032,1040,1071,1093,1101],{"type":34,"tag":102,"props":1033,"children":1034},{"class":104,"line":105},[1035],{"type":34,"tag":102,"props":1036,"children":1037},{"style":385},[1038],{"type":39,"value":1039},"-- Only email on the events you care about\n",{"type":34,"tag":102,"props":1041,"children":1042},{"class":104,"line":114},[1043,1047,1052,1056,1061,1066],{"type":34,"tag":102,"props":1044,"children":1045},{"style":299},[1046],{"type":39,"value":439},{"type":34,"tag":102,"props":1048,"children":1049},{"style":305},[1050],{"type":39,"value":1051}," event.",{"type":34,"tag":102,"props":1053,"children":1054},{"style":423},[1055],{"type":39,"value":518},{"type":34,"tag":102,"props":1057,"children":1058},{"style":299},[1059],{"type":39,"value":1060}," ~=",{"type":34,"tag":102,"props":1062,"children":1063},{"style":327},[1064],{"type":39,"value":1065}," \"payment.succeeded\" ",{"type":34,"tag":102,"props":1067,"children":1068},{"style":299},[1069],{"type":39,"value":1070},"then\n",{"type":34,"tag":102,"props":1072,"children":1073},{"class":104,"line":371},[1074,1079,1083,1088],{"type":34,"tag":102,"props":1075,"children":1076},{"style":423},[1077],{"type":39,"value":1078},"    r",{"type":34,"tag":102,"props":1080,"children":1081},{"style":305},[1082],{"type":39,"value":736},{"type":34,"tag":102,"props":1084,"children":1085},{"style":316},[1086],{"type":39,"value":1087},"StopForwarding",{"type":34,"tag":102,"props":1089,"children":1090},{"style":305},[1091],{"type":39,"value":1092},"()\n",{"type":34,"tag":102,"props":1094,"children":1095},{"class":104,"line":381},[1096],{"type":34,"tag":102,"props":1097,"children":1098},{"style":299},[1099],{"type":39,"value":1100},"    return\n",{"type":34,"tag":102,"props":1102,"children":1103},{"class":104,"line":391},[1104],{"type":34,"tag":102,"props":1105,"children":1106},{"style":299},[1107],{"type":39,"value":464},{"type":34,"tag":35,"props":1109,"children":1110},{},[1111,1116,1118,1124],{"type":34,"tag":98,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":39,"value":1087},{"type":39,"value":1117}," stops the request right there, so no email goes out and nothing is forwarded. You can also push this upstream with ",{"type":34,"tag":54,"props":1119,"children":1121},{"href":1120},"/features/forwarding-rules",[1122],{"type":39,"value":1123},"forwarding rules",{"type":39,"value":1125}," so only matching events ever reach the function.",{"type":34,"tag":80,"props":1127,"children":1129},{"id":1128},"a-concrete-example-stripe-email",[1130],{"type":39,"value":1131},"A concrete example: Stripe → email",{"type":34,"tag":35,"props":1133,"children":1134},{},[1135,1137,1143],{"type":39,"value":1136},"A classic use of this is emailing yourself when a new customer subscribes. The decode-format-filter-send pattern above is exactly what powers the ",{"type":34,"tag":54,"props":1138,"children":1140},{"href":1139},"/blog/stripe-webhook-to-email",[1141],{"type":39,"value":1142},"Stripe webhook to email walkthrough",{"type":39,"value":1144},", which filters out free-plan signups and emails you the plan, amount, and links straight into the Stripe dashboard on every new paying customer. Swap Stripe for any provider and the shape of the function stays the same.",{"type":34,"tag":80,"props":1146,"children":1148},{"id":1147},"going-further",[1149],{"type":39,"value":1150},"Going further",{"type":34,"tag":248,"props":1152,"children":1153},{},[1154,1164,1190],{"type":34,"tag":252,"props":1155,"children":1156},{},[1157,1162],{"type":34,"tag":42,"props":1158,"children":1159},{},[1160],{"type":39,"value":1161},"Richer formatting.",{"type":39,"value":1163}," Send HTML email by passing an HTML body to your provider, so you can include headings, tables and links instead of plain text.",{"type":34,"tag":252,"props":1165,"children":1166},{},[1167,1172,1174,1180,1182,1188],{"type":34,"tag":42,"props":1168,"children":1169},{},[1170],{"type":39,"value":1171},"Route by content.",{"type":39,"value":1173}," Inspect the payload and choose the recipient dynamically — ",{"type":34,"tag":98,"props":1175,"children":1177},{"className":1176},[],[1178],{"type":39,"value":1179},"payment",{"type":39,"value":1181}," events to finance, ",{"type":34,"tag":98,"props":1183,"children":1185},{"className":1184},[],[1186],{"type":39,"value":1187},"error",{"type":39,"value":1189}," events to on-call.",{"type":34,"tag":252,"props":1191,"children":1192},{},[1193,1205,1207,1213],{"type":34,"tag":42,"props":1194,"children":1195},{},[1196,1198,1203],{"type":39,"value":1197},"Email ",{"type":34,"tag":72,"props":1199,"children":1200},{},[1201],{"type":39,"value":1202},"and",{"type":39,"value":1204}," more.",{"type":39,"value":1206}," A webhook doesn't have to go just one place. Fan the same event out to email plus a chat channel or another API at once with ",{"type":34,"tag":54,"props":1208,"children":1210},{"href":1209},"/features/webhook-multiple-destinations",[1211],{"type":39,"value":1212},"multiple destinations",{"type":39,"value":154},{"type":34,"tag":80,"props":1215,"children":1217},{"id":1216},"faq",[1218],{"type":39,"value":1219},"FAQ",{"type":34,"tag":35,"props":1221,"children":1222},{},[1223,1228],{"type":34,"tag":42,"props":1224,"children":1225},{},[1226],{"type":39,"value":1227},"What do I need besides Webhook Relay?",{"type":39,"value":1229}," An email provider account (Mailgun, SendGrid, Postmark, etc.) and its API key. You store the key as a config variable on the function — it never goes near your source service.",{"type":34,"tag":35,"props":1231,"children":1232},{},[1233,1238,1240,1244],{"type":34,"tag":42,"props":1234,"children":1235},{},[1236],{"type":39,"value":1237},"Will this work with any webhook provider?",{"type":39,"value":1239}," Yes. Anything that can POST to a URL works — payment providers, CI systems, monitors, forms, IoT devices. The function decodes whatever JSON arrives; inspect a real payload in a ",{"type":34,"tag":54,"props":1241,"children":1242},{"href":208},[1243],{"type":39,"value":211},{"type":39,"value":1245}," first to learn the field names.",{"type":34,"tag":35,"props":1247,"children":1248},{},[1249,1254],{"type":34,"tag":42,"props":1250,"children":1251},{},[1252],{"type":39,"value":1253},"Do I need to host anything?",{"type":39,"value":1255}," No. The function — including the email send — runs on Webhook Relay in the cloud. There's nothing to deploy or keep online.",{"type":34,"tag":80,"props":1257,"children":1259},{"id":1258},"get-started",[1260],{"type":39,"value":1261},"Get started",{"type":34,"tag":35,"props":1263,"children":1264},{},[1265,1272,1274,1278,1280,1285],{"type":34,"tag":54,"props":1266,"children":1269},{"href":1267,"rel":1268},"https://my.webhookrelay.com/register",[58],[1270],{"type":39,"value":1271},"Create a free Webhook Relay account",{"type":39,"value":1273},", attach a ",{"type":34,"tag":54,"props":1275,"children":1276},{"href":128},[1277],{"type":39,"value":68},{"type":39,"value":1279},", and turn your next webhook into an email. Not sure what your source sends? ",{"type":34,"tag":54,"props":1281,"children":1282},{"href":208},[1283],{"type":39,"value":1284},"Inspect the payload in a Webhook Bin",{"type":39,"value":1286}," first, then write the function to match.",{"type":34,"tag":1288,"props":1289,"children":1290},"style",{},[1291],{"type":39,"value":1292},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":371,"depth":371,"links":1294},[1295,1296,1297,1298,1299,1300,1301,1302,1303],{"id":82,"depth":114,"text":85},{"id":157,"depth":114,"text":160},{"id":197,"depth":114,"text":200},{"id":216,"depth":114,"text":219},{"id":1016,"depth":114,"text":1019},{"id":1128,"depth":114,"text":1131},{"id":1147,"depth":114,"text":1150},{"id":1216,"depth":114,"text":1219},{"id":1258,"depth":114,"text":1261},"markdown","content:blog:webhook-to-email.md","content","blog/webhook-to-email.md","blog/webhook-to-email","md",{"loc":4},[1312,1316,1320,1324,1328,1332,1336,1340,1344,1348,1352,1356,1360,1364,1368,1372,1376,1380,1384,1388,1392,1396,1400,1404,1408,1412,1416,1420,1424,1428,1432,1435,1439,1443,1447,1451,1455,1459,1463,1467,1471,1475,1479,1483,1487,1491,1495,1499,1503,1507,1511,1515,1519,1523,1527,1531,1535,1538,1542,1546,1550,1554,1558,1562,1565,1568,1572,1576,1580,1584,1588,1592,1596,1600,1604,1608,1612,1616,1617,1621,1625,1629,1633,1637,1641,1645,1649,1653,1657],{"_path":1313,"title":1314,"description":1315},"/blog/airtable-integrations","Airtable integrations: inserting rows","How to setup Airtable  on setting up HTML contact form with Airtable code webhook integration",{"_path":1317,"title":1318,"description":1319},"/blog/auto-deploy-on-git-push","Auto deploy your Node.js app on push to GitHub","Learn how to update your Node.js app on push to GitHub using webhooks on any virtual machine or your local computer",{"_path":1321,"title":1322,"description":1323},"/blog/auto-transform-webhook","Automatically transform webhook payloads","Automatically transform webhook payloads using AI in Webhook Relay. Step-by-step guide to convert webhook data between different formats without coding.",{"_path":1325,"title":1326,"description":1327},"/blog/automated-github-pull-request-builds-on-jenkins","Automated Jenkins builds on GitHub pull request","Configuration example on how to automatically start builds on GitHub pull request",{"_path":1329,"title":1330,"description":1331},"/blog/azure-functions-vs-webhook-relay","Azure Functions vs Webhook Relay: Why I stopped overengineering webhooks","A practical comparison of Azure Functions and Webhook Relay for webhook processing, with code examples showing the difference in setup complexity.",{"_path":1333,"title":1334,"description":1335},"/blog/beeceptor-alternative","A Beeceptor Alternative for Inspecting and Forwarding Webhooks (2026)","Looking for a Beeceptor alternative? Compare Beeceptor and Webhook Relay for inspecting and delivering webhooks — a free Webhook Bin with custom responses, plus forwarding to localhost and private servers, transforms, retries and fan-out. Free plan available.",{"_path":1337,"title":1338,"description":1339},"/blog/cdn-types-and-setup","CDN types and setting them up (Vue, React)","CDN (content delivery network) types and how to set one up (Vue, React)",{"_path":1341,"title":1342,"description":1343},"/blog/cloudflare-support-for-home-assistant","Introducing Cloudflare support for Home Assistant remote access","Webhook Relay Home Assistant remote access add-on now support Cloudflare Domains",{"_path":1345,"title":1346,"description":1347},"/blog/cloudflare-tunnel-alternative","A Cloudflare Tunnel Alternative for Webhooks and Localhost Tunnels (2026)","Looking for a Cloudflare Tunnel alternative? Compare Cloudflare Tunnel and Webhook Relay for exposing localhost and forwarding webhooks — a stable URL with no domain to manage, plus webhook inspection, transforms, retries and fan-out. Free plan available.",{"_path":1349,"title":1350,"description":1351},"/blog/convoy-alternative","A Convoy Alternative for Delivering Webhooks Into Private Infrastructure","Compare Convoy (getconvoy.io) and Webhook Relay. Convoy is an open-source, self-hostable webhook gateway; Webhook Relay is a hosted service that receives webhooks and forwards them to public, localhost and private destinations via the relay agent, with tunnels, transformations and cron, from $9.99/month.",{"_path":1353,"title":1354,"description":1355},"/blog/docker-compose-update-on-github-webhooks","Docker Compose update on Github webhook","Learn how to update Docker Compose on push to Github using webhooks",{"_path":1357,"title":1358,"description":1359},"/blog/domain-based-webhook-endpoints","New feature announcement: domain-based endpoints","Introducing new feature: domain based webhook endpoints",{"_path":1361,"title":1362,"description":1363},"/blog/dotscience-tunnels-jupyter","How Dotscience manages thousands of tunnels to create a better Data Science environment","A case study on how Dotscience utilizes Webhook Relay tunnels",{"_path":1365,"title":1366,"description":1367},"/blog/expose-dev-alternative","An expose.dev Alternative for Webhooks and Tunnels (2026)","Looking for an expose.dev (Expose) alternative? Compare Expose and Webhook Relay for tunneling localhost and forwarding webhooks — stable URLs, transforms, fan-out, retries, and a free plan.",{"_path":1369,"title":1370,"description":1371},"/blog/extra-webhook-packages","Introducing extra webhook packages","Purchase additional webhook capacity directly from your current plan tier",{"_path":1373,"title":1374,"description":1375},"/blog/github-jenkins-guide","Receive Github webhooks on Jenkins without public IP","A short tutorial on how to configure and receive Github webhooks on your jenkins instance even without a public IP",{"_path":1377,"title":1378,"description":1379},"/blog/google-home-ifttt-node-red","Controlling TV with Google Home, IFTTT and Node-RED","Easiest way to start controlling your TV with Google Home, IFTTT and Node-RED",{"_path":1381,"title":1382,"description":1383},"/blog/guardduty-to-gcs-archival","Archive AWS GuardDuty Findings to GCP Cloud Storage","Route AWS GuardDuty security findings to Google Cloud Storage using Webhook Relay Service Connections for long-term retention and cross-cloud analysis",{"_path":1385,"title":1386,"description":1387},"/blog/hassio-tls-tunnels-duckdns","Home Assistant remote access add-on","Reverse tunnels for testing and development environments",{"_path":1389,"title":1390,"description":1391},"/blog/home-assistant-remote-access","Hassle-free remote access to Home Assistant on a Raspberry Pi","How to connect to your Home Assistant without public IP or NAT configuration",{"_path":1393,"title":1394,"description":1395},"/blog/hookdeck-alternative","A Hookdeck Alternative for Delivering Webhooks to Private Infrastructure","Compare Hookdeck and Webhook Relay for webhook infrastructure. Both queue, retry and transform — but Webhook Relay also delivers to localhost and private networks, tunnels, and schedules webhooks, from $9.99/month.",{"_path":1397,"title":1398,"description":1399},"/blog/how-to-create-webhook","What is a webhook and how to create one?","Webhooks are key to building reliable and responsive systems. However, you must know how to use them properly. Let's explore what is a webhook and how to support webhooks in your application",{"_path":1401,"title":1402,"description":1403},"/blog/how-to-debug-webhooks","Debug Webhooks: A Practical Troubleshooting Guide (2026)","Troubleshoot webhooks step by step: when an event never arrives, when it arrives but fails (signature mismatch, wrong content-type, body parsing), plus duplicates, ordering, timeouts and retries. Inspect, forward to localhost, and replay.",{"_path":1405,"title":1406,"description":1407},"/blog/how-to-test-webhooks","How to Test Webhooks: The Complete Guide (2026)","A practical guide to testing webhooks: get an instant URL to inspect payloads, receive webhooks on localhost, replay requests, verify signatures, and test providers like Stripe and GitHub.",{"_path":1409,"title":1410,"description":1411},"/blog/ingesting-facebook-webhooks","Ingesting Facebook webhooks (challenge & verification)","How to receive Facebook webhooks and do verification for challenge and token",{"_path":1413,"title":1414,"description":1415},"/blog/ingress-with-docker-for-mac","Web Relay Ingress with Docker for Mac","Web Relay ingress for Mac lets users expose their local services to the internet for testing and demoing",{"_path":1417,"title":1418,"description":1419},"/blog/install-jenkins-ci-docker","How to install and run a dockerized Jenkins CI with webhook support","A quick tutorial on how to setup a Jenkins CI server using Docker, Synpse and Webhook Relay to have remote SSH access and secure webhooks",{"_path":1421,"title":1422,"description":1423},"/blog/introducing_service_connections","Introducing Service Connections","Connect AWS, GCP, and Azure services through Webhook Relay buckets with fast, flexible cloud-to-cloud routing.",{"_path":1425,"title":1426,"description":1427},"/blog/introducing-keel","Keel - automated Kubernetes updates","Automatically update kubernetes deployments on image push",{"_path":1429,"title":1430,"description":1431},"/blog/introducing-websocket-server","Introducing WebSocket Server","Listen for new webhooks directly from your application using websockets",{"_path":1433,"title":1434,"description":1387},"/blog/introduction","Introduction to Webhook Relay",{"_path":1436,"title":1437,"description":1438},"/blog/kubernetes-redis-commander","DevOps Use Case: Performing Redis maintenance in Kubernetes","Use Redis-Commander with Webhook Relay ingress controller to access Redis in a Kubernetes cluster",{"_path":1440,"title":1441,"description":1442},"/blog/lightning-ai-company-webhooks-setup","How Lightning AI uses WHR to ship webhooks to the entire team","How Lightning AI uses Webhook Relay container to broadcast Stripe webhooks to every developer's laptop and staging environment simultaneously - zero setup required",{"_path":1444,"title":1445,"description":1446},"/blog/localtunnel-alternative","A Reliable localtunnel Alternative for Webhooks and Tunnels (2026)","Looking for a reliable localtunnel alternative? Compare localtunnel and Webhook Relay for exposing localhost and forwarding webhooks — stable URLs, retries, inspection, and a free plan.",{"_path":1448,"title":1449,"description":1450},"/blog/mailgun-webhook-fanout","Mailgun webhook fan-out","How to send mailgun webhooks to multiple destinations",{"_path":1452,"title":1453,"description":1454},"/blog/may-10th-outage-gke-controlplane","Managed GKE control-plane failure resulting in platform outage on 10th May, 2022","An RCA on how the managed GKE control-plane failure brought down the platform",{"_path":1456,"title":1457,"description":1458},"/blog/ngrok-alternative","An ngrok Alternative for Webhooks and Localhost Tunnels (2026)","Looking for an ngrok alternative? Compare ngrok and Webhook Relay for exposing localhost, testing webhooks, and forwarding them to private servers — stable URLs, no session timeouts, and a free plan.",{"_path":1460,"title":1461,"description":1462},"/blog/nodered-owntracks-direct","Node-RED OwnTracks location tracking without public IP/MQTT","How to get webhooks from OwnTracks to Node-RED without public IP or configuring NAT",{"_path":1464,"title":1465,"description":1466},"/blog/openapi-redoc-tutorial","Documenting your API with OpenAPI (Swagger) and Redoc","API tooling review and a guide on how to document your API with Swagger's OpenAPI and Redoc",{"_path":1468,"title":1469,"description":1470},"/blog/pipedream-alternative","A Pipedream Alternative for Webhook Routing and Private Delivery","Compare Pipedream and Webhook Relay for webhooks. Pipedream is a no-code automation platform; Webhook Relay is dedicated webhook infrastructure that delivers to localhost and private networks, with tunnels, transformations and cron, from $9.99/month.",{"_path":1472,"title":1473,"description":1474},"/blog/pricing-changes","Changes to our prices for new customers","As of 1st of May 2021, new WHR subscribers will be subject to new prices.",{"_path":1476,"title":1477,"description":1478},"/blog/rancher-push-to-deploy-workflow","Rancher - push to deploy workflow with Keel","Configuring push to deploy workflow with Rancher and Keel",{"_path":1480,"title":1481,"description":1482},"/blog/receive-calendly-webhooks-locally","Test Calendly Webhooks Locally (Calendly Webhook on localhost)","Test Calendly webhooks locally on localhost without deploying. Create the API webhook subscription, inspect the real invitee.created payload, and verify the signature.",{"_path":1484,"title":1485,"description":1486},"/blog/receive-clerk-webhooks-locally","Test Clerk Webhooks Locally (Receive Clerk Webhooks on localhost)","Test Clerk webhooks locally and receive them on localhost without deploying. Inspect the real payload, forward to your handler, and verify the Svix signature.",{"_path":1488,"title":1489,"description":1490},"/blog/receive-datadog-webhooks-locally","Receive Datadog Webhooks Locally (Test Datadog Webhooks on localhost)","Test Datadog webhooks locally on localhost without deploying. Inspect the real alert payload, forward monitor notifications to your handler, and verify the request.",{"_path":1492,"title":1493,"description":1494},"/blog/receive-github-webhooks-locally","Receive GitHub Webhooks Locally (Test GitHub Webhooks on localhost)","Receive GitHub webhooks locally and test them on localhost without deploying. Inspect the real payload, forward to your handler, and verify the signature.",{"_path":1496,"title":1497,"description":1498},"/blog/receive-gitlab-webhooks-locally","Receive GitLab Webhooks Locally (No Public IP Required)","Receive GitLab webhooks locally with no public IP. Inspect the real payload, forward push and merge request events to localhost, and verify the token.",{"_path":1500,"title":1501,"description":1502},"/blog/receive-mailgun-webhooks-locally","Receive Mailgun Webhooks Locally (Test Mailgun Webhooks on localhost)","Test Mailgun webhooks locally on localhost without deploying. Inspect the real event payload, forward delivered/opened/bounced events to your handler, and verify the signature.",{"_path":1504,"title":1505,"description":1506},"/blog/receive-sendgrid-webhooks-locally","Test SendGrid Webhooks Locally (SendGrid Event Webhook on localhost)","Test the SendGrid Event Webhook locally on localhost without deploying. Inspect the real JSON event array, forward to your handler, and verify the signed webhook signature.",{"_path":1508,"title":1509,"description":1510},"/blog/receive-sentry-webhooks-locally","Test Sentry Webhooks Locally (Receive Sentry Webhooks on localhost)","Test Sentry webhooks locally and receive them on localhost without deploying. Inspect the real payload, forward to your handler, and verify the Sentry-Hook-Signature.",{"_path":1512,"title":1513,"description":1514},"/blog/receive-slack-events-locally","Receive Slack Events Locally: Test Slack Webhooks on localhost","Test Slack webhooks locally without deploying. Forward Events API requests to localhost, pass the url_verification challenge, and verify the X-Slack-Signature header.",{"_path":1516,"title":1517,"description":1518},"/blog/receive-square-webhooks-locally","Receive Square Webhooks Locally (Test Square Webhooks on localhost)","Receive Square webhooks locally and test them on localhost without deploying. Inspect the real payment.created payload, forward to your handler, and verify the HMAC signature.",{"_path":1520,"title":1521,"description":1522},"/blog/receive-twilio-webhooks-locally","Receive Twilio Webhooks Locally: Test Twilio Webhooks on localhost","Test Twilio webhooks locally without deploying. Forward incoming SMS and voice callbacks to localhost, handle Twilio's form-encoded body, and verify X-Twilio-Signature.",{"_path":1524,"title":1525,"description":1526},"/blog/receive-typeform-webhooks-locally","Test Typeform Webhooks Locally (Typeform Webhook on localhost)","Test Typeform webhooks locally on localhost without deploying. Add the webhook in the Typeform UI, inspect the real form_response payload, and verify the signature.",{"_path":1528,"title":1529,"description":1530},"/blog/receiving-paypal-webhooks-localhost","How to receive Paypal webhooks on localhost","Often when building an application that integrates with 3rd party services we need a way to receive webhooks",{"_path":1532,"title":1533,"description":1534},"/blog/receiving-shopify-webhooks-flask-api","Receive Shopify webhooks on Flask API","How to get Shopify webhooks working on your local Flask app, with proper signature verification",{"_path":1536,"title":1537,"description":1530},"/blog/receiving-stripe-webhooks-localhost","How to receive Stripe webhooks on localhost",{"_path":1539,"title":1540,"description":1541},"/blog/remote-tube-downloader","Remote YouTube downloader Slack bot","A short tutorial to help you build a remote YouTube video downloader using WebSockets and Slack",{"_path":1543,"title":1544,"description":1545},"/blog/requestbin-alternative","A RequestBin Alternative: Free Webhook Inspector, No Signup","The original free RequestBin is gone. Webhook Relay's Webhook Bin is a free RequestBin alternative — get an instant URL, inspect HTTP requests and webhooks in real time, then forward them to localhost.",{"_path":1547,"title":1548,"description":1549},"/blog/responding-to-api-calls-on-nodered","Responding to API calls using Node-RED Webhook Relay node","How to respond to API calls using Node-RED Webhook Relay node",{"_path":1551,"title":1552,"description":1553},"/blog/setting-up-selfhosted-metabase","Self-hosted business intelligence with Metabase","Setting up self-hosted Metabase on-prem",{"_path":1555,"title":1556,"description":1557},"/blog/smee-io-alternative","A smee.io Alternative for Reliable Webhook Forwarding","smee.io is great for quick GitHub webhook tests but is explicitly dev-only. Webhook Relay is a production-ready smee.io alternative: stable URLs, retries, and forwarding to localhost or private servers.",{"_path":1559,"title":1560,"description":1561},"/blog/static-ip","Static IPs for outgoing webhooks","How to setup static IPs for webhook calls to enable whitelisting",{"_path":1563,"title":1564,"description":1561},"/blog/static-ips-for-webhook-whitelisting","Static IPs for webhook calls to enable whitelisting",{"_path":1139,"title":1566,"description":1567},"Receive emails on new Stripe subscribers","It's nice to get Stripe notifications on new payments however we can turn any Stripe into an email",{"_path":1569,"title":1570,"description":1571},"/blog/svix-alternative","A Svix Alternative for Receiving and Forwarding Webhooks Into Private Infrastructure","Compare Svix and Webhook Relay. Svix sends webhooks to your customers; Webhook Relay receives third-party webhooks and forwards them to public, localhost and private destinations, with tunnels, transformations and cron, from $9.99/month.",{"_path":1573,"title":1574,"description":1575},"/blog/trading-view","TradingView Webhooks: Automate Alerts to Discord, Slack & More","Send TradingView alerts anywhere with webhooks. Step-by-step setup to forward TradingView webhook alerts to Discord, Slack, email or a trading API — with payload formatting and transformations.",{"_path":1577,"title":1578,"description":1579},"/blog/tunnels-to-kubernetes","Providing access to Kubernetes through tunnels in one of the largest cities in Lithuania","How Lithuania's transport operator uses Webhook Relay tunnels to provide easy access to private Kubernetes clusters using TLS pass-through tunnels mixed with an ingress",{"_path":1581,"title":1582,"description":1583},"/blog/using-drone-for-simple-selfhosted-ci-cd","Setting up simple, self-hosted & fast CI/CD solution with Drone.io","A guide/tutorial on how to set up Drone as a self-hosted CI/CD solution for private projects",{"_path":1585,"title":1586,"description":1587},"/blog/using-google-firestore-for-go-backend","Using Google Firestore for a Golang backend application","Switching from internal KV store to a Google Firestore can be quick and easy",{"_path":1589,"title":1590,"description":1591},"/blog/verify-webhook-signature","How to Verify a Webhook Signature (HMAC SHA256)","Verify webhook signatures so you only trust authentic requests. How HMAC SHA256 signing works, how GitHub, Stripe and Shopify do it, a Node.js example, and a free verifier.",{"_path":1593,"title":1594,"description":1595},"/blog/webhook-authentication","Webhook Authentication: HMAC, Tokens, mTLS and IP Allow-listing Compared","A practical guide to webhook authentication: how HMAC signatures, shared-secret tokens, basic auth, mTLS, IP allow-listing and JWT work, their trade-offs, and when to use each to verify incoming webhooks.",{"_path":1597,"title":1598,"description":1599},"/blog/webhook-retries-and-idempotency","Webhook Retries and Idempotency: A Practical Guide","Why webhook deliveries fail, how providers retry with exponential backoff, why duplicate events happen, and how to build idempotent handlers that dedupe on event ID and survive at-least-once delivery.",{"_path":1601,"title":1602,"description":1603},"/blog/webhook-rule-based-filters","Rules-based webhook filtering & routing","Example use-case of rules-based routing and filtering for GitHub webhooks",{"_path":1605,"title":1606,"description":1607},"/blog/webhook-security","Webhook Security: Best Practices to Secure Your Webhooks","Explore essential measures to fortify your webhooks. Dive into the latest security best practices to ensure reliable, safe data transfers and protect your applications from vulnerabilities.",{"_path":1609,"title":1610,"description":1611},"/blog/webhook-site-alternative","A webhook.site Alternative for Testing and Forwarding Webhooks","A webhook.site alternative that does more than inspect: get an instant webhook URL, see requests in real time, then forward them to localhost or a private server. Free, with no request cap to start.",{"_path":1613,"title":1614,"description":1615},"/blog/webhook-to-discord","Send a Webhook to Discord: Transform & Forward Any Payload","Send any webhook to Discord. Step-by-step guide to forward an incoming webhook to a Discord channel, transforming the raw payload into Discord's { content } format in flight.",{"_path":4,"title":8,"description":9},{"_path":1618,"title":1619,"description":1620},"/blog/webhook-to-microsoft-teams","Send a Webhook to Microsoft Teams: Transform & Forward Any Payload","Send any incoming webhook to Microsoft Teams. Forward an event through Webhook Relay, transform the raw payload into the Teams message JSON in flight, and post it to a Teams Incoming Webhook or Power Automate Workflow URL.",{"_path":1622,"title":1623,"description":1624},"/blog/webhook-to-pubsub","How to Send Webhooks to Google Cloud Pub/Sub","Publish incoming webhooks straight to a Google Cloud Pub/Sub topic with Webhook Relay Service Connections — no Cloud Function to write. Build event-driven pipelines from any webhook.",{"_path":1626,"title":1627,"description":1628},"/blog/webhook-to-s3","How to Archive Webhooks to Amazon S3 (Store Every Payload)","Store every incoming webhook in Amazon S3 with Webhook Relay Service Connections — no code. Keep an auditable archive of payloads for compliance, debugging and replay.",{"_path":1630,"title":1631,"description":1632},"/blog/webhook-to-slack","Send a Webhook to Slack: Transform & Forward Any Payload","Send any webhook to Slack. Step-by-step guide to forward an incoming webhook into a Slack channel, transforming the raw payload into Slack's { text } format in flight.",{"_path":1634,"title":1635,"description":1636},"/blog/webhook-to-sqs","How to Send Webhooks to AWS SQS (No Consumer Code)","Forward incoming webhooks straight into an Amazon SQS queue with Webhook Relay Service Connections — no Lambda, no consumer to write. Decouple, buffer, and process webhooks reliably.",{"_path":1638,"title":1639,"description":1640},"/blog/webhookrelayd-with-podman","Running Webhook Relay agent with Podman","A short guide how to run Webhook Relay agent with Podman",{"_path":1642,"title":1643,"description":1644},"/blog/webhooks-to-jenkins-on-kubernetes","Secure webhooks to Jenkins on Kubernetes","A tutorial on how to securely receive GitHub webhooks on your Jenkins inside a Kubernetes cluster",{"_path":1646,"title":1647,"description":1648},"/blog/webhooks-vs-api","Webhooks vs API: What's the Difference?","Webhooks and APIs both move data between systems, but one pulls and the other pushes. A clear explanation of webhooks vs APIs, when to use each, and how they work together.",{"_path":1650,"title":1651,"description":1652},"/blog/what-is-a-webhook-gateway","What Is a Webhook Gateway? A Practical Guide","A webhook gateway is a managed layer that receives, verifies, queues, transforms, routes, retries and fans out webhooks between producers and your services. Here's what it does, why teams use one, and build-vs-buy.",{"_path":1654,"title":1655,"description":1656},"/blog/what-is-webhook","What is a Webhook? Definition, Examples & How to Set One Up","What is a webhook? A webhook is an automated HTTP request a service sends when an event happens. Learn how webhooks work, see examples, set one up in Node.js, and follow best practices.",{"_path":1658,"title":1659,"description":1660},"/blog/zapier-webhooks-alternative","A Zapier Webhooks Alternative for Developer-Grade Webhook Delivery","Compare Webhooks by Zapier and Webhook Relay. Zapier is no-code automation across thousands of apps; Webhook Relay is developer webhook infrastructure that receives webhooks and forwards them to public, localhost and private destinations, with transformations and cron, from $9.99/month.",[1662,1666,1670,1674,1678,1682,1686,1690,1694,1698,1702,1706,1710,1714,1718,1722,1726,1730,1734,1738,1742,1746,1750,1754,1758,1762,1766,1770,1774,1778,1782,1786,1790,1794,1798,1802,1806,1810,1814,1818,1822,1826,1830,1834,1838,1842,1846,1850,1854,1858,1862,1866,1870,1873,1877,1880,1884,1888,1892,1895,1899],{"_path":1663,"title":1664,"description":1665},"/docs/account/account-management","Account management","How to manage your account, change email address, password or delete your account",{"_path":1667,"title":1668,"description":1669},"/docs/account/team","Teams and sub-accounts","How to create teams and invite team members to your Webhook Relay account",{"_path":1671,"title":1672,"description":1673},"/docs/account/billing-and-subscriptions","Billing & subscriptions","How to manage your billing and subscriptions, updating payment methods and billing address, viewing invoices",{"_path":1675,"title":1676,"description":1677},"/docs","Getting Started","What is Webhook Relay and how you can use it.",{"_path":1679,"title":1680,"description":1681},"/docs/installation/cli","CLI","Learn how to install relay CLI on MacOS, Linux and Windows to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1683,"title":1684,"description":1685},"/docs/installation/docker","Docker container","How to use Webhook Relay client with Docker to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1687,"title":1688,"description":1689},"/docs/installation/docker-compose","Docker Compose","How to use Webhook Relay client with Docker Compose to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1691,"title":1692,"description":1693},"/docs/installation/kubernetes","Kubernetes","How to use Webhook Relay client with Kubernetes to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1695,"title":1696,"description":1697},"/docs/installation/autostart-windows","Autostart (Windows)","Learn how to configure background service so that Webhook Relay agent connects on Windows server startup",{"_path":1699,"title":1700,"description":1701},"/docs/installation/autostart-linux","Autostart (Linux)","Learn how to configure background service so that Webhook Relay agent connects on Linux server startup",{"_path":1703,"title":1704,"description":1705},"/docs/installation/autostart-macos","Autostart (MacOS)","Learn how to configure background service so that Webhook Relay agent connects on MacOS startup",{"_path":1707,"title":1708,"description":1709},"/docs/installation/behind-proxy","HTTP proxy configuration","How to configure relay or webhookrelayd agent to work behind a proxy",{"_path":1711,"title":1712,"description":1713},"/docs/mcp","MCP Server","Use the Webhook Relay MCP server to manage buckets, webhook logs, transform functions, and cloud service connections from AI agents.",{"_path":1715,"title":1716,"description":1717},"/docs/security","Security & Tech","We will address the most common questions about the system, protocols involved, and security policies.",{"_path":1719,"title":1720,"description":1721},"/docs/service-connections","Service Connections","Connect Webhook Relay to AWS and GCP cloud services. Receive events from S3, SQS, SNS, GCS, Pub/Sub and send webhooks to cloud providers.",{"_path":1723,"title":1724,"description":1725},"/docs/service-connections/aws_s3","AWS S3","Receive S3 object notifications as webhooks and upload webhook data to S3 buckets using Webhook Relay service connections.",{"_path":1727,"title":1728,"description":1729},"/docs/service-connections/aws_sns","AWS SNS","Subscribe to Amazon SNS topics and publish webhook data to SNS using Webhook Relay service connections.",{"_path":1731,"title":1732,"description":1733},"/docs/service-connections/aws_sqs","AWS SQS","Poll messages from Amazon SQS queues and send webhook data to SQS using Webhook Relay service connections.",{"_path":1735,"title":1736,"description":1737},"/docs/service-connections/gcp_gcs","GCP Cloud Storage","Receive GCS object notifications as webhooks and upload webhook data to Google Cloud Storage using Webhook Relay service connections.",{"_path":1739,"title":1740,"description":1741},"/docs/service-connections/gcp_pubsub","GCP Pub/Sub","Subscribe to Google Cloud Pub/Sub topics and publish webhook data to Pub/Sub using Webhook Relay service connections.",{"_path":1743,"title":1744,"description":1745},"/docs/tunnels/demoing-your-website","Demoing your website","How to expose your local web server to the internet without public IP or router changes",{"_path":1747,"title":1748,"description":1749},"/docs/tunnels/regions","Regions","Regional tunnel servers are available in a number of different locations to enable fast & low latency traffic to your applications.",{"_path":1751,"title":1752,"description":1753},"/docs/tutorials/cicd/jenkins-bitbucket","Jenkins and Bitbucket","A quick guide on Jenkins Bitbucket webhooks integration without public IP/NAT or behind a firewall",{"_path":1755,"title":1756,"description":1757},"/docs/tutorials/cicd/jenkins-github","Jenkins and GitHub","Configuring Jenkins CI to receive webhooks from Github without public IP/NAT or behind a firewall",{"_path":1759,"title":1760,"description":1761},"/docs/tutorials/cicd/kubernetes-operator","Kubernetes Operator","Trigger Jenkins builds on push to Github using Webhook Relay Operator",{"_path":1763,"title":1764,"description":1765},"/docs/tutorials/cicd/terraform-atlantis","Terraform Atlantis","Securely forward webhooks to Terraform Atlantis in Kubernetes cluster using Webhook Relay Operator",{"_path":1767,"title":1768,"description":1769},"/docs/tutorials/cicd/webhook-exec","Execute scripts on webhook","Execute commands such as bash, python or ruby when webhooks are received",{"_path":1771,"title":1772,"description":1773},"/docs/tutorials/edge/home-assistant","Home Assistant","Connecting to your Home Assistant remotely without domain/public IP or configuring NAT.",{"_path":1775,"title":1776,"description":1777},"/docs/tutorials/edge/javascript-app","JavaScript app","Receive webhooks directly inside your application without public IP",{"_path":1779,"title":1780,"description":1781},"/docs/tutorials/edge/node-red","Node-RED","Directly receiving and process webhooks in Node-RED instance without public IP or domain.",{"_path":1783,"title":1784,"description":1785},"/docs/tutorials","Tutorials","Tutorials for Webhook Relay.",{"_path":1787,"title":1788,"description":1789},"/docs/tutorials/transform/docker-to-slack","DockerHub webhook to Slack notification","Use Lua function to convert DockerHub webhook request to Slack channel notification",{"_path":1791,"title":1792,"description":1793},"/docs/tutorials/transform/enrich-webhooks","Enrich webhooks from APIs","Call 3rd party API and transform your webhook before sending it to the final destination",{"_path":1795,"title":1796,"description":1797},"/docs/tutorials/warehouse/bigquery","GCP BigQuery","Learn to insert and stream data into BigQuery from webhooks",{"_path":1799,"title":1800,"description":1801},"/docs/webhooks/auth/username-password","Username and password","How to set up authentication for webhooks. This guide shows you how to use basic username and password or token authentication.",{"_path":1803,"title":1804,"description":1805},"/docs/webhooks/auth/hmac","HMAC","HMAC is the most popular authentication and message security method used on webhook requests. Learn how to validate HMAC signatures",{"_path":1807,"title":1808,"description":1809},"/docs/webhooks/auth/jwt","JWT authentication","a helper JWT package is available to validate and authenticate webhooks",{"_path":1811,"title":1812,"description":1813},"/docs/webhooks/auth/http-method","Auth using request method","How do I allow only POST requests through the input or output?",{"_path":1815,"title":1816,"description":1817},"/docs/webhooks/cors","CORS for webhooks","Configure CORS for your webhooks to allow requests from other domains.",{"_path":1819,"title":1820,"description":1821},"/docs/webhooks/cron/using-cron-webhooks","Schedule recurring webhooks","Schedule recurring webhooks with Webhook Relay",{"_path":1823,"title":1824,"description":1825},"/docs/webhooks/custom-domains","Custom webhook domains","Receive, process and forward webhooks using your own domain name.",{"_path":1827,"title":1828,"description":1829},"/docs/webhooks/custom-subdomains","Custom webhook subdomains","Receive, process and forward webhooks using webhookrelay.com subdomain.",{"_path":1831,"title":1832,"description":1833},"/docs/webhooks/custom-webhook-response","Custom response to webhooks","Configure a custom response to your webhooks, some applications require it, for example Facebook webhooks.",{"_path":1835,"title":1836,"description":1837},"/docs/webhooks/functions/manipulating-json","JSON encoding","How to encode and decode JSON in Webhook Relay Functions",{"_path":1839,"title":1840,"description":1841},"/docs/webhooks/functions/make-http-request","Make HTTP request","Making HTTP requests from Webhook Relay Functions",{"_path":1843,"title":1844,"description":1845},"/docs/webhooks/functions/modify-request","Read, write request data","How to access and modify request data in Webhook Relay Functions",{"_path":1847,"title":1848,"description":1849},"/docs/webhooks/functions/multipart-form-data","Multipart form to JSON","Parsing multipart form data inside the Webhook Relay Function",{"_path":1851,"title":1852,"description":1853},"/docs/webhooks/functions/url-encoded-data","URL Encoded Form","Parse and convert URL encoded form data into JSON or any other format",{"_path":1855,"title":1856,"description":1857},"/docs/webhooks/functions/working-with-time","Working with time","Webhook Relay provides several helpers when working with time, this section shows how to get current time, how to parse and format time",{"_path":1859,"title":1860,"description":1861},"/docs/webhooks/functions/send-emails","Sending emails","Webhook Relay provides a Mailgun package to easily send emails on various events.",{"_path":1863,"title":1864,"description":1865},"/docs/webhooks/functions/crypto-functions","Base64, encryption","How to generate hmac, crc32, sha1, sha256, sha512 hashes and encrypt data in Webhook Relay functions",{"_path":1867,"title":1868,"description":1869},"/docs/webhooks/functions/integrate-into-cicd","Integrating into CI/CD","A guide on how to automatically deploy Functions in various source control management systems",{"_path":1871,"title":1796,"description":1872},"/docs/webhooks/functions/big-query","How to send data to BigQuery from Webhook Relay.",{"_path":1874,"title":1875,"description":1876},"/docs/webhooks/functions/accessing-metadata","Accessing metadata","Accessing metadata from Webhook Relay Functions",{"_path":1878,"title":231,"description":1879},"/docs/webhooks/functions","Use functions to transform webhooks, modify payloads, filter requests, integrate systems, and more.",{"_path":1881,"title":1882,"description":1883},"/docs/webhooks/internal/localhost","Receiving webhooks on localhost","Receive webhooks on localhost or private networks with Webhook Relay forward command",{"_path":1885,"title":1886,"description":1887},"/docs/webhooks/polling-webhooks","Polling webhooks with /v1/events","Learn how to poll webhook events with the Webhook Relay /v1/events API. Use cursor-based polling to consume webhook deliveries, webhook logs, and event data from your application.",{"_path":1889,"title":1890,"description":1891},"/docs/webhooks/public/public-destination","Forward to public URL","How to forward a webhook to a single public URL",{"_path":1893,"title":1894,"description":1891},"/docs/webhooks/public/multiple-destination-urls","Multiple destinations",{"_path":1896,"title":1897,"description":1898},"/docs/webhooks/static-ip-address","Static IP Address","Enable a static IP address for outgoing webhooks to allow IP whitelisting.",{"_path":1900,"title":1901,"description":1902},"/docs/webhooks/websocket-server","Connecting to websocket server","Webhook Relay websocket server allows your applications to directly process webhooks without having a public IP.",[1904,1907,1911,1915,1918,1922,1926,1930,1933,1936,1939,1943,1947,1950],{"_path":1905,"title":1906,"description":7},"/features/audit-logs","Audit Logs",{"_path":1908,"title":1909,"description":1910},"/features/custom-domains","Custom Domains","How to use custom domains for your webhook endpoints",{"_path":1912,"title":1913,"description":1914},"/features/custom-subdomains","Custom Subdomains","How to use custom subdomains for your webhook endpoints",{"_path":1120,"title":1916,"description":1917},"Forwarding Rules - Filter and Route Webhooks","Filter and route webhooks based on request body, JSON paths, URL query parameters, URL path, and IP address. Precisely control which webhooks reach each destination.",{"_path":1919,"title":1920,"description":1921},"/features/rewrite-host-header","Rewriting Host Header","How to rewrite the Host header to enable exposing local servers to the internet",{"_path":1923,"title":1924,"description":1925},"/features/sso","Single Sign-On (SSO)","How to enable single sign-on for your Webhook Relay account so it can be shared with your organization",{"_path":1927,"title":1928,"description":1929},"/features/static-outgoing-ip","Static Outgoing IP Address","How to use a static outgoing IP address for your webhooks to unlock integrations that require whitelisting your IP address",{"_path":1931,"title":1932,"description":7},"/features/team-member-roles","Team Member Roles",{"_path":1934,"title":1935,"description":1669},"/features/teams","Teams",{"_path":128,"title":1937,"description":1938},"Serverless Webhook Transformations","How to transform webhooks before forwarding them to your destination",{"_path":1940,"title":1941,"description":1942},"/features/transform-webhooks-with-ai","Transform Webhooks with AI","How to automatically transform webhook payloads using AI for seamless integrations",{"_path":1944,"title":1945,"description":1946},"/features/webhook-kubernetes-integration","Webhook Relay Kubernetes Integration","Seamlessly connect your Kubernetes services to external webhooks without exposing them directly to the internet using the Webhook Relay Operator.",{"_path":1209,"title":1948,"description":1949},"Forward Webhooks to Multiple Destinations","Webhook Relay allows you to forward webhooks to multiple destinations. Ideal for data replication and backup.",{"_path":1951,"title":1952,"description":1953},"/features/webhook-to-internal-server","Webhooks to Internal Servers","Webhook Relay allows you to forward webhooks to internal servers",1781126204789]