[{"data":1,"prerenderedAt":1333},["ShallowReactive",2],{"content-query-zTMyAxtCb4":3,"content-query-W4RtfFQaoh":1129,"content-query-yP1cWMns5L":1154,"content-query-M5aWdXgQKx":1158,"content-query-eJ9XWy0CGH":1165,"content-query-UP87PRcOMw":1178,"content-query-7VgBfxLOWV":1182,"content-query-Z6fTkbgt1D":1204,"content-query-9giMhwHrGj":1212,"content-query-G03kJtQzJS":1219,"content-query-1mvwAKmUBq":1238,"content-query-j8GGVgf9na":1261,"content-query-No6iPTj4EO":1274,"content-query-zRSmsuVl55":1284,"content-query-MsdmgXewTK":1288,"content-query-BMhIInEJl2":1295},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"intro":9,"type":10,"layout":11,"tags":12,"body":15,"_type":1122,"_id":1123,"_source":1124,"_file":1125,"_stem":1126,"_extension":1127,"sitemap":1128},"/docs/tutorials/email/database","email",false,"","Email to Database","Store every inbound email in your own database. Webhook Relay parses email to JSON and POSTs it to a tiny insert endpoint you run — even one behind a firewall.","tutorial","doc",[13,14],"Email","Webhook Forwarding",{"type":16,"children":17,"toc":1114},"root",[18,34,65,72,77,96,101,519,548,554,564,582,592,610,620,637,643,664,857,893,899,912,1038,1043,1049,1077,1083,1096,1108],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,26,32],{"type":24,"value":25},"text","You want every inbound email stored in ",{"type":19,"tag":27,"props":28,"children":29},"strong",{},[30],{"type":24,"value":31},"your own database",{"type":24,"value":33}," — an archive, an audit trail, or a queue your app reads from. Doing that the traditional way means running a mail server or polling an IMAP mailbox, parsing raw MIME, and writing a daemon to keep it alive.",{"type":19,"tag":20,"props":35,"children":36},{},[37,46,48,54,56,63],{"type":19,"tag":38,"props":39,"children":43},"a",{"href":40,"rel":41},"https://webhookrelay.com",[42],"nofollow",[44],{"type":24,"value":45},"Webhook Relay",{"type":24,"value":47}," removes all of that. It ",{"type":19,"tag":38,"props":49,"children":51},{"href":50},"/docs/email",[52],{"type":24,"value":53},"receives emails as webhooks",{"type":24,"value":55},": you get a unique address, every message sent to it is parsed into JSON, and that JSON is POSTed to a tiny HTTP endpoint you run — which does a single ",{"type":19,"tag":57,"props":58,"children":60},"code",{"className":59},[],[61],{"type":24,"value":62},"INSERT",{"type":24,"value":64},". No mail server, no IMAP loop.",{"type":19,"tag":66,"props":67,"children":69},"h2",{"id":68},"how-it-works",[70],{"type":24,"value":71},"How it works",{"type":19,"tag":20,"props":73,"children":74},{},[75],{"type":24,"value":76},"Webhook Relay doesn't connect to your database directly. It parses the email and POSTs it to an HTTP handler you control, and that handler owns the SQL:",{"type":19,"tag":78,"props":79,"children":82},"pre",{"className":80,"code":81,"language":24,"meta":7,"style":7},"language-text shiki shiki-themes github-dark","inbound email  ──▶  Webhook Relay (parse)  ──▶  POST  ──▶  your insert endpoint  ──▶  database\n",[83],{"type":19,"tag":57,"props":84,"children":85},{"__ignoreMap":7},[86],{"type":19,"tag":87,"props":88,"children":91},"span",{"class":89,"line":90},"line",1,[92],{"type":19,"tag":87,"props":93,"children":94},{},[95],{"type":24,"value":81},{"type":19,"tag":20,"props":97,"children":98},{},[99],{"type":24,"value":100},"The parsed email looks like this:",{"type":19,"tag":78,"props":102,"children":106},{"className":103,"code":104,"language":105,"meta":7,"style":7},"language-json shiki shiki-themes github-dark","{\n  \"from\": \"jon@example.com\",\n  \"from_name\": \"Jon Snow\",\n  \"recipient\": \"\u003Cuuid>@in.webhookrelay-mail.com\",\n  \"to\": [\"\u003Cuuid>@in.webhookrelay-mail.com\"],\n  \"subject\": \"Invoice #4821\",\n  \"date\": \"Sun, 28 Jun 2026 11:27:41 +0400\",\n  \"message_id\": \"\u003Cabc@mail.example.com>\",\n  \"text\": \"plain body\",\n  \"html\": \"\u003Cp>html body\u003C/p>\",\n  \"spf\": \"pass\",\n  \"dkim\": \"pass\",\n  \"dmarc\": \"pass\",\n  \"attachments\": [\n    { \"name\": \"invoice.pdf\", \"content_type\": \"application/pdf\", \"size\": 48213, \"content\": \"\u003Cbase64>\", \"truncated\": false }\n  ]\n}\n","json",[107],{"type":19,"tag":57,"props":108,"children":109},{"__ignoreMap":7},[110,119,145,167,189,212,234,256,278,300,322,344,365,386,400,501,510],{"type":19,"tag":87,"props":111,"children":112},{"class":89,"line":90},[113],{"type":19,"tag":87,"props":114,"children":116},{"style":115},"--shiki-default:#E1E4E8",[117],{"type":24,"value":118},"{\n",{"type":19,"tag":87,"props":120,"children":122},{"class":89,"line":121},2,[123,129,134,140],{"type":19,"tag":87,"props":124,"children":126},{"style":125},"--shiki-default:#79B8FF",[127],{"type":24,"value":128},"  \"from\"",{"type":19,"tag":87,"props":130,"children":131},{"style":115},[132],{"type":24,"value":133},": ",{"type":19,"tag":87,"props":135,"children":137},{"style":136},"--shiki-default:#9ECBFF",[138],{"type":24,"value":139},"\"jon@example.com\"",{"type":19,"tag":87,"props":141,"children":142},{"style":115},[143],{"type":24,"value":144},",\n",{"type":19,"tag":87,"props":146,"children":148},{"class":89,"line":147},3,[149,154,158,163],{"type":19,"tag":87,"props":150,"children":151},{"style":125},[152],{"type":24,"value":153},"  \"from_name\"",{"type":19,"tag":87,"props":155,"children":156},{"style":115},[157],{"type":24,"value":133},{"type":19,"tag":87,"props":159,"children":160},{"style":136},[161],{"type":24,"value":162},"\"Jon Snow\"",{"type":19,"tag":87,"props":164,"children":165},{"style":115},[166],{"type":24,"value":144},{"type":19,"tag":87,"props":168,"children":170},{"class":89,"line":169},4,[171,176,180,185],{"type":19,"tag":87,"props":172,"children":173},{"style":125},[174],{"type":24,"value":175},"  \"recipient\"",{"type":19,"tag":87,"props":177,"children":178},{"style":115},[179],{"type":24,"value":133},{"type":19,"tag":87,"props":181,"children":182},{"style":136},[183],{"type":24,"value":184},"\"\u003Cuuid>@in.webhookrelay-mail.com\"",{"type":19,"tag":87,"props":186,"children":187},{"style":115},[188],{"type":24,"value":144},{"type":19,"tag":87,"props":190,"children":192},{"class":89,"line":191},5,[193,198,203,207],{"type":19,"tag":87,"props":194,"children":195},{"style":125},[196],{"type":24,"value":197},"  \"to\"",{"type":19,"tag":87,"props":199,"children":200},{"style":115},[201],{"type":24,"value":202},": [",{"type":19,"tag":87,"props":204,"children":205},{"style":136},[206],{"type":24,"value":184},{"type":19,"tag":87,"props":208,"children":209},{"style":115},[210],{"type":24,"value":211},"],\n",{"type":19,"tag":87,"props":213,"children":215},{"class":89,"line":214},6,[216,221,225,230],{"type":19,"tag":87,"props":217,"children":218},{"style":125},[219],{"type":24,"value":220},"  \"subject\"",{"type":19,"tag":87,"props":222,"children":223},{"style":115},[224],{"type":24,"value":133},{"type":19,"tag":87,"props":226,"children":227},{"style":136},[228],{"type":24,"value":229},"\"Invoice #4821\"",{"type":19,"tag":87,"props":231,"children":232},{"style":115},[233],{"type":24,"value":144},{"type":19,"tag":87,"props":235,"children":237},{"class":89,"line":236},7,[238,243,247,252],{"type":19,"tag":87,"props":239,"children":240},{"style":125},[241],{"type":24,"value":242},"  \"date\"",{"type":19,"tag":87,"props":244,"children":245},{"style":115},[246],{"type":24,"value":133},{"type":19,"tag":87,"props":248,"children":249},{"style":136},[250],{"type":24,"value":251},"\"Sun, 28 Jun 2026 11:27:41 +0400\"",{"type":19,"tag":87,"props":253,"children":254},{"style":115},[255],{"type":24,"value":144},{"type":19,"tag":87,"props":257,"children":259},{"class":89,"line":258},8,[260,265,269,274],{"type":19,"tag":87,"props":261,"children":262},{"style":125},[263],{"type":24,"value":264},"  \"message_id\"",{"type":19,"tag":87,"props":266,"children":267},{"style":115},[268],{"type":24,"value":133},{"type":19,"tag":87,"props":270,"children":271},{"style":136},[272],{"type":24,"value":273},"\"\u003Cabc@mail.example.com>\"",{"type":19,"tag":87,"props":275,"children":276},{"style":115},[277],{"type":24,"value":144},{"type":19,"tag":87,"props":279,"children":281},{"class":89,"line":280},9,[282,287,291,296],{"type":19,"tag":87,"props":283,"children":284},{"style":125},[285],{"type":24,"value":286},"  \"text\"",{"type":19,"tag":87,"props":288,"children":289},{"style":115},[290],{"type":24,"value":133},{"type":19,"tag":87,"props":292,"children":293},{"style":136},[294],{"type":24,"value":295},"\"plain body\"",{"type":19,"tag":87,"props":297,"children":298},{"style":115},[299],{"type":24,"value":144},{"type":19,"tag":87,"props":301,"children":303},{"class":89,"line":302},10,[304,309,313,318],{"type":19,"tag":87,"props":305,"children":306},{"style":125},[307],{"type":24,"value":308},"  \"html\"",{"type":19,"tag":87,"props":310,"children":311},{"style":115},[312],{"type":24,"value":133},{"type":19,"tag":87,"props":314,"children":315},{"style":136},[316],{"type":24,"value":317},"\"\u003Cp>html body\u003C/p>\"",{"type":19,"tag":87,"props":319,"children":320},{"style":115},[321],{"type":24,"value":144},{"type":19,"tag":87,"props":323,"children":325},{"class":89,"line":324},11,[326,331,335,340],{"type":19,"tag":87,"props":327,"children":328},{"style":125},[329],{"type":24,"value":330},"  \"spf\"",{"type":19,"tag":87,"props":332,"children":333},{"style":115},[334],{"type":24,"value":133},{"type":19,"tag":87,"props":336,"children":337},{"style":136},[338],{"type":24,"value":339},"\"pass\"",{"type":19,"tag":87,"props":341,"children":342},{"style":115},[343],{"type":24,"value":144},{"type":19,"tag":87,"props":345,"children":347},{"class":89,"line":346},12,[348,353,357,361],{"type":19,"tag":87,"props":349,"children":350},{"style":125},[351],{"type":24,"value":352},"  \"dkim\"",{"type":19,"tag":87,"props":354,"children":355},{"style":115},[356],{"type":24,"value":133},{"type":19,"tag":87,"props":358,"children":359},{"style":136},[360],{"type":24,"value":339},{"type":19,"tag":87,"props":362,"children":363},{"style":115},[364],{"type":24,"value":144},{"type":19,"tag":87,"props":366,"children":368},{"class":89,"line":367},13,[369,374,378,382],{"type":19,"tag":87,"props":370,"children":371},{"style":125},[372],{"type":24,"value":373},"  \"dmarc\"",{"type":19,"tag":87,"props":375,"children":376},{"style":115},[377],{"type":24,"value":133},{"type":19,"tag":87,"props":379,"children":380},{"style":136},[381],{"type":24,"value":339},{"type":19,"tag":87,"props":383,"children":384},{"style":115},[385],{"type":24,"value":144},{"type":19,"tag":87,"props":387,"children":389},{"class":89,"line":388},14,[390,395],{"type":19,"tag":87,"props":391,"children":392},{"style":125},[393],{"type":24,"value":394},"  \"attachments\"",{"type":19,"tag":87,"props":396,"children":397},{"style":115},[398],{"type":24,"value":399},": [\n",{"type":19,"tag":87,"props":401,"children":403},{"class":89,"line":402},15,[404,409,414,418,423,428,433,437,442,446,451,455,460,464,469,473,478,482,487,491,496],{"type":19,"tag":87,"props":405,"children":406},{"style":115},[407],{"type":24,"value":408},"    { ",{"type":19,"tag":87,"props":410,"children":411},{"style":125},[412],{"type":24,"value":413},"\"name\"",{"type":19,"tag":87,"props":415,"children":416},{"style":115},[417],{"type":24,"value":133},{"type":19,"tag":87,"props":419,"children":420},{"style":136},[421],{"type":24,"value":422},"\"invoice.pdf\"",{"type":19,"tag":87,"props":424,"children":425},{"style":115},[426],{"type":24,"value":427},", ",{"type":19,"tag":87,"props":429,"children":430},{"style":125},[431],{"type":24,"value":432},"\"content_type\"",{"type":19,"tag":87,"props":434,"children":435},{"style":115},[436],{"type":24,"value":133},{"type":19,"tag":87,"props":438,"children":439},{"style":136},[440],{"type":24,"value":441},"\"application/pdf\"",{"type":19,"tag":87,"props":443,"children":444},{"style":115},[445],{"type":24,"value":427},{"type":19,"tag":87,"props":447,"children":448},{"style":125},[449],{"type":24,"value":450},"\"size\"",{"type":19,"tag":87,"props":452,"children":453},{"style":115},[454],{"type":24,"value":133},{"type":19,"tag":87,"props":456,"children":457},{"style":125},[458],{"type":24,"value":459},"48213",{"type":19,"tag":87,"props":461,"children":462},{"style":115},[463],{"type":24,"value":427},{"type":19,"tag":87,"props":465,"children":466},{"style":125},[467],{"type":24,"value":468},"\"content\"",{"type":19,"tag":87,"props":470,"children":471},{"style":115},[472],{"type":24,"value":133},{"type":19,"tag":87,"props":474,"children":475},{"style":136},[476],{"type":24,"value":477},"\"\u003Cbase64>\"",{"type":19,"tag":87,"props":479,"children":480},{"style":115},[481],{"type":24,"value":427},{"type":19,"tag":87,"props":483,"children":484},{"style":125},[485],{"type":24,"value":486},"\"truncated\"",{"type":19,"tag":87,"props":488,"children":489},{"style":115},[490],{"type":24,"value":133},{"type":19,"tag":87,"props":492,"children":493},{"style":125},[494],{"type":24,"value":495},"false",{"type":19,"tag":87,"props":497,"children":498},{"style":115},[499],{"type":24,"value":500}," }\n",{"type":19,"tag":87,"props":502,"children":504},{"class":89,"line":503},16,[505],{"type":19,"tag":87,"props":506,"children":507},{"style":115},[508],{"type":24,"value":509},"  ]\n",{"type":19,"tag":87,"props":511,"children":513},{"class":89,"line":512},17,[514],{"type":19,"tag":87,"props":515,"children":516},{"style":115},[517],{"type":24,"value":518},"}\n",{"type":19,"tag":20,"props":520,"children":521},{},[522,524,530,532,538,540,546],{"type":24,"value":523},"See the full ",{"type":19,"tag":38,"props":525,"children":527},{"href":526},"/docs/email/payload",[528],{"type":24,"value":529},"payload reference",{"type":24,"value":531}," for every field, including ",{"type":19,"tag":57,"props":533,"children":535},{"className":534},[],[536],{"type":24,"value":537},"cc",{"type":24,"value":539}," and the raw ",{"type":19,"tag":57,"props":541,"children":543},{"className":542},[],[544],{"type":24,"value":545},"headers",{"type":24,"value":547}," map.",{"type":19,"tag":66,"props":549,"children":551},{"id":550},"setup",[552],{"type":24,"value":553},"Setup",{"type":19,"tag":20,"props":555,"children":556},{},[557,562],{"type":19,"tag":27,"props":558,"children":559},{},[560],{"type":24,"value":561},"1. Create a bucket.",{"type":24,"value":563}," This ties an input to its outputs.",{"type":19,"tag":20,"props":565,"children":566},{},[567,572,574,580],{"type":19,"tag":27,"props":568,"children":569},{},[570],{"type":24,"value":571},"2. Add an email input.",{"type":24,"value":573}," Webhook Relay returns a unique address of the form ",{"type":19,"tag":57,"props":575,"children":577},{"className":576},[],[578],{"type":24,"value":579},"\u003Cuuid>@in.webhookrelay-mail.com",{"type":24,"value":581},". Anything sent there is parsed and forwarded to the bucket's outputs.",{"type":19,"tag":20,"props":583,"children":584},{},[585,590],{"type":19,"tag":27,"props":586,"children":587},{},[588],{"type":24,"value":589},"3. Run your insert endpoint.",{"type":24,"value":591}," A small HTTP service that accepts a POST and writes one row (see below).",{"type":19,"tag":20,"props":593,"children":594},{},[595,600,602,608],{"type":19,"tag":27,"props":596,"children":597},{},[598],{"type":24,"value":599},"4. Add its URL as the output.",{"type":24,"value":601}," Point the bucket's output at your endpoint, e.g. ",{"type":19,"tag":57,"props":603,"children":605},{"className":604},[],[606],{"type":24,"value":607},"https://api.example.com/inbound",{"type":24,"value":609},".",{"type":19,"tag":20,"props":611,"children":612},{},[613,618],{"type":19,"tag":27,"props":614,"children":615},{},[616],{"type":24,"value":617},"5. (Optional) attach a transform",{"type":24,"value":619}," to trim the payload to just the columns you store.",{"type":19,"tag":20,"props":621,"children":622},{},[623,628,630,635],{"type":19,"tag":27,"props":624,"children":625},{},[626],{"type":24,"value":627},"6. Send a test email.",{"type":24,"value":629}," Email your ",{"type":19,"tag":57,"props":631,"children":633},{"className":632},[],[634],{"type":24,"value":579},{"type":24,"value":636}," address. Within a second or two a row appears. If it doesn't, open the request log in your dashboard to see exactly what was received and delivered.",{"type":19,"tag":66,"props":638,"children":640},{"id":639},"the-handler",[641],{"type":24,"value":642},"The handler",{"type":19,"tag":20,"props":644,"children":645},{},[646,648,654,656,662],{"type":24,"value":647},"The endpoint receives the email JSON and inserts it. Use ",{"type":19,"tag":57,"props":649,"children":651},{"className":650},[],[652],{"type":24,"value":653},"message_id",{"type":24,"value":655}," with a ",{"type":19,"tag":57,"props":657,"children":659},{"className":658},[],[660],{"type":24,"value":661},"UNIQUE",{"type":24,"value":663}," constraint so the write is idempotent:",{"type":19,"tag":78,"props":665,"children":669},{"className":666,"code":667,"language":668,"meta":7,"style":7},"language-js shiki shiki-themes github-dark","app.post('/inbound', async (req, res) => {\n  const e = req.body; // the parsed email JSON\n  await db.query(\n    'INSERT INTO emails(message_id, sender, subject, body, received_at) VALUES($1,$2,$3,$4,$5) ON CONFLICT (message_id) DO NOTHING',\n    [e.message_id, e.from, e.subject, e.text, e.date]\n  );\n  res.sendStatus(200);\n});\n","js",[670],{"type":19,"tag":57,"props":671,"children":672},{"__ignoreMap":7},[673,742,771,794,806,814,822,849],{"type":19,"tag":87,"props":674,"children":675},{"class":89,"line":90},[676,681,687,692,697,701,707,712,718,722,727,732,737],{"type":19,"tag":87,"props":677,"children":678},{"style":115},[679],{"type":24,"value":680},"app.",{"type":19,"tag":87,"props":682,"children":684},{"style":683},"--shiki-default:#B392F0",[685],{"type":24,"value":686},"post",{"type":19,"tag":87,"props":688,"children":689},{"style":115},[690],{"type":24,"value":691},"(",{"type":19,"tag":87,"props":693,"children":694},{"style":136},[695],{"type":24,"value":696},"'/inbound'",{"type":19,"tag":87,"props":698,"children":699},{"style":115},[700],{"type":24,"value":427},{"type":19,"tag":87,"props":702,"children":704},{"style":703},"--shiki-default:#F97583",[705],{"type":24,"value":706},"async",{"type":19,"tag":87,"props":708,"children":709},{"style":115},[710],{"type":24,"value":711}," (",{"type":19,"tag":87,"props":713,"children":715},{"style":714},"--shiki-default:#FFAB70",[716],{"type":24,"value":717},"req",{"type":19,"tag":87,"props":719,"children":720},{"style":115},[721],{"type":24,"value":427},{"type":19,"tag":87,"props":723,"children":724},{"style":714},[725],{"type":24,"value":726},"res",{"type":19,"tag":87,"props":728,"children":729},{"style":115},[730],{"type":24,"value":731},") ",{"type":19,"tag":87,"props":733,"children":734},{"style":703},[735],{"type":24,"value":736},"=>",{"type":19,"tag":87,"props":738,"children":739},{"style":115},[740],{"type":24,"value":741}," {\n",{"type":19,"tag":87,"props":743,"children":744},{"class":89,"line":121},[745,750,755,760,765],{"type":19,"tag":87,"props":746,"children":747},{"style":703},[748],{"type":24,"value":749},"  const",{"type":19,"tag":87,"props":751,"children":752},{"style":125},[753],{"type":24,"value":754}," e",{"type":19,"tag":87,"props":756,"children":757},{"style":703},[758],{"type":24,"value":759}," =",{"type":19,"tag":87,"props":761,"children":762},{"style":115},[763],{"type":24,"value":764}," req.body; ",{"type":19,"tag":87,"props":766,"children":768},{"style":767},"--shiki-default:#6A737D",[769],{"type":24,"value":770},"// the parsed email JSON\n",{"type":19,"tag":87,"props":772,"children":773},{"class":89,"line":147},[774,779,784,789],{"type":19,"tag":87,"props":775,"children":776},{"style":703},[777],{"type":24,"value":778},"  await",{"type":19,"tag":87,"props":780,"children":781},{"style":115},[782],{"type":24,"value":783}," db.",{"type":19,"tag":87,"props":785,"children":786},{"style":683},[787],{"type":24,"value":788},"query",{"type":19,"tag":87,"props":790,"children":791},{"style":115},[792],{"type":24,"value":793},"(\n",{"type":19,"tag":87,"props":795,"children":796},{"class":89,"line":169},[797,802],{"type":19,"tag":87,"props":798,"children":799},{"style":136},[800],{"type":24,"value":801},"    'INSERT INTO emails(message_id, sender, subject, body, received_at) VALUES($1,$2,$3,$4,$5) ON CONFLICT (message_id) DO NOTHING'",{"type":19,"tag":87,"props":803,"children":804},{"style":115},[805],{"type":24,"value":144},{"type":19,"tag":87,"props":807,"children":808},{"class":89,"line":191},[809],{"type":19,"tag":87,"props":810,"children":811},{"style":115},[812],{"type":24,"value":813},"    [e.message_id, e.from, e.subject, e.text, e.date]\n",{"type":19,"tag":87,"props":815,"children":816},{"class":89,"line":214},[817],{"type":19,"tag":87,"props":818,"children":819},{"style":115},[820],{"type":24,"value":821},"  );\n",{"type":19,"tag":87,"props":823,"children":824},{"class":89,"line":236},[825,830,835,839,844],{"type":19,"tag":87,"props":826,"children":827},{"style":115},[828],{"type":24,"value":829},"  res.",{"type":19,"tag":87,"props":831,"children":832},{"style":683},[833],{"type":24,"value":834},"sendStatus",{"type":19,"tag":87,"props":836,"children":837},{"style":115},[838],{"type":24,"value":691},{"type":19,"tag":87,"props":840,"children":841},{"style":125},[842],{"type":24,"value":843},"200",{"type":19,"tag":87,"props":845,"children":846},{"style":115},[847],{"type":24,"value":848},");\n",{"type":19,"tag":87,"props":850,"children":851},{"class":89,"line":258},[852],{"type":19,"tag":87,"props":853,"children":854},{"style":115},[855],{"type":24,"value":856},"});\n",{"type":19,"tag":20,"props":858,"children":859},{},[860,862,868,870,876,878,884,886,891],{"type":24,"value":861},"That ",{"type":19,"tag":57,"props":863,"children":865},{"className":864},[],[866],{"type":24,"value":867},"ON CONFLICT (message_id) DO NOTHING",{"type":24,"value":869}," is what makes retries safe. Webhook Relay ",{"type":19,"tag":38,"props":871,"children":873},{"href":872},"/docs/webhooks/durable-webhooks",[874],{"type":24,"value":875},"durable retries",{"type":24,"value":877}," re-attempt any delivery your endpoint didn't acknowledge with a ",{"type":19,"tag":57,"props":879,"children":881},{"className":880},[],[882],{"type":24,"value":883},"2xx",{"type":24,"value":885},", so an email is never lost if your service is briefly down or slow. Because each email carries a stable ",{"type":19,"tag":57,"props":887,"children":889},{"className":888},[],[890],{"type":24,"value":653},{"type":24,"value":892},", a retried delivery hits the unique constraint and becomes a no-op instead of a duplicate row.",{"type":19,"tag":66,"props":894,"children":896},{"id":895},"trim-the-payload-optional",[897],{"type":24,"value":898},"Trim the payload (optional)",{"type":19,"tag":20,"props":900,"children":901},{},[902,904,910],{"type":24,"value":903},"If you only store a handful of columns, a ",{"type":19,"tag":38,"props":905,"children":907},{"href":906},"/docs/webhooks/functions",[908],{"type":24,"value":909},"transform function",{"type":24,"value":911}," can shrink the body before it ever reaches your endpoint — your handler then deals with a small, predictable shape:",{"type":19,"tag":78,"props":913,"children":915},{"className":666,"code":914,"language":668,"meta":7,"style":7},"const e = JSON.parse(r.body);\nr.setBody(JSON.stringify({\n  message_id: e.message_id,\n  from: e.from,\n  subject: e.subject,\n  body: e.text,\n  received_at: e.date\n}));\n",[916],{"type":19,"tag":57,"props":917,"children":918},{"__ignoreMap":7},[919,954,990,998,1006,1014,1022,1030],{"type":19,"tag":87,"props":920,"children":921},{"class":89,"line":90},[922,927,931,935,940,944,949],{"type":19,"tag":87,"props":923,"children":924},{"style":703},[925],{"type":24,"value":926},"const",{"type":19,"tag":87,"props":928,"children":929},{"style":125},[930],{"type":24,"value":754},{"type":19,"tag":87,"props":932,"children":933},{"style":703},[934],{"type":24,"value":759},{"type":19,"tag":87,"props":936,"children":937},{"style":125},[938],{"type":24,"value":939}," JSON",{"type":19,"tag":87,"props":941,"children":942},{"style":115},[943],{"type":24,"value":609},{"type":19,"tag":87,"props":945,"children":946},{"style":683},[947],{"type":24,"value":948},"parse",{"type":19,"tag":87,"props":950,"children":951},{"style":115},[952],{"type":24,"value":953},"(r.body);\n",{"type":19,"tag":87,"props":955,"children":956},{"class":89,"line":121},[957,962,967,971,976,980,985],{"type":19,"tag":87,"props":958,"children":959},{"style":115},[960],{"type":24,"value":961},"r.",{"type":19,"tag":87,"props":963,"children":964},{"style":683},[965],{"type":24,"value":966},"setBody",{"type":19,"tag":87,"props":968,"children":969},{"style":115},[970],{"type":24,"value":691},{"type":19,"tag":87,"props":972,"children":973},{"style":125},[974],{"type":24,"value":975},"JSON",{"type":19,"tag":87,"props":977,"children":978},{"style":115},[979],{"type":24,"value":609},{"type":19,"tag":87,"props":981,"children":982},{"style":683},[983],{"type":24,"value":984},"stringify",{"type":19,"tag":87,"props":986,"children":987},{"style":115},[988],{"type":24,"value":989},"({\n",{"type":19,"tag":87,"props":991,"children":992},{"class":89,"line":147},[993],{"type":19,"tag":87,"props":994,"children":995},{"style":115},[996],{"type":24,"value":997},"  message_id: e.message_id,\n",{"type":19,"tag":87,"props":999,"children":1000},{"class":89,"line":169},[1001],{"type":19,"tag":87,"props":1002,"children":1003},{"style":115},[1004],{"type":24,"value":1005},"  from: e.from,\n",{"type":19,"tag":87,"props":1007,"children":1008},{"class":89,"line":191},[1009],{"type":19,"tag":87,"props":1010,"children":1011},{"style":115},[1012],{"type":24,"value":1013},"  subject: e.subject,\n",{"type":19,"tag":87,"props":1015,"children":1016},{"class":89,"line":214},[1017],{"type":19,"tag":87,"props":1018,"children":1019},{"style":115},[1020],{"type":24,"value":1021},"  body: e.text,\n",{"type":19,"tag":87,"props":1023,"children":1024},{"class":89,"line":236},[1025],{"type":19,"tag":87,"props":1026,"children":1027},{"style":115},[1028],{"type":24,"value":1029},"  received_at: e.date\n",{"type":19,"tag":87,"props":1031,"children":1032},{"class":89,"line":258},[1033],{"type":19,"tag":87,"props":1034,"children":1035},{"style":115},[1036],{"type":24,"value":1037},"}));\n",{"type":19,"tag":20,"props":1039,"children":1040},{},[1041],{"type":24,"value":1042},"This keeps base64 attachment blobs and HTML bodies out of the request when you don't need them.",{"type":19,"tag":66,"props":1044,"children":1046},{"id":1045},"delivering-to-a-private-database",[1047],{"type":24,"value":1048},"Delivering to a private database",{"type":19,"tag":20,"props":1050,"children":1051},{},[1052,1054,1060,1062,1067,1069,1075],{"type":24,"value":1053},"Your endpoint usually sits next to the database, on a private network. You don't have to expose it. Run the ",{"type":19,"tag":38,"props":1055,"children":1057},{"href":1056},"/webhooks",[1058],{"type":24,"value":1059},"relay agent",{"type":24,"value":1061}," alongside the service and Webhook Relay forwards each email to it over an outbound connection — so you can ",{"type":19,"tag":38,"props":1063,"children":1064},{"href":1056},[1065],{"type":24,"value":1066},"deliver behind a firewall",{"type":24,"value":1068}," or to ",{"type":19,"tag":57,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":24,"value":1074},"localhost",{"type":24,"value":1076}," with no public IP and no inbound ports open. Durable retries still apply, so a host that's briefly unreachable catches up automatically.",{"type":19,"tag":66,"props":1078,"children":1080},{"id":1079},"get-started",[1081],{"type":24,"value":1082},"Get started",{"type":19,"tag":20,"props":1084,"children":1085},{},[1086,1088,1094],{"type":24,"value":1087},"Storing inbound mail in a database is one case of a broader pattern: ",{"type":19,"tag":38,"props":1089,"children":1091},{"href":1090},"/email-to-webhook",[1092],{"type":24,"value":1093},"Email to Webhook",{"type":24,"value":1095},". Once an email is JSON, you can route it to any endpoint a webhook can reach — including a one-line insert handler.",{"type":19,"tag":20,"props":1097,"children":1098},{},[1099,1106],{"type":19,"tag":38,"props":1100,"children":1103},{"href":1101,"rel":1102},"https://my.webhookrelay.com/register",[42],[1104],{"type":24,"value":1105},"Create a free Webhook Relay account",{"type":24,"value":1107},", add an email input, point it at your endpoint, and start archiving every inbound message in minutes.",{"type":19,"tag":1109,"props":1110,"children":1111},"style",{},[1112],{"type":24,"value":1113},"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":147,"depth":147,"links":1115},[1116,1117,1118,1119,1120,1121],{"id":68,"depth":121,"text":71},{"id":550,"depth":121,"text":553},{"id":639,"depth":121,"text":642},{"id":895,"depth":121,"text":898},{"id":1045,"depth":121,"text":1048},{"id":1079,"depth":121,"text":1082},"markdown","content:docs:tutorials:email:database.md","content","docs/tutorials/email/database.md","docs/tutorials/email/database","md",{"loc":4},[1130,1133,1136,1139,1142,1145,1148,1151],{"_path":1131,"title":1132},"/docs/installation/cli","CLI",{"_path":1134,"title":1135},"/docs/installation/docker","Docker container",{"_path":1137,"title":1138},"/docs/installation/docker-compose","Docker Compose",{"_path":1140,"title":1141},"/docs/installation/kubernetes","Kubernetes",{"_path":1143,"title":1144},"/docs/installation/autostart-windows","Autostart (Windows)",{"_path":1146,"title":1147},"/docs/installation/autostart-linux","Autostart (Linux)",{"_path":1149,"title":1150},"/docs/installation/autostart-macos","Autostart (MacOS)",{"_path":1152,"title":1153},"/docs/installation/behind-proxy","HTTP proxy configuration",[1155],{"_path":1156,"title":1157},"/docs/webhooks/internal/localhost","Receiving webhooks on localhost",[1159,1162],{"_path":1160,"title":1161},"/docs/webhooks/public/public-destination","Forward to public URL",{"_path":1163,"title":1164},"/docs/webhooks/public/multiple-destination-urls","Multiple destinations",[1166,1169,1172,1175],{"_path":1167,"title":1168},"/docs/webhooks/auth/username-password","Username and password",{"_path":1170,"title":1171},"/docs/webhooks/auth/hmac","HMAC",{"_path":1173,"title":1174},"/docs/webhooks/auth/jwt","JWT authentication",{"_path":1176,"title":1177},"/docs/webhooks/auth/http-method","Auth using request method",[1179],{"_path":1180,"title":1181},"/docs/webhooks/cron/using-cron-webhooks","Schedule recurring webhooks",[1183,1186,1189,1192,1195,1198,1201],{"_path":1184,"title":1185},"/docs/service-connections","Service Connections",{"_path":1187,"title":1188},"/docs/service-connections/aws_s3","AWS S3",{"_path":1190,"title":1191},"/docs/service-connections/aws_sns","AWS SNS",{"_path":1193,"title":1194},"/docs/service-connections/aws_sqs","AWS SQS",{"_path":1196,"title":1197},"/docs/service-connections/azure","Azure",{"_path":1199,"title":1200},"/docs/service-connections/gcp_gcs","GCP Cloud Storage",{"_path":1202,"title":1203},"/docs/service-connections/gcp_pubsub","GCP Pub/Sub",[1205,1207,1209],{"_path":50,"title":1206},"Receive emails as webhooks",{"_path":526,"title":1208},"Email webhook payload",{"_path":1210,"title":1211},"/docs/email/filtering-and-policy","Sender filtering & policy",[1213,1216],{"_path":1214,"title":1215},"/docs/tunnels/demoing-your-website","Demoing your website",{"_path":1217,"title":1218},"/docs/tunnels/regions","Regions",[1220,1223,1226,1229,1232,1235],{"_path":1221,"title":1222},"/docs/tutorials/cicd/jenkins-bitbucket","Jenkins and Bitbucket",{"_path":1224,"title":1225},"/docs/tutorials/cicd/jenkins-github","Jenkins and GitHub",{"_path":1227,"title":1228},"/docs/tutorials/cicd/jenkins-plugin","Jenkins Plugin",{"_path":1230,"title":1231},"/docs/tutorials/cicd/kubernetes-operator","Kubernetes Operator",{"_path":1233,"title":1234},"/docs/tutorials/cicd/terraform-atlantis","Terraform Atlantis",{"_path":1236,"title":1237},"/docs/tutorials/cicd/webhook-exec","Execute scripts on webhook",[1239,1242,1245,1246,1249,1252,1255,1258],{"_path":1240,"title":1241},"/docs/tutorials/email/airtable","Email to Airtable",{"_path":1243,"title":1244},"/docs/tutorials/email/api","Email to API",{"_path":4,"title":8},{"_path":1247,"title":1248},"/docs/tutorials/email/discord","Email to Discord",{"_path":1250,"title":1251},"/docs/tutorials/email/google-sheets","Email to Google Sheets",{"_path":1253,"title":1254},"/docs/tutorials/email/microsoft-teams","Email to Microsoft Teams",{"_path":1256,"title":1257},"/docs/tutorials/email/notion","Email to Notion",{"_path":1259,"title":1260},"/docs/tutorials/email/slack","Email to Slack",[1262,1265,1268,1271],{"_path":1263,"title":1264},"/docs/account/account-management","Account management",{"_path":1266,"title":1267},"/docs/account/mfa","Multi-factor authentication (MFA)",{"_path":1269,"title":1270},"/docs/account/team","Teams and sub-accounts",{"_path":1272,"title":1273},"/docs/account/billing-and-subscriptions","Billing & subscriptions",[1275,1278,1281],{"_path":1276,"title":1277},"/docs/tutorials/edge/home-assistant","Home Assistant",{"_path":1279,"title":1280},"/docs/tutorials/edge/javascript-app","JavaScript app",{"_path":1282,"title":1283},"/docs/tutorials/edge/node-red","Node-RED",[1285],{"_path":1286,"title":1287},"/docs/tutorials/warehouse/bigquery","GCP BigQuery",[1289,1292],{"_path":1290,"title":1291},"/docs/tutorials/transform/docker-to-slack","DockerHub webhook to Slack notification",{"_path":1293,"title":1294},"/docs/tutorials/transform/enrich-webhooks","Enrich webhooks from APIs",[1296,1299,1302,1305,1308,1311,1314,1317,1320,1323,1325,1328,1331],{"_path":1297,"title":1298},"/docs/webhooks/functions/manipulating-json","JSON encoding",{"_path":1300,"title":1301},"/docs/webhooks/functions/make-http-request","Make HTTP request",{"_path":1303,"title":1304},"/docs/webhooks/functions/modify-request","Read, write request data",{"_path":1306,"title":1307},"/docs/webhooks/functions/multipart-form-data","Multipart form to JSON",{"_path":1309,"title":1310},"/docs/webhooks/functions/url-encoded-data","URL Encoded Form",{"_path":1312,"title":1313},"/docs/webhooks/functions/working-with-time","Working with time",{"_path":1315,"title":1316},"/docs/webhooks/functions/send-emails","Sending emails",{"_path":1318,"title":1319},"/docs/webhooks/functions/crypto-functions","Base64, encryption",{"_path":1321,"title":1322},"/docs/webhooks/functions/integrate-into-cicd","Integrating into CI/CD",{"_path":1324,"title":1287},"/docs/webhooks/functions/big-query",{"_path":1326,"title":1327},"/docs/webhooks/functions/accessing-metadata","Accessing metadata",{"_path":1329,"title":1330},"/docs/webhooks/functions/response-functions","Response (post-delivery) functions",{"_path":906,"title":1332},"Functions",1782815890280]