[{"data":1,"prerenderedAt":977},["ShallowReactive",2],{"content-query-bTTUJN6jzW":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"crumb":11,"term":11,"summary":12,"group":13,"order":14,"updated":15,"cta":16,"related":24,"faq":43,"body":56,"_type":970,"_id":971,"_source":972,"_file":973,"_stem":974,"_extension":975,"sitemap":976},"/glossary/webhook-signature","glossary",false,"","What is a webhook signature? How verification works","A webhook signature is an HMAC of the request body, sent in a header, that proves a webhook came from the provider and wasn't modified. Formats, verification code and common mistakes.","reference","Webhook signature","A header that proves a webhook is genuine and unmodified.","Security",10,"2026-10-28",{"eyebrow":17,"title":18,"text":19,"to":20,"label":21,"secondaryTo":22,"secondaryLabel":23},"Free tool","Check a webhook signature in your browser","Paste the raw body, the signature header and your secret into the webhook signature verifier to see whether it matches, with verifiers for Stripe, GitHub, Shopify, Slack, Standard Webhooks and more. Nothing is sent to a server.","/verify-webhook-signature/","Verify a signature","/hmac-verification/","HMAC calculator",[25,28,31,34,37,40],{"title":26,"to":27},"Webhook secret","/glossary/webhook-secret/",{"title":29,"to":30},"HMAC","/glossary/hmac/",{"title":32,"to":33},"Standard Webhooks","/glossary/standard-webhooks/",{"title":35,"to":36},"Webhook replay","/glossary/webhook-replay/",{"title":38,"to":39},"401 vs 403","/http-errors/401-vs-403/",{"title":41,"to":42},"How to verify webhook signatures","/blog/verify-webhook-signature/",[44,47,50,53],{"q":45,"a":46},"What is a webhook signature?","A webhook signature is a value the provider computes from the request body and a shared secret, usually with HMAC-SHA256, and sends in a request header. The receiver recomputes it with the same secret and compares. A match proves the webhook came from someone who knows the secret and that the body was not changed in transit.",{"q":48,"a":49},"Why does my webhook signature verification fail?","The most common cause is computing the HMAC over a parsed and re-serialized body instead of the exact raw bytes. Other causes are using the wrong secret, for example a test-mode secret against live events, forgetting to include the timestamp in the signed string, comparing hex against base64, or a proxy that modifies the body.",{"q":51,"a":52},"Where is the webhook signature sent?","In a request header whose name depends on the provider. Stripe uses Stripe-Signature, GitHub uses X-Hub-Signature-256, Shopify uses X-Shopify-Hmac-Sha256, Slack uses X-Slack-Signature, and providers that follow the Standard Webhooks spec use webhook-signature.",{"q":54,"a":55},"Is HTTPS enough without a webhook signature?","No. HTTPS encrypts the request in transit, but anyone who knows your webhook URL can send a request to it. The signature proves the sender knows the shared secret. Use both.",{"type":57,"children":58,"toc":964},"root",[59,95,163,170,222,521,527,732,768,774,915,921,958],{"type":60,"tag":61,"props":62,"children":63},"element","p",{},[64,71,73,79,81,85,87,93],{"type":60,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":69,"value":70},"text","A webhook signature is a value, sent in a request header, that proves a webhook really came from the provider and that its body wasn't changed on the way.",{"type":69,"value":72}," The provider computes it from the raw body (often plus a timestamp) and a shared ",{"type":60,"tag":74,"props":75,"children":76},"a",{"href":27},[77],{"type":69,"value":78},"webhook secret",{"type":69,"value":80},", almost always with ",{"type":60,"tag":74,"props":82,"children":83},{"href":30},[84],{"type":69,"value":29},{"type":69,"value":86},"-SHA256. Your ",{"type":60,"tag":74,"props":88,"children":90},{"href":89},"/glossary/webhook-endpoint/",[91],{"type":69,"value":92},"endpoint",{"type":69,"value":94}," recomputes it with the same secret and rejects the request if the values don't match.",{"type":60,"tag":96,"props":97,"children":101},"pre",{"className":98,"code":99,"language":100,"meta":7,"style":7},"language-http shiki shiki-themes github-dark","POST /webhooks/github HTTP/1.1\nX-GitHub-Event: push\nX-Hub-Signature-256: sha256=3b1f6e4c0a5d8c3f0a3d5e2b1c4f9a7e8d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a\nContent-Type: application/json\n\n{\"ref\":\"refs/heads/main\", ...}\n","http",[102],{"type":60,"tag":103,"props":104,"children":105},"code",{"__ignoreMap":7},[106,117,126,135,144,154],{"type":60,"tag":107,"props":108,"children":111},"span",{"class":109,"line":110},"line",1,[112],{"type":60,"tag":107,"props":113,"children":114},{},[115],{"type":69,"value":116},"POST /webhooks/github HTTP/1.1\n",{"type":60,"tag":107,"props":118,"children":120},{"class":109,"line":119},2,[121],{"type":60,"tag":107,"props":122,"children":123},{},[124],{"type":69,"value":125},"X-GitHub-Event: push\n",{"type":60,"tag":107,"props":127,"children":129},{"class":109,"line":128},3,[130],{"type":60,"tag":107,"props":131,"children":132},{},[133],{"type":69,"value":134},"X-Hub-Signature-256: sha256=3b1f6e4c0a5d8c3f0a3d5e2b1c4f9a7e8d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a\n",{"type":60,"tag":107,"props":136,"children":138},{"class":109,"line":137},4,[139],{"type":60,"tag":107,"props":140,"children":141},{},[142],{"type":69,"value":143},"Content-Type: application/json\n",{"type":60,"tag":107,"props":145,"children":147},{"class":109,"line":146},5,[148],{"type":60,"tag":107,"props":149,"children":151},{"emptyLinePlaceholder":150},true,[152],{"type":69,"value":153},"\n",{"type":60,"tag":107,"props":155,"children":157},{"class":109,"line":156},6,[158],{"type":60,"tag":107,"props":159,"children":160},{},[161],{"type":69,"value":162},"{\"ref\":\"refs/heads/main\", ...}\n",{"type":60,"tag":164,"props":165,"children":167},"h2",{"id":166},"how-webhook-signature-verification-works",[168],{"type":69,"value":169},"How webhook signature verification works",{"type":60,"tag":171,"props":172,"children":173},"ol",{},[174,180,192,205,210],{"type":60,"tag":175,"props":176,"children":177},"li",{},[178],{"type":69,"value":179},"You and the provider share a secret, shown when you create the webhook.",{"type":60,"tag":175,"props":181,"children":182},{},[183,185,190],{"type":69,"value":184},"For each delivery, the provider builds a ",{"type":60,"tag":65,"props":186,"children":187},{},[188],{"type":69,"value":189},"signed string",{"type":69,"value":191},": the raw body, or a timestamp and the body joined together.",{"type":60,"tag":175,"props":193,"children":194},{},[195,197,203],{"type":69,"value":196},"It computes ",{"type":60,"tag":103,"props":198,"children":200},{"className":199},[],[201],{"type":69,"value":202},"HMAC-SHA256(secret, signed_string)",{"type":69,"value":204}," and sends the result, hex or base64 encoded, in a header.",{"type":60,"tag":175,"props":206,"children":207},{},[208],{"type":69,"value":209},"Your endpoint builds the same string from the bytes it received, computes the HMAC, and compares in constant time.",{"type":60,"tag":175,"props":211,"children":212},{},[213,215,220],{"type":69,"value":214},"If the provider includes a timestamp, you also reject requests older than a few minutes, which stops ",{"type":60,"tag":74,"props":216,"children":217},{"href":36},[218],{"type":69,"value":219},"replay attacks",{"type":69,"value":221},".",{"type":60,"tag":96,"props":223,"children":227},{"className":224,"code":225,"language":226,"meta":7,"style":7},"language-js shiki shiki-themes github-dark","import crypto from 'node:crypto'\n\nfunction verifyGithub(rawBody, header, secret) {\n  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex')\n  const a = Buffer.from(expected), b = Buffer.from(header || '')\n  return a.length === b.length && crypto.timingSafeEqual(a, b)\n}\n","js",[228],{"type":60,"tag":103,"props":229,"children":230},{"__ignoreMap":7},[231,257,264,313,395,461,512],{"type":60,"tag":107,"props":232,"children":233},{"class":109,"line":110},[234,240,246,251],{"type":60,"tag":107,"props":235,"children":237},{"style":236},"--shiki-default:#F97583",[238],{"type":69,"value":239},"import",{"type":60,"tag":107,"props":241,"children":243},{"style":242},"--shiki-default:#E1E4E8",[244],{"type":69,"value":245}," crypto ",{"type":60,"tag":107,"props":247,"children":248},{"style":236},[249],{"type":69,"value":250},"from",{"type":60,"tag":107,"props":252,"children":254},{"style":253},"--shiki-default:#9ECBFF",[255],{"type":69,"value":256}," 'node:crypto'\n",{"type":60,"tag":107,"props":258,"children":259},{"class":109,"line":119},[260],{"type":60,"tag":107,"props":261,"children":262},{"emptyLinePlaceholder":150},[263],{"type":69,"value":153},{"type":60,"tag":107,"props":265,"children":266},{"class":109,"line":128},[267,272,278,283,289,294,299,303,308],{"type":60,"tag":107,"props":268,"children":269},{"style":236},[270],{"type":69,"value":271},"function",{"type":60,"tag":107,"props":273,"children":275},{"style":274},"--shiki-default:#B392F0",[276],{"type":69,"value":277}," verifyGithub",{"type":60,"tag":107,"props":279,"children":280},{"style":242},[281],{"type":69,"value":282},"(",{"type":60,"tag":107,"props":284,"children":286},{"style":285},"--shiki-default:#FFAB70",[287],{"type":69,"value":288},"rawBody",{"type":60,"tag":107,"props":290,"children":291},{"style":242},[292],{"type":69,"value":293},", ",{"type":60,"tag":107,"props":295,"children":296},{"style":285},[297],{"type":69,"value":298},"header",{"type":60,"tag":107,"props":300,"children":301},{"style":242},[302],{"type":69,"value":293},{"type":60,"tag":107,"props":304,"children":305},{"style":285},[306],{"type":69,"value":307},"secret",{"type":60,"tag":107,"props":309,"children":310},{"style":242},[311],{"type":69,"value":312},") {\n",{"type":60,"tag":107,"props":314,"children":315},{"class":109,"line":137},[316,321,327,332,337,342,347,352,356,361,366,371,376,381,385,390],{"type":60,"tag":107,"props":317,"children":318},{"style":236},[319],{"type":69,"value":320},"  const",{"type":60,"tag":107,"props":322,"children":324},{"style":323},"--shiki-default:#79B8FF",[325],{"type":69,"value":326}," expected",{"type":60,"tag":107,"props":328,"children":329},{"style":236},[330],{"type":69,"value":331}," =",{"type":60,"tag":107,"props":333,"children":334},{"style":253},[335],{"type":69,"value":336}," 'sha256='",{"type":60,"tag":107,"props":338,"children":339},{"style":236},[340],{"type":69,"value":341}," +",{"type":60,"tag":107,"props":343,"children":344},{"style":242},[345],{"type":69,"value":346}," crypto.",{"type":60,"tag":107,"props":348,"children":349},{"style":274},[350],{"type":69,"value":351},"createHmac",{"type":60,"tag":107,"props":353,"children":354},{"style":242},[355],{"type":69,"value":282},{"type":60,"tag":107,"props":357,"children":358},{"style":253},[359],{"type":69,"value":360},"'sha256'",{"type":60,"tag":107,"props":362,"children":363},{"style":242},[364],{"type":69,"value":365},", secret).",{"type":60,"tag":107,"props":367,"children":368},{"style":274},[369],{"type":69,"value":370},"update",{"type":60,"tag":107,"props":372,"children":373},{"style":242},[374],{"type":69,"value":375},"(rawBody).",{"type":60,"tag":107,"props":377,"children":378},{"style":274},[379],{"type":69,"value":380},"digest",{"type":60,"tag":107,"props":382,"children":383},{"style":242},[384],{"type":69,"value":282},{"type":60,"tag":107,"props":386,"children":387},{"style":253},[388],{"type":69,"value":389},"'hex'",{"type":60,"tag":107,"props":391,"children":392},{"style":242},[393],{"type":69,"value":394},")\n",{"type":60,"tag":107,"props":396,"children":397},{"class":109,"line":146},[398,402,407,411,416,420,425,430,434,438,442,447,452,457],{"type":60,"tag":107,"props":399,"children":400},{"style":236},[401],{"type":69,"value":320},{"type":60,"tag":107,"props":403,"children":404},{"style":323},[405],{"type":69,"value":406}," a",{"type":60,"tag":107,"props":408,"children":409},{"style":236},[410],{"type":69,"value":331},{"type":60,"tag":107,"props":412,"children":413},{"style":242},[414],{"type":69,"value":415}," Buffer.",{"type":60,"tag":107,"props":417,"children":418},{"style":274},[419],{"type":69,"value":250},{"type":60,"tag":107,"props":421,"children":422},{"style":242},[423],{"type":69,"value":424},"(expected), ",{"type":60,"tag":107,"props":426,"children":427},{"style":323},[428],{"type":69,"value":429},"b",{"type":60,"tag":107,"props":431,"children":432},{"style":236},[433],{"type":69,"value":331},{"type":60,"tag":107,"props":435,"children":436},{"style":242},[437],{"type":69,"value":415},{"type":60,"tag":107,"props":439,"children":440},{"style":274},[441],{"type":69,"value":250},{"type":60,"tag":107,"props":443,"children":444},{"style":242},[445],{"type":69,"value":446},"(header ",{"type":60,"tag":107,"props":448,"children":449},{"style":236},[450],{"type":69,"value":451},"||",{"type":60,"tag":107,"props":453,"children":454},{"style":253},[455],{"type":69,"value":456}," ''",{"type":60,"tag":107,"props":458,"children":459},{"style":242},[460],{"type":69,"value":394},{"type":60,"tag":107,"props":462,"children":463},{"class":109,"line":156},[464,469,474,479,484,489,493,498,502,507],{"type":60,"tag":107,"props":465,"children":466},{"style":236},[467],{"type":69,"value":468},"  return",{"type":60,"tag":107,"props":470,"children":471},{"style":242},[472],{"type":69,"value":473}," a.",{"type":60,"tag":107,"props":475,"children":476},{"style":323},[477],{"type":69,"value":478},"length",{"type":60,"tag":107,"props":480,"children":481},{"style":236},[482],{"type":69,"value":483}," ===",{"type":60,"tag":107,"props":485,"children":486},{"style":242},[487],{"type":69,"value":488}," b.",{"type":60,"tag":107,"props":490,"children":491},{"style":323},[492],{"type":69,"value":478},{"type":60,"tag":107,"props":494,"children":495},{"style":236},[496],{"type":69,"value":497}," &&",{"type":60,"tag":107,"props":499,"children":500},{"style":242},[501],{"type":69,"value":346},{"type":60,"tag":107,"props":503,"children":504},{"style":274},[505],{"type":69,"value":506},"timingSafeEqual",{"type":60,"tag":107,"props":508,"children":509},{"style":242},[510],{"type":69,"value":511},"(a, b)\n",{"type":60,"tag":107,"props":513,"children":515},{"class":109,"line":514},7,[516],{"type":60,"tag":107,"props":517,"children":518},{"style":242},[519],{"type":69,"value":520},"}\n",{"type":60,"tag":164,"props":522,"children":524},{"id":523},"signature-formats-by-provider",[525],{"type":69,"value":526},"Signature formats by provider",{"type":60,"tag":528,"props":529,"children":530},"table",{},[531,560],{"type":60,"tag":532,"props":533,"children":534},"thead",{},[535],{"type":60,"tag":536,"props":537,"children":538},"tr",{},[539,545,550,555],{"type":60,"tag":540,"props":541,"children":542},"th",{},[543],{"type":69,"value":544},"Provider",{"type":60,"tag":540,"props":546,"children":547},{},[548],{"type":69,"value":549},"Header",{"type":60,"tag":540,"props":551,"children":552},{},[553],{"type":69,"value":554},"Signed string",{"type":60,"tag":540,"props":556,"children":557},{},[558],{"type":69,"value":559},"Encoding",{"type":60,"tag":561,"props":562,"children":563},"tbody",{},[564,592,622,648,686],{"type":60,"tag":536,"props":565,"children":566},{},[567,573,582,587],{"type":60,"tag":568,"props":569,"children":570},"td",{},[571],{"type":69,"value":572},"GitHub",{"type":60,"tag":568,"props":574,"children":575},{},[576],{"type":60,"tag":103,"props":577,"children":579},{"className":578},[],[580],{"type":69,"value":581},"X-Hub-Signature-256: sha256=...",{"type":60,"tag":568,"props":583,"children":584},{},[585],{"type":69,"value":586},"raw body",{"type":60,"tag":568,"props":588,"children":589},{},[590],{"type":69,"value":591},"hex",{"type":60,"tag":536,"props":593,"children":594},{},[595,600,609,618],{"type":60,"tag":568,"props":596,"children":597},{},[598],{"type":69,"value":599},"Stripe",{"type":60,"tag":568,"props":601,"children":602},{},[603],{"type":60,"tag":103,"props":604,"children":606},{"className":605},[],[607],{"type":69,"value":608},"Stripe-Signature: t=...,v1=...",{"type":60,"tag":568,"props":610,"children":611},{},[612],{"type":60,"tag":103,"props":613,"children":615},{"className":614},[],[616],{"type":69,"value":617},"{t}.{body}",{"type":60,"tag":568,"props":619,"children":620},{},[621],{"type":69,"value":591},{"type":60,"tag":536,"props":623,"children":624},{},[625,630,639,643],{"type":60,"tag":568,"props":626,"children":627},{},[628],{"type":69,"value":629},"Shopify",{"type":60,"tag":568,"props":631,"children":632},{},[633],{"type":60,"tag":103,"props":634,"children":636},{"className":635},[],[637],{"type":69,"value":638},"X-Shopify-Hmac-Sha256",{"type":60,"tag":568,"props":640,"children":641},{},[642],{"type":69,"value":586},{"type":60,"tag":568,"props":644,"children":645},{},[646],{"type":69,"value":647},"base64",{"type":60,"tag":536,"props":649,"children":650},{},[651,656,673,682],{"type":60,"tag":568,"props":652,"children":653},{},[654],{"type":69,"value":655},"Slack",{"type":60,"tag":568,"props":657,"children":658},{},[659,665,667],{"type":60,"tag":103,"props":660,"children":662},{"className":661},[],[663],{"type":69,"value":664},"X-Slack-Signature: v0=...",{"type":69,"value":666}," with ",{"type":60,"tag":103,"props":668,"children":670},{"className":669},[],[671],{"type":69,"value":672},"X-Slack-Request-Timestamp",{"type":60,"tag":568,"props":674,"children":675},{},[676],{"type":60,"tag":103,"props":677,"children":679},{"className":678},[],[680],{"type":69,"value":681},"v0:{timestamp}:{body}",{"type":60,"tag":568,"props":683,"children":684},{},[685],{"type":69,"value":591},{"type":60,"tag":536,"props":687,"children":688},{},[689,696,719,728],{"type":60,"tag":568,"props":690,"children":691},{},[692],{"type":60,"tag":74,"props":693,"children":694},{"href":33},[695],{"type":69,"value":32},{"type":60,"tag":568,"props":697,"children":698},{},[699,705,706,712,713],{"type":60,"tag":103,"props":700,"children":702},{"className":701},[],[703],{"type":69,"value":704},"webhook-signature: v1,...",{"type":69,"value":666},{"type":60,"tag":103,"props":707,"children":709},{"className":708},[],[710],{"type":69,"value":711},"webhook-id",{"type":69,"value":293},{"type":60,"tag":103,"props":714,"children":716},{"className":715},[],[717],{"type":69,"value":718},"webhook-timestamp",{"type":60,"tag":568,"props":720,"children":721},{},[722],{"type":60,"tag":103,"props":723,"children":725},{"className":724},[],[726],{"type":69,"value":727},"{id}.{timestamp}.{body}",{"type":60,"tag":568,"props":729,"children":730},{},[731],{"type":69,"value":647},{"type":60,"tag":61,"props":733,"children":734},{},[735,737,742,743,748,749,754,755,760,762,767],{"type":69,"value":736},"Each has its own verifier page: ",{"type":60,"tag":74,"props":738,"children":740},{"href":739},"/verify-stripe-webhook-signature/",[741],{"type":69,"value":599},{"type":69,"value":293},{"type":60,"tag":74,"props":744,"children":746},{"href":745},"/verify-github-webhook-signature/",[747],{"type":69,"value":572},{"type":69,"value":293},{"type":60,"tag":74,"props":750,"children":752},{"href":751},"/verify-shopify-webhook-signature/",[753],{"type":69,"value":629},{"type":69,"value":293},{"type":60,"tag":74,"props":756,"children":758},{"href":757},"/verify-slack-webhook-signature/",[759],{"type":69,"value":655},{"type":69,"value":761}," and ",{"type":60,"tag":74,"props":763,"children":765},{"href":764},"/verify-standard-webhooks-signature/",[766],{"type":69,"value":32},{"type":69,"value":221},{"type":60,"tag":164,"props":769,"children":771},{"id":770},"common-mistakes",[772],{"type":69,"value":773},"Common mistakes",{"type":60,"tag":775,"props":776,"children":777},"ul",{},[778,796,836,854,864,874,884],{"type":60,"tag":175,"props":779,"children":780},{},[781,786,788,794],{"type":60,"tag":65,"props":782,"children":783},{},[784],{"type":69,"value":785},"Verifying a parsed body.",{"type":69,"value":787}," ",{"type":60,"tag":103,"props":789,"children":791},{"className":790},[],[792],{"type":69,"value":793},"JSON.stringify(JSON.parse(body))",{"type":69,"value":795}," doesn't give back the same bytes. Capture the raw body before any JSON middleware runs on the webhook route.",{"type":60,"tag":175,"props":797,"children":798},{},[799,811,813,819,820,826,828,834],{"type":60,"tag":65,"props":800,"children":801},{},[802,804,810],{"type":69,"value":803},"Comparing with ",{"type":60,"tag":103,"props":805,"children":807},{"className":806},[],[808],{"type":69,"value":809},"==",{"type":69,"value":221},{"type":69,"value":812}," A normal string comparison exits at the first differing character, which can leak timing information. Use ",{"type":60,"tag":103,"props":814,"children":816},{"className":815},[],[817],{"type":69,"value":818},"crypto.timingSafeEqual",{"type":69,"value":293},{"type":60,"tag":103,"props":821,"children":823},{"className":822},[],[824],{"type":69,"value":825},"hmac.compare_digest",{"type":69,"value":827}," in Python, or ",{"type":60,"tag":103,"props":829,"children":831},{"className":830},[],[832],{"type":69,"value":833},"hmac.Equal",{"type":69,"value":835}," in Go.",{"type":60,"tag":175,"props":837,"children":838},{},[839,844,846,852],{"type":60,"tag":65,"props":840,"children":841},{},[842],{"type":69,"value":843},"Wrong secret.",{"type":69,"value":845}," Test-mode and live-mode secrets differ, and each endpoint in Stripe has its own. Standard Webhooks secrets must be base64-decoded after removing the ",{"type":60,"tag":103,"props":847,"children":849},{"className":848},[],[850],{"type":69,"value":851},"whsec_",{"type":69,"value":853}," prefix.",{"type":60,"tag":175,"props":855,"children":856},{},[857,862],{"type":60,"tag":65,"props":858,"children":859},{},[860],{"type":69,"value":861},"Mixing up encodings.",{"type":69,"value":863}," Comparing a hex digest against a base64 header always fails.",{"type":60,"tag":175,"props":865,"children":866},{},[867,872],{"type":60,"tag":65,"props":868,"children":869},{},[870],{"type":69,"value":871},"Ignoring the timestamp.",{"type":69,"value":873}," A valid signed request captured once can be resent forever unless you check its age.",{"type":60,"tag":175,"props":875,"children":876},{},[877,882],{"type":60,"tag":65,"props":878,"children":879},{},[880],{"type":69,"value":881},"A proxy that rewrites the body.",{"type":69,"value":883}," Anything that re-encodes, decompresses or reformats the body between the provider and your code breaks the signature. If you forward webhooks, the forwarder must pass the body through byte for byte.",{"type":60,"tag":175,"props":885,"children":886},{},[887,900,902,908,910,914],{"type":60,"tag":65,"props":888,"children":889},{},[890,892,898],{"type":69,"value":891},"Returning ",{"type":60,"tag":103,"props":893,"children":895},{"className":894},[],[896],{"type":69,"value":897},"200",{"type":69,"value":899}," on failure.",{"type":69,"value":901}," Return ",{"type":60,"tag":103,"props":903,"children":905},{"className":904},[],[906],{"type":69,"value":907},"401",{"type":69,"value":909}," for a missing or invalid signature so the failure shows up in the provider's logs. See ",{"type":60,"tag":74,"props":911,"children":912},{"href":39},[913],{"type":69,"value":38},{"type":69,"value":221},{"type":60,"tag":164,"props":916,"children":918},{"id":917},"signatures-and-webhook-forwarding",[919],{"type":69,"value":920},"Signatures and webhook forwarding",{"type":60,"tag":61,"props":922,"children":923},{},[924,926,932,934,940,942,948,950,956],{"type":69,"value":925},"When webhooks pass through a ",{"type":60,"tag":74,"props":927,"children":929},{"href":928},"/glossary/webhook-gateway/",[930],{"type":69,"value":931},"webhook gateway",{"type":69,"value":933}," or ",{"type":60,"tag":74,"props":935,"children":937},{"href":936},"/glossary/webhook-forwarding/",[938],{"type":69,"value":939},"forwarder",{"type":69,"value":941},", the provider's signature still covers the original body. Webhook Relay forwards the body and headers unchanged unless you attach a transform, so your endpoint can verify as usual. You can also verify HMAC signatures at the gateway with a function, as shown in the ",{"type":60,"tag":74,"props":943,"children":945},{"href":944},"/docs/webhooks/auth/hmac/",[946],{"type":69,"value":947},"HMAC authentication docs",{"type":69,"value":949},". For webhooks you send to your own customers, the ",{"type":60,"tag":74,"props":951,"children":953},{"href":952},"/outbound-webhooks/",[954],{"type":69,"value":955},"Outbound Gateway",{"type":69,"value":957}," signs every delivery with Standard Webhooks headers.",{"type":60,"tag":959,"props":960,"children":961},"style",{},[962],{"type":69,"value":963},"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":128,"depth":128,"links":965},[966,967,968,969],{"id":166,"depth":119,"text":169},{"id":523,"depth":119,"text":526},{"id":770,"depth":119,"text":773},{"id":917,"depth":119,"text":920},"markdown","content:glossary:webhook-signature.md","content","glossary/webhook-signature.md","glossary/webhook-signature","md",{"loc":4},1793199804980]