[{"data":1,"prerenderedAt":889},["ShallowReactive",2],{"navigation":3,"\u002Ftransactional\u002Fwebhooks":216,"\u002Ftransactional\u002Fwebhooks-surround":884},[4,9,14,40,57,74,95,112,133,150,199,208],{"title":5,"path":6,"stem":7,"icon":8},"Quick start","\u002Fgetting-started","01.getting-started","i-lucide-rocket",{"title":10,"path":11,"stem":12,"icon":13},"Set up from the terminal","\u002Fcli","02.cli","i-lucide-terminal",{"title":15,"path":16,"stem":17,"children":18,"page":39},"Domains & DNS","\u002Fdomains","03.domains",[19,23,27,31,35],{"title":20,"path":21,"stem":22},"Adding a domain","\u002Fdomains\u002Fadding-a-domain","03.domains\u002F01.adding-a-domain",{"title":24,"path":25,"stem":26},"Automatic DNS setup","\u002Fdomains\u002Fautomatic-dns-setup","03.domains\u002F02.automatic-dns-setup",{"title":28,"path":29,"stem":30},"Manual DNS records","\u002Fdomains\u002Fmanual-dns-records","03.domains\u002F03.manual-dns-records",{"title":32,"path":33,"stem":34},"Domain verification","\u002Fdomains\u002Fverification","03.domains\u002F04.verification",{"title":36,"path":37,"stem":38},"Troubleshooting DNS","\u002Fdomains\u002Ftroubleshooting","03.domains\u002F05.troubleshooting",false,{"title":41,"path":42,"stem":43,"children":44,"page":39},"Mailboxes & Aliases","\u002Fmailboxes","04.mailboxes",[45,49,53],{"title":46,"path":47,"stem":48},"Creating mailboxes","\u002Fmailboxes\u002Fcreating-mailboxes","04.mailboxes\u002F01.creating-mailboxes",{"title":50,"path":51,"stem":52},"Aliases","\u002Fmailboxes\u002Faliases","04.mailboxes\u002F02.aliases",{"title":54,"path":55,"stem":56},"Passwords, passkeys & access","\u002Fmailboxes\u002Fpasswords-and-access","04.mailboxes\u002F03.passwords-and-access",{"title":58,"path":59,"stem":60,"children":61,"page":39},"Using Your Mail","\u002Fmail","05.mail",[62,66,70],{"title":63,"path":64,"stem":65},"Webmail","\u002Fmail\u002Fwebmail","05.mail\u002F01.webmail",{"title":67,"path":68,"stem":69},"IMAP & SMTP settings","\u002Fmail\u002Fimap-smtp-settings","05.mail\u002F02.imap-smtp-settings",{"title":71,"path":72,"stem":73},"iPhone setup","\u002Fmail\u002Fios-profile","05.mail\u002F03.ios-profile",{"title":75,"path":76,"stem":77,"children":78,"page":39},"Drive","\u002Fdrive","06.drive",[79,83,87,91],{"title":80,"path":81,"stem":82},"Drive overview","\u002Fdrive\u002Foverview","06.drive\u002F01.overview",{"title":84,"path":85,"stem":86},"Uploading & organising files","\u002Fdrive\u002Ffiles-and-folders","06.drive\u002F02.files-and-folders",{"title":88,"path":89,"stem":90},"Sharing files","\u002Fdrive\u002Fsharing","06.drive\u002F03.sharing",{"title":92,"path":93,"stem":94},"Connect Drive to other apps","\u002Fdrive\u002Fconnect-apps","06.drive\u002F04.connect-apps",{"title":96,"path":97,"stem":98,"children":99,"page":39},"Sending & Campaigns","\u002Fsending","07.sending",[100,104,108],{"title":101,"path":102,"stem":103},"Sending limits","\u002Fsending\u002Flimits","07.sending\u002F01.limits",{"title":105,"path":106,"stem":107},"Campaigns","\u002Fsending\u002Fcampaigns","07.sending\u002F02.campaigns",{"title":109,"path":110,"stem":111},"Deliverability & staying out of spam","\u002Fsending\u002Fdeliverability","07.sending\u002F03.deliverability",{"title":113,"path":114,"stem":115,"children":116,"page":39},"Transactional Email","\u002Ftransactional","08.transactional",[117,121,125,129],{"title":118,"path":119,"stem":120},"Transactional email","\u002Ftransactional\u002Foverview","08.transactional\u002F01.overview",{"title":122,"path":123,"stem":124},"Templates","\u002Ftransactional\u002Ftemplates","08.transactional\u002F02.templates",{"title":126,"path":127,"stem":128},"Sending via the API","\u002Ftransactional\u002Fsend-api","08.transactional\u002F03.send-api",{"title":130,"path":131,"stem":132},"Webhooks","\u002Ftransactional\u002Fwebhooks","08.transactional\u002F04.webhooks",{"title":134,"path":135,"stem":136,"children":137,"page":39},"Migrations","\u002Fmigrations","09.migrations",[138,142,146],{"title":139,"path":140,"stem":141},"Migrating your email","\u002Fmigrations\u002Foverview","09.migrations\u002F01.overview",{"title":143,"path":144,"stem":145},"Migrating from Gmail","\u002Fmigrations\u002Ffrom-gmail","09.migrations\u002F02.from-gmail",{"title":147,"path":148,"stem":149},"Migrating from Microsoft 365","\u002Fmigrations\u002Ffrom-microsoft-365","09.migrations\u002F03.from-microsoft-365",{"title":151,"path":152,"stem":153,"children":154,"page":39},"AI & Developers","\u002Fdevelopers","10.developers",[155,159,163,167,170,174,178,182,187,191,195],{"title":156,"path":157,"stem":158,"icon":8},"Quickstart","\u002Fdevelopers\u002Fquickstart","10.developers\u002F00.quickstart",{"title":160,"path":161,"stem":162},"Connect Claude","\u002Fdevelopers\u002Fconnect-claude","10.developers\u002F01.connect-claude",{"title":164,"path":165,"stem":166},"AI agents & API keys","\u002Fdevelopers\u002Fai-agents","10.developers\u002F02.ai-agents",{"title":130,"path":168,"stem":169},"\u002Fdevelopers\u002Fwebhooks","10.developers\u002F03.webhooks",{"title":171,"path":172,"stem":173},"Partner API","\u002Fdevelopers\u002Fpartners","10.developers\u002F04.partners",{"title":175,"path":176,"stem":177},"Intake and Lens","\u002Fdevelopers\u002Fintake","10.developers\u002F05.intake",{"title":179,"path":180,"stem":181},"Use Faivelo from your coding agent","\u002Fdevelopers\u002Fcoding-agents","10.developers\u002F06.coding-agents",{"title":183,"path":184,"stem":185,"icon":186},"Errors","\u002Fdevelopers\u002Ferrors","10.developers\u002F07.errors","i-lucide-circle-alert",{"title":188,"path":189,"stem":190},"Email your agent","\u002Fdevelopers\u002Femail-your-agent","10.developers\u002F08.email-your-agent",{"title":192,"path":193,"stem":194},"Email agent with Claude","\u002Fdevelopers\u002Fagent-with-claude","10.developers\u002F09.agent-with-claude",{"title":196,"path":197,"stem":198},"Email agent with ChatGPT","\u002Fdevelopers\u002Fagent-with-chatgpt","10.developers\u002F10.agent-with-chatgpt",{"title":200,"path":201,"stem":202,"children":203,"page":39},"Billing","\u002Fbilling","11.billing",[204],{"title":205,"path":206,"stem":207},"Billing & plans","\u002Fbilling\u002Fplans","11.billing\u002F01.plans",{"title":209,"path":210,"stem":211,"children":212,"page":39},"Security","\u002Fsecurity","12.security",[213],{"title":209,"path":214,"stem":215},"\u002Fsecurity\u002Foverview","12.security\u002F01.overview",{"id":217,"title":130,"body":218,"description":878,"extension":879,"links":880,"meta":881,"navigation":556,"path":131,"seo":882,"stem":132,"__hash__":883},"docs\u002F08.transactional\u002F04.webhooks.md",{"type":219,"value":220,"toc":871},"minimark",[221,225,245,253,258,309,312,316,323,483,497,501,512,520,530,805,812,816,849,853,867],[222,223,224],"p",{},"Webhooks are the push counterpart of polling a send's status: register an HTTPS endpoint and Faivelo POSTs delivery events to it as they happen. Use them to mark a message delivered in your app, alert on bounces, or clean bad addresses out of your database the moment they bounce.",[222,226,227,228,232,233,236,237,240,241,244],{},"Manage webhooks in the dashboard under ",[229,230,231],"strong",{},"Settings → Developers → Webhooks",". They are included on the ",[229,234,235],{},"Growth",", ",[229,238,239],{},"Pro"," and ",[229,242,243],{},"Business"," plans.",[222,246,247,248,252],{},"This page covers the delivery events for transactional email. Webhooks also cover mailboxes, domains and account health, with retries, a delivery log and secret rotation: see the full ",[249,250,251],"a",{"href":168},"Webhooks guide",".",[254,255,257],"h2",{"id":256},"events","Events",[259,260,261,274],"table",{},[262,263,264],"thead",{},[265,266,267,271],"tr",{},[268,269,270],"th",{},"Event",[268,272,273],{},"Fires when",[275,276,277,289,299],"tbody",{},[265,278,279,286],{},[280,281,282],"td",{},[283,284,285],"code",{},"email.delivered",[280,287,288],{},"The receiving server accepted the message",[265,290,291,296],{},[280,292,293],{},[283,294,295],{},"email.bounced",[280,297,298],{},"The receiving server rejected it (hard bounce; the address is suppressed)",[265,300,301,306],{},[280,302,303],{},[283,304,305],{},"email.complained",[280,307,308],{},"The recipient marked it as spam (the address is suppressed)",[222,310,311],{},"Each webhook subscribes to the events you choose.",[254,313,315],{"id":314},"the-payload","The payload",[222,317,318,319,322],{},"Every delivery is a JSON ",[283,320,321],{},"POST",":",[324,325,330],"pre",{"className":326,"code":327,"language":328,"meta":329,"style":329},"language-json shiki shiki-themes github-light-high-contrast","{\n  \"type\": \"email.bounced\",\n  \"created_at\": \"2026-08-19T14:03:22.000Z\",\n  \"data\": {\n    \"email_id\": \"cme1x…\",\n    \"from\": \"receipts@yourdomain.com\",\n    \"to\": [\"customer@example.com\"],\n    \"subject\": \"Your order is confirmed\",\n    \"template_alias\": \"order-confirmation\",\n    \"status\": \"BOUNCED\",\n    \"sent_at\": \"2026-08-19T14:03:20.000Z\"\n  }\n}\n","json","",[283,331,332,341,358,371,380,393,406,421,434,447,460,471,477],{"__ignoreMap":329},[333,334,337],"span",{"class":335,"line":336},"line",1,[333,338,340],{"class":339},"sigWx","{\n",[333,342,344,348,351,355],{"class":335,"line":343},2,[333,345,347],{"class":346},"s742_","  \"type\"",[333,349,350],{"class":339},": ",[333,352,354],{"class":353},"sYEJz","\"email.bounced\"",[333,356,357],{"class":339},",\n",[333,359,361,364,366,369],{"class":335,"line":360},3,[333,362,363],{"class":346},"  \"created_at\"",[333,365,350],{"class":339},[333,367,368],{"class":353},"\"2026-08-19T14:03:22.000Z\"",[333,370,357],{"class":339},[333,372,374,377],{"class":335,"line":373},4,[333,375,376],{"class":346},"  \"data\"",[333,378,379],{"class":339},": {\n",[333,381,383,386,388,391],{"class":335,"line":382},5,[333,384,385],{"class":346},"    \"email_id\"",[333,387,350],{"class":339},[333,389,390],{"class":353},"\"cme1x…\"",[333,392,357],{"class":339},[333,394,396,399,401,404],{"class":335,"line":395},6,[333,397,398],{"class":346},"    \"from\"",[333,400,350],{"class":339},[333,402,403],{"class":353},"\"receipts@yourdomain.com\"",[333,405,357],{"class":339},[333,407,409,412,415,418],{"class":335,"line":408},7,[333,410,411],{"class":346},"    \"to\"",[333,413,414],{"class":339},": [",[333,416,417],{"class":353},"\"customer@example.com\"",[333,419,420],{"class":339},"],\n",[333,422,424,427,429,432],{"class":335,"line":423},8,[333,425,426],{"class":346},"    \"subject\"",[333,428,350],{"class":339},[333,430,431],{"class":353},"\"Your order is confirmed\"",[333,433,357],{"class":339},[333,435,437,440,442,445],{"class":335,"line":436},9,[333,438,439],{"class":346},"    \"template_alias\"",[333,441,350],{"class":339},[333,443,444],{"class":353},"\"order-confirmation\"",[333,446,357],{"class":339},[333,448,450,453,455,458],{"class":335,"line":449},10,[333,451,452],{"class":346},"    \"status\"",[333,454,350],{"class":339},[333,456,457],{"class":353},"\"BOUNCED\"",[333,459,357],{"class":339},[333,461,463,466,468],{"class":335,"line":462},11,[333,464,465],{"class":346},"    \"sent_at\"",[333,467,350],{"class":339},[333,469,470],{"class":353},"\"2026-08-19T14:03:20.000Z\"\n",[333,472,474],{"class":335,"line":473},12,[333,475,476],{"class":339},"  }\n",[333,478,480],{"class":335,"line":479},13,[333,481,482],{"class":339},"}\n",[222,484,485,488,489,492,493,496],{},[283,486,487],{},"data.email_id"," is the id the ",[249,490,491],{"href":127},"send call"," returned. Bounce and complaint events may carry extra detail about the reason. The request also carries an ",[283,494,495],{},"X-Faivelo-Event"," header naming the event type.",[254,498,500],{"id":499},"verifying-signatures","Verifying signatures",[222,502,503,504,507,508,511],{},"Anyone who discovers your endpoint URL can POST fake JSON to it — so verify every request. Each webhook has a ",[229,505,506],{},"signing secret"," (shown when you create it), and every delivery is signed with an ",[283,509,510],{},"X-Faivelo-Signature"," header:",[324,513,518],{"className":514,"code":516,"language":517},[515],"language-text","X-Faivelo-Signature: t=1755612202,v1=5257a869e7…\n","text",[283,519,516],{"__ignoreMap":329},[222,521,522,525,526,529],{},[283,523,524],{},"v1"," is ",[283,527,528],{},"HMAC-SHA256(secret, \"{t}.{raw request body}\")",". To verify:",[324,531,535],{"className":532,"code":533,"language":534,"meta":329,"style":329},"language-js shiki shiki-themes github-light-high-contrast","import { createHmac, timingSafeEqual } from 'node:crypto'\n\nfunction verify(rawBody, header, secret) {\n  const { t, v1 } = Object.fromEntries(header.split(',').map(p => p.split('=')))\n  \u002F\u002F Reject stale timestamps to block replay attacks\n  if (Math.abs(Date.now() \u002F 1000 - Number(t)) > 300) return false\n  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')\n  return v1.length === expected.length\n    && timingSafeEqual(Buffer.from(v1), Buffer.from(expected))\n}\n","js",[283,536,537,552,558,587,652,658,708,760,780,801],{"__ignoreMap":329},[333,538,539,543,546,549],{"class":335,"line":336},[333,540,542],{"class":541},"sTJeM","import",[333,544,545],{"class":339}," { createHmac, timingSafeEqual } ",[333,547,548],{"class":541},"from",[333,550,551],{"class":353}," 'node:crypto'\n",[333,553,554],{"class":335,"line":343},[333,555,557],{"emptyLinePlaceholder":556},true,"\n",[333,559,560,563,567,570,574,576,579,581,584],{"class":335,"line":360},[333,561,562],{"class":541},"function",[333,564,566],{"class":565},"s3dhs"," verify",[333,568,569],{"class":339},"(",[333,571,573],{"class":572},"sV4o_","rawBody",[333,575,236],{"class":339},[333,577,578],{"class":572},"header",[333,580,236],{"class":339},[333,582,583],{"class":572},"secret",[333,585,586],{"class":339},") {\n",[333,588,589,592,595,599,601,603,606,609,612,615,618,621,623,626,629,632,634,636,639,642,644,646,649],{"class":335,"line":373},[333,590,591],{"class":541},"  const",[333,593,594],{"class":339}," { ",[333,596,598],{"class":597},"sacAq","t",[333,600,236],{"class":339},[333,602,524],{"class":597},[333,604,605],{"class":339}," } ",[333,607,608],{"class":541},"=",[333,610,611],{"class":339}," Object.",[333,613,614],{"class":565},"fromEntries",[333,616,617],{"class":339},"(header.",[333,619,620],{"class":565},"split",[333,622,569],{"class":339},[333,624,625],{"class":353},"','",[333,627,628],{"class":339},").",[333,630,631],{"class":565},"map",[333,633,569],{"class":339},[333,635,222],{"class":572},[333,637,638],{"class":541}," =>",[333,640,641],{"class":339}," p.",[333,643,620],{"class":565},[333,645,569],{"class":339},[333,647,648],{"class":353},"'='",[333,650,651],{"class":339},")))\n",[333,653,654],{"class":335,"line":382},[333,655,657],{"class":656},"sFeEa","  \u002F\u002F Reject stale timestamps to block replay attacks\n",[333,659,660,663,666,669,672,675,678,681,684,687,690,693,696,699,702,705],{"class":335,"line":395},[333,661,662],{"class":541},"  if",[333,664,665],{"class":339}," (Math.",[333,667,668],{"class":565},"abs",[333,670,671],{"class":339},"(Date.",[333,673,674],{"class":565},"now",[333,676,677],{"class":339},"() ",[333,679,680],{"class":541},"\u002F",[333,682,683],{"class":597}," 1000",[333,685,686],{"class":541}," -",[333,688,689],{"class":565}," Number",[333,691,692],{"class":339},"(t)) ",[333,694,695],{"class":541},">",[333,697,698],{"class":597}," 300",[333,700,701],{"class":339},") ",[333,703,704],{"class":541},"return",[333,706,707],{"class":597}," false\n",[333,709,710,712,715,718,721,723,726,729,732,734,737,739,742,744,747,749,752,754,757],{"class":335,"line":408},[333,711,591],{"class":541},[333,713,714],{"class":597}," expected",[333,716,717],{"class":541}," =",[333,719,720],{"class":565}," createHmac",[333,722,569],{"class":339},[333,724,725],{"class":353},"'sha256'",[333,727,728],{"class":339},", secret).",[333,730,731],{"class":565},"update",[333,733,569],{"class":339},[333,735,736],{"class":353},"`${",[333,738,598],{"class":339},[333,740,741],{"class":353},"}.${",[333,743,573],{"class":339},[333,745,746],{"class":353},"}`",[333,748,628],{"class":339},[333,750,751],{"class":565},"digest",[333,753,569],{"class":339},[333,755,756],{"class":353},"'hex'",[333,758,759],{"class":339},")\n",[333,761,762,765,768,771,774,777],{"class":335,"line":423},[333,763,764],{"class":541},"  return",[333,766,767],{"class":339}," v1.",[333,769,770],{"class":597},"length",[333,772,773],{"class":541}," ===",[333,775,776],{"class":339}," expected.",[333,778,779],{"class":597},"length\n",[333,781,782,785,788,791,793,796,798],{"class":335,"line":436},[333,783,784],{"class":541},"    &&",[333,786,787],{"class":565}," timingSafeEqual",[333,789,790],{"class":339},"(Buffer.",[333,792,548],{"class":565},[333,794,795],{"class":339},"(v1), Buffer.",[333,797,548],{"class":565},[333,799,800],{"class":339},"(expected))\n",[333,802,803],{"class":335,"line":449},[333,804,482],{"class":339},[222,806,807,808,811],{},"Compute the HMAC over the ",[229,809,810],{},"raw request body",", before any JSON parsing — a re-serialized body won't match.",[254,813,815],{"id":814},"delivery-behavior","Delivery behavior",[817,818,819,827,834,837],"ul",{},[820,821,822,823,826],"li",{},"Your endpoint has ",[229,824,825],{},"5 seconds"," to respond with a 2xx status. Respond first, process after — do your database work asynchronously.",[820,828,829,830,833],{},"Redirects are ",[229,831,832],{},"not followed","; point the webhook at its final URL.",[820,835,836],{},"The dashboard shows each webhook's last successful delivery and last error, so a misbehaving endpoint is visible at a glance.",[820,838,839,840,843,844,848],{},"Each event is delivered ",[229,841,842],{},"once"," — there is no automatic retry queue. Treat webhooks as the fast path and the ",[249,845,847],{"href":846},"\u002Ftransactional\u002Fsend-api#tracking-delivery","send status API"," as the source of truth you can re-query anytime.",[254,850,852],{"id":851},"testing","Testing",[222,854,855,856,859,860,862,863,866],{},"Every webhook has a ",[229,857,858],{},"Send test"," button in the dashboard. It delivers a real signed ",[283,861,285],{}," event with ",[283,864,865],{},"\"test\": true"," in the payload — so you can prove your endpoint and signature verification end-to-end without sending an email.",[868,869,870],"style",{},"html pre.shiki code .sigWx, html code.shiki .sigWx{--shiki-default:#0E1116}html pre.shiki code .s742_, html code.shiki .s742_{--shiki-default:#024C1A}html pre.shiki code .sYEJz, html code.shiki .sYEJz{--shiki-default:#032563}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);}html pre.shiki code .sTJeM, html code.shiki .sTJeM{--shiki-default:#A0111F}html pre.shiki code .s3dhs, html code.shiki .s3dhs{--shiki-default:#622CBC}html pre.shiki code .sV4o_, html code.shiki .sV4o_{--shiki-default:#702C00}html pre.shiki code .sacAq, html code.shiki .sacAq{--shiki-default:#023B95}html pre.shiki code .sFeEa, html code.shiki .sFeEa{--shiki-default:#66707B}",{"title":329,"searchDepth":336,"depth":343,"links":872},[873,874,875,876,877],{"id":256,"depth":343,"text":257},{"id":314,"depth":343,"text":315},{"id":499,"depth":343,"text":500},{"id":814,"depth":343,"text":815},{"id":851,"depth":343,"text":852},"Get delivery, bounce, and complaint events pushed to your server.","md",null,{},{"title":130,"description":878},"DwrHi4OxicfQfoCkBI35FSyAMb-VJ33wfWtnV2ChhQ4",[885,887],{"title":126,"path":127,"stem":128,"description":886,"children":-1},"Send transactional email with POST \u002Fapi\u002Fv1\u002Femails.",{"title":139,"path":140,"stem":141,"description":888,"children":-1},"Move your existing mailbox into Faivelo with the migration wizard — import every folder from Gmail, Outlook, or any provider.",1792109925204]