[{"data":1,"prerenderedAt":3624},["ShallowReactive",2],{"docs-navigation":3,"content-query-T340Keah4a":315},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160,163,166,169,172,175,178,181,184,187,190,193,196,199,202,205,208,211,214,217,220,223,226,229,232,235,238,241,244,247,250,253,256,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312],{"_path":5,"title":6},"/docs/account/account-management","Account management",{"_path":8,"title":9},"/docs/account/mfa","Multi-factor authentication (MFA)",{"_path":11,"title":12},"/docs/account/team","Teams and sub-accounts",{"_path":14,"title":15},"/docs/account/billing-and-subscriptions","Billing & subscriptions",{"_path":17,"title":18},"/docs/account/access-tokens","Webhook Relay access tokens: permissions and subscription scopes",{"_path":20,"title":21},"/docs/clawhub","Webhook Relay on ClawHub",{"_path":23,"title":24},"/docs/email","Receive emails as webhooks",{"_path":26,"title":27},"/docs/email/payload","Email webhook payload",{"_path":29,"title":30},"/docs/email/filtering-and-policy","Sender filtering & policy",{"_path":32,"title":33},"/docs/email/cli","Create & poll email addresses from the CLI",{"_path":35,"title":36},"/docs","Getting Started",{"_path":38,"title":39},"/docs/installation/cli","CLI",{"_path":41,"title":42},"/docs/installation/docker","Docker container",{"_path":44,"title":45},"/docs/installation/docker-compose","Docker Compose",{"_path":47,"title":48},"/docs/installation/kubernetes","Kubernetes",{"_path":50,"title":51},"/docs/installation/autostart-windows","Autostart (Windows)",{"_path":53,"title":54},"/docs/installation/autostart-linux","Autostart (Linux)",{"_path":56,"title":57},"/docs/installation/autostart-macos","Autostart (MacOS)",{"_path":59,"title":60},"/docs/installation/behind-proxy","HTTP proxy configuration",{"_path":62,"title":63},"/docs/mcp","MCP Server",{"_path":65,"title":66},"/docs/outbound","Outbound Gateway: send webhooks to your customers",{"_path":68,"title":69},"/docs/outbound/setup","Set up the Outbound Gateway",{"_path":71,"title":72},"/docs/outbound/receiving","Receive and verify outbound webhooks",{"_path":74,"title":75},"/docs/outbound/operating","Monitor, retry and recover deliveries",{"_path":77,"title":78},"/docs/security","Security & Tech",{"_path":80,"title":81},"/docs/service-connections","Service Connections",{"_path":83,"title":84},"/docs/service-connections/ai-providers","AI provider connections",{"_path":86,"title":87},"/docs/service-connections/aws_s3","AWS S3",{"_path":89,"title":90},"/docs/service-connections/aws_sns","AWS SNS",{"_path":92,"title":93},"/docs/service-connections/aws_sqs","AWS SQS",{"_path":95,"title":96},"/docs/service-connections/azure","Azure",{"_path":98,"title":99},"/docs/service-connections/gcp_gcs","GCP Cloud Storage",{"_path":101,"title":102},"/docs/service-connections/gcp_pubsub","GCP Pub/Sub",{"_path":104,"title":105},"/docs/service-connections/secrets","Secrets",{"_path":107,"title":108},"/docs/skills","Agent Skills",{"_path":110,"title":111},"/docs/skills-cli","skills.sh — the Agent Skills CLI",{"_path":113,"title":114},"/docs/tunnels/demoing-your-website","Demoing your website",{"_path":116,"title":117},"/docs/tunnels/regions","Regions",{"_path":119,"title":120},"/docs/tutorials/cicd/jenkins-bitbucket","Jenkins and Bitbucket",{"_path":122,"title":123},"/docs/tutorials/cicd/jenkins-github","Jenkins and GitHub",{"_path":125,"title":126},"/docs/tutorials/cicd/jenkins-plugin","Jenkins Plugin",{"_path":128,"title":129},"/docs/tutorials/cicd/jenkins-plugin-multibranch","Jenkins Multibranch Pipelines",{"_path":131,"title":132},"/docs/tutorials/cicd/kubernetes-operator","Kubernetes Operator",{"_path":134,"title":135},"/docs/tutorials/cicd/terraform-atlantis","Terraform Atlantis",{"_path":137,"title":138},"/docs/tutorials/cicd/webhook-exec","Execute scripts on webhook",{"_path":140,"title":141},"/docs/tutorials/edge/home-assistant","Home Assistant",{"_path":143,"title":144},"/docs/tutorials/edge/javascript-app","JavaScript app",{"_path":146,"title":147},"/docs/tutorials/edge/node-red","Node-RED",{"_path":149,"title":150},"/docs/tutorials/email/airtable","Email to Airtable",{"_path":152,"title":153},"/docs/tutorials/email/api","Email to API",{"_path":155,"title":156},"/docs/tutorials/email/database","Email to Database",{"_path":158,"title":159},"/docs/tutorials/email/discord","Email to Discord",{"_path":161,"title":162},"/docs/tutorials/email/google-sheets","Email to Google Sheets",{"_path":164,"title":165},"/docs/tutorials/email/microsoft-teams","Email to Microsoft Teams",{"_path":167,"title":168},"/docs/tutorials/email/notion","Email to Notion",{"_path":170,"title":171},"/docs/tutorials/email/slack","Email to Slack",{"_path":173,"title":174},"/docs/tutorials","Tutorials",{"_path":176,"title":177},"/docs/tutorials/n8n/email-trigger","n8n Email Trigger (Inbound Email)",{"_path":179,"title":180},"/docs/tutorials/n8n/webhook-trigger","n8n Webhook Trigger (No Public IP)",{"_path":182,"title":183},"/docs/tutorials/n8n/whatsapp-cloud-api-webhook","n8n WhatsApp Cloud API Webhook Setup",{"_path":185,"title":186},"/docs/tutorials/transform/docker-to-slack","DockerHub webhook to Slack notification",{"_path":188,"title":189},"/docs/tutorials/transform/enrich-webhooks","Enrich webhooks from APIs",{"_path":191,"title":192},"/docs/tutorials/transform/stripe-to-plain","Sync Stripe subscriptions to Plain.com tenants",{"_path":194,"title":195},"/docs/tutorials/warehouse/bigquery","GCP BigQuery",{"_path":197,"title":198},"/docs/webhooks/alerts","Alerts",{"_path":200,"title":201},"/docs/webhooks/auth/username-password","Username and password",{"_path":203,"title":204},"/docs/webhooks/auth/hmac","HMAC",{"_path":206,"title":207},"/docs/webhooks/auth/jwt","JWT authentication",{"_path":209,"title":210},"/docs/webhooks/auth/http-method","Auth using request method",{"_path":212,"title":213},"/docs/webhooks/cors","CORS for webhooks",{"_path":215,"title":216},"/docs/webhooks/cron/using-cron-webhooks","Schedule recurring webhooks",{"_path":218,"title":219},"/docs/webhooks/custom-domains","Custom webhook domains",{"_path":221,"title":222},"/docs/webhooks/custom-subdomains","Custom webhook subdomains",{"_path":224,"title":225},"/docs/webhooks/custom-webhook-response","Custom response to webhooks",{"_path":227,"title":228},"/docs/webhooks/durable-webhooks","Durable webhooks: reliable delivery with automatic retries",{"_path":230,"title":231},"/docs/webhooks/functions/manipulating-json","JSON encoding",{"_path":233,"title":234},"/docs/webhooks/functions/make-http-request","Make HTTP request",{"_path":236,"title":237},"/docs/webhooks/functions/modify-request","Modify webhook headers, body, method and path",{"_path":239,"title":240},"/docs/webhooks/functions/multipart-form-data","Multipart form to JSON",{"_path":242,"title":243},"/docs/webhooks/functions/url-encoded-data","URL Encoded Form",{"_path":245,"title":246},"/docs/webhooks/functions/working-with-time","Working with time",{"_path":248,"title":249},"/docs/webhooks/functions/send-emails","Sending emails",{"_path":251,"title":252},"/docs/webhooks/functions/crypto-functions","Base64, encryption",{"_path":254,"title":255},"/docs/webhooks/functions/integrate-into-cicd","Integrating into CI/CD",{"_path":257,"title":195},"/docs/webhooks/functions/big-query",{"_path":259,"title":260},"/docs/webhooks/functions/accessing-metadata","Accessing metadata",{"_path":262,"title":263},"/docs/webhooks/functions/response-functions","Response (post-delivery) functions",{"_path":265,"title":266},"/docs/webhooks/functions/alerting","Alerting from functions",{"_path":268,"title":269},"/docs/webhooks/functions/helper-libraries","Helper libraries",{"_path":271,"title":272},"/docs/webhooks/functions/transform-webhook-payload","Transform a webhook payload",{"_path":274,"title":275},"/docs/webhooks/functions/filter-webhooks","Filter or drop webhooks before forwarding",{"_path":277,"title":278},"/docs/webhooks/functions/provider-helpers","Provider-aware function helpers",{"_path":280,"title":281},"/docs/webhooks/functions","Webhook transformations (functions): modify body, headers, method and path",{"_path":283,"title":284},"/docs/webhooks/internal/localhost","Receive webhooks on localhost with the relay CLI",{"_path":286,"title":287},"/docs/webhooks/large-webhooks","Large Webhooks",{"_path":289,"title":290},"/docs/webhooks/outbound-throttling","Outbound throttling: control webhook delivery speed",{"_path":292,"title":293},"/docs/webhooks/polling-webhooks","Polling webhooks with /v1/events",{"_path":295,"title":296},"/docs/webhooks/public/public-destination","Forward to public URL",{"_path":298,"title":299},"/docs/webhooks/public/multiple-destination-urls","Forward webhooks to multiple destinations",{"_path":301,"title":302},"/docs/webhooks/replay-on-agent-connect","Webhook replay on agent connect: recover missed webhooks",{"_path":304,"title":305},"/docs/webhooks/static-ip-address","Static IP Address",{"_path":307,"title":308},"/docs/webhooks/tls-ssl-errors","Fix TLS/SSL handshake errors: unsupported protocol, wrong version number, handshake failure",{"_path":310,"title":311},"/docs/webhooks/websocket-server","Connecting to websocket server",{"_path":313,"title":314},"/docs/webhooks/zero-retention-buckets","Zero Retention Buckets",{"_path":71,"_dir":316,"_draft":317,"_partial":317,"_locale":318,"title":72,"description":319,"intro":320,"layout":321,"tags":322,"faq":328,"body":341,"_type":3617,"_id":3618,"_source":3619,"_file":3620,"_stem":3621,"_extension":3622,"sitemap":3623},"outbound",false,"","What your customers' endpoints receive from the Webhook Relay Outbound Gateway: Standard Webhooks headers, signature verification in Node.js and Go, deduplication on webhook-id, retries, endpoint states and secret rotation.","Every Outbound Gateway delivery is a signed JSON POST that follows the Standard Webhooks specification. Receivers verify the signature, deduplicate on webhook-id and answer with a 2xx status quickly.","doc",[323,324,325,326,327],"Outbound webhooks","Standard Webhooks","Webhook signature verification","Idempotency","Webhook retries",[329,332,335,338],{"q":330,"a":331},"How do I verify an Outbound Gateway webhook signature?","Compute HMAC-SHA256 over '{webhook-id}.{webhook-timestamp}.{raw body}' using the base64-decoded part of the endpoint secret after 'whsec_' as the key. Base64-encode the result and compare it in constant time with each 'v1,\u003Csignature>' entry in the webhook-signature header. Any Standard Webhooks library does the same.",{"q":333,"a":334},"Can the same webhook be delivered more than once?","Yes. Delivery is at least once: a retry after a timeout, a manual retry or a recovery replay can deliver a message again. Every copy carries the same webhook-id header, so receivers should store processed webhook-id values and skip repeats.",{"q":336,"a":337},"How long does Webhook Relay retry a failed outbound webhook?","A delivery is retried after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours, for up to eight attempts within 48 hours of publication. Any 2xx response is a success. A 429 or 503 response's Retry-After header (up to one hour) delays the next attempt. 410 Gone stops retrying and disables the endpoint.",{"q":339,"a":340},"What happens to signatures when a signing secret is rotated?","For 24 hours after a rotation, every delivery is signed with both the new and the previous secret, so the webhook-signature header carries two signatures. Receivers that accept any matching signature keep working while they switch to the new secret.",{"type":342,"children":343,"toc":3605},"root",[344,393,400,503,631,644,650,701,706,713,1667,1672,1921,1927,3033,3054,3065,3091,3096,3102,3245,3280,3286,3428,3448,3460,3466,3499,3580,3599],{"type":345,"tag":346,"props":347,"children":348},"element","p",{},[349,375,377,383,385,391],{"type":345,"tag":350,"props":351,"children":352},"strong",{},[353,356,363,365,373],{"type":354,"value":355},"text","Each Outbound Gateway delivery is an HTTPS ",{"type":345,"tag":357,"props":358,"children":360},"code",{"className":359},[],[361],{"type":354,"value":362},"POST",{"type":354,"value":364}," with a JSON body, signed using the ",{"type":345,"tag":366,"props":367,"children":371},"a",{"href":368,"rel":369},"https://www.standardwebhooks.com/",[370],"nofollow",[372],{"type":354,"value":324},{"type":354,"value":374}," scheme.",{"type":354,"value":376}," The receiving endpoint verifies the signature against the raw body, deduplicates on ",{"type":345,"tag":357,"props":378,"children":380},{"className":379},[],[381],{"type":354,"value":382},"webhook-id",{"type":354,"value":384},", and responds with any ",{"type":345,"tag":357,"props":386,"children":388},{"className":387},[],[389],{"type":354,"value":390},"2xx",{"type":354,"value":392}," status within the endpoint timeout (15 seconds by default). Share this page with your customers along with their endpoint's signing secret.",{"type":345,"tag":394,"props":395,"children":397},"h2",{"id":396},"what-a-delivery-looks-like",[398],{"type":354,"value":399},"What a delivery looks like",{"type":345,"tag":401,"props":402,"children":406},"pre",{"className":403,"code":404,"language":405,"meta":318,"style":318},"language-http shiki shiki-themes github-dark","POST /webhooks HTTP/1.1\nHost: acme.example\nContent-Type: application/json\nwebhook-id: 0199cf5e-7a3c-7d2e-9b1a-3f4e5d6c7b8a\nwebhook-timestamp: 1791626714\nwebhook-signature: v1,6UwV1HPN4tp13ssBSQEu7mdFW217e42pcT32bZjJlyc=\nwebhook-event-type: invoice.paid\nwebhook-consumer: customer_42\n\n{\"invoice_id\":\"inv_123\",\"amount\":4900}\n","http",[407],{"type":345,"tag":357,"props":408,"children":409},{"__ignoreMap":318},[410,421,430,439,448,457,466,475,484,494],{"type":345,"tag":411,"props":412,"children":415},"span",{"class":413,"line":414},"line",1,[416],{"type":345,"tag":411,"props":417,"children":418},{},[419],{"type":354,"value":420},"POST /webhooks HTTP/1.1\n",{"type":345,"tag":411,"props":422,"children":424},{"class":413,"line":423},2,[425],{"type":345,"tag":411,"props":426,"children":427},{},[428],{"type":354,"value":429},"Host: acme.example\n",{"type":345,"tag":411,"props":431,"children":433},{"class":413,"line":432},3,[434],{"type":345,"tag":411,"props":435,"children":436},{},[437],{"type":354,"value":438},"Content-Type: application/json\n",{"type":345,"tag":411,"props":440,"children":442},{"class":413,"line":441},4,[443],{"type":345,"tag":411,"props":444,"children":445},{},[446],{"type":354,"value":447},"webhook-id: 0199cf5e-7a3c-7d2e-9b1a-3f4e5d6c7b8a\n",{"type":345,"tag":411,"props":449,"children":451},{"class":413,"line":450},5,[452],{"type":345,"tag":411,"props":453,"children":454},{},[455],{"type":354,"value":456},"webhook-timestamp: 1791626714\n",{"type":345,"tag":411,"props":458,"children":460},{"class":413,"line":459},6,[461],{"type":345,"tag":411,"props":462,"children":463},{},[464],{"type":354,"value":465},"webhook-signature: v1,6UwV1HPN4tp13ssBSQEu7mdFW217e42pcT32bZjJlyc=\n",{"type":345,"tag":411,"props":467,"children":469},{"class":413,"line":468},7,[470],{"type":345,"tag":411,"props":471,"children":472},{},[473],{"type":354,"value":474},"webhook-event-type: invoice.paid\n",{"type":345,"tag":411,"props":476,"children":478},{"class":413,"line":477},8,[479],{"type":345,"tag":411,"props":480,"children":481},{},[482],{"type":354,"value":483},"webhook-consumer: customer_42\n",{"type":345,"tag":411,"props":485,"children":487},{"class":413,"line":486},9,[488],{"type":345,"tag":411,"props":489,"children":491},{"emptyLinePlaceholder":490},true,[492],{"type":354,"value":493},"\n",{"type":345,"tag":411,"props":495,"children":497},{"class":413,"line":496},10,[498],{"type":345,"tag":411,"props":499,"children":500},{},[501],{"type":354,"value":502},"{\"invoice_id\":\"inv_123\",\"amount\":4900}\n",{"type":345,"tag":504,"props":505,"children":506},"table",{},[507,526],{"type":345,"tag":508,"props":509,"children":510},"thead",{},[511],{"type":345,"tag":512,"props":513,"children":514},"tr",{},[515,521],{"type":345,"tag":516,"props":517,"children":518},"th",{},[519],{"type":354,"value":520},"Header",{"type":345,"tag":516,"props":522,"children":523},{},[524],{"type":354,"value":525},"Value",{"type":345,"tag":527,"props":528,"children":529},"tbody",{},[530,547,564,589,614],{"type":345,"tag":512,"props":531,"children":532},{},[533,542],{"type":345,"tag":534,"props":535,"children":536},"td",{},[537],{"type":345,"tag":357,"props":538,"children":540},{"className":539},[],[541],{"type":354,"value":382},{"type":345,"tag":534,"props":543,"children":544},{},[545],{"type":354,"value":546},"The message ID. It is the same for every endpoint, every retry and every replay of the message.",{"type":345,"tag":512,"props":548,"children":549},{},[550,559],{"type":345,"tag":534,"props":551,"children":552},{},[553],{"type":345,"tag":357,"props":554,"children":556},{"className":555},[],[557],{"type":354,"value":558},"webhook-timestamp",{"type":345,"tag":534,"props":560,"children":561},{},[562],{"type":354,"value":563},"Unix time in seconds of this attempt. Each retry gets a new timestamp and a new signature.",{"type":345,"tag":512,"props":565,"children":566},{},[567,576],{"type":345,"tag":534,"props":568,"children":569},{},[570],{"type":345,"tag":357,"props":571,"children":573},{"className":572},[],[574],{"type":354,"value":575},"webhook-signature",{"type":345,"tag":534,"props":577,"children":578},{},[579,581,587],{"type":354,"value":580},"One or more space-separated ",{"type":345,"tag":357,"props":582,"children":584},{"className":583},[],[585],{"type":354,"value":586},"v1,\u003Cbase64 HMAC-SHA256>",{"type":354,"value":588}," signatures. There are two during a secret rotation.",{"type":345,"tag":512,"props":590,"children":591},{},[592,601],{"type":345,"tag":534,"props":593,"children":594},{},[595],{"type":345,"tag":357,"props":596,"children":598},{"className":597},[],[599],{"type":354,"value":600},"webhook-event-type",{"type":345,"tag":534,"props":602,"children":603},{},[604,606,612],{"type":354,"value":605},"The event type, such as ",{"type":345,"tag":357,"props":607,"children":609},{"className":608},[],[610],{"type":354,"value":611},"invoice.paid",{"type":354,"value":613},".",{"type":345,"tag":512,"props":615,"children":616},{},[617,626],{"type":345,"tag":534,"props":618,"children":619},{},[620],{"type":345,"tag":357,"props":621,"children":623},{"className":622},[],[624],{"type":354,"value":625},"webhook-consumer",{"type":345,"tag":534,"props":627,"children":628},{},[629],{"type":354,"value":630},"The consumer ID the endpoint belongs to.",{"type":345,"tag":346,"props":632,"children":633},{},[634,636,642],{"type":354,"value":635},"The body is the published JSON payload, or the output of the endpoint's ",{"type":345,"tag":366,"props":637,"children":639},{"href":638},"/docs/outbound/operating#transform-or-drop-payloads-with-functions",[640],{"type":354,"value":641},"Function",{"type":354,"value":643}," if it has one. Any custom headers configured on the endpoint are sent as well. Redirects are not followed.",{"type":345,"tag":394,"props":645,"children":647},{"id":646},"verify-the-signature",[648],{"type":354,"value":649},"Verify the signature",{"type":345,"tag":346,"props":651,"children":652},{},[653,655,661,663,669,671,676,678,684,686,692,694,699],{"type":354,"value":654},"The signed content is ",{"type":345,"tag":357,"props":656,"children":658},{"className":657},[],[659],{"type":354,"value":660},"{webhook-id}.{webhook-timestamp}.{body}",{"type":354,"value":662},", where ",{"type":345,"tag":357,"props":664,"children":666},{"className":665},[],[667],{"type":354,"value":668},"body",{"type":354,"value":670}," is the ",{"type":345,"tag":350,"props":672,"children":673},{},[674],{"type":354,"value":675},"exact raw bytes",{"type":354,"value":677}," received. The key is the base64-decoded part of the endpoint secret after the ",{"type":345,"tag":357,"props":679,"children":681},{"className":680},[],[682],{"type":354,"value":683},"whsec_",{"type":354,"value":685}," prefix. Compute HMAC-SHA256, base64-encode it, and compare it in constant time against each ",{"type":345,"tag":357,"props":687,"children":689},{"className":688},[],[690],{"type":354,"value":691},"v1,",{"type":354,"value":693}," entry in ",{"type":345,"tag":357,"props":695,"children":697},{"className":696},[],[698],{"type":354,"value":575},{"type":354,"value":700},". Also reject timestamps that are too far from the current time, so captured requests can't be replayed later.",{"type":345,"tag":346,"props":702,"children":703},{},[704],{"type":354,"value":705},"Parsing and re-serializing the JSON before verifying changes the bytes and breaks the signature. Read the raw body first.",{"type":345,"tag":707,"props":708,"children":710},"h3",{"id":709},"nodejs",[711],{"type":354,"value":712},"Node.js",{"type":345,"tag":714,"props":715,"children":716},"code-block",{},[717],{"type":345,"tag":401,"props":718,"children":722},{"className":719,"code":720,"language":721,"meta":318,"style":318},"language-js shiki shiki-themes github-dark","import crypto from \"node:crypto\";\n\n// rawBody: the exact bytes received (Buffer or string). secret: \"whsec_…\".\nexport function verifyWebhook(rawBody, headers, secret, toleranceSeconds = 300) {\n  const id = headers[\"webhook-id\"];\n  const timestamp = headers[\"webhook-timestamp\"];\n  const signatureHeader = headers[\"webhook-signature\"];\n  if (!id || !timestamp || !signatureHeader) return false;\n\n  // Reject old or future-dated timestamps to limit replay attacks.\n  const age = Math.abs(Date.now() / 1000 - Number(timestamp));\n  if (!Number.isFinite(age) || age > toleranceSeconds) return false;\n\n  const key = Buffer.from(secret.replace(/^whsec_/, \"\"), \"base64\");\n  const expected = crypto\n    .createHmac(\"sha256\", key)\n    .update(`${id}.${timestamp}.`)\n    .update(rawBody)\n    .digest();\n\n  // During a secret rotation the header carries two signatures: \"v1,\u003Ca> v1,\u003Cb>\".\n  return signatureHeader.split(\" \").some((entry) => {\n    const [version, signature] = entry.split(\",\");\n    if (version !== \"v1\" || !signature) return false;\n    const received = Buffer.from(signature, \"base64\");\n    return received.length === expected.length && crypto.timingSafeEqual(received, expected);\n  });\n}\n","js",[723],{"type":345,"tag":357,"props":724,"children":725},{"__ignoreMap":318},[726,757,764,773,847,879,908,937,1002,1009,1017,1084,1146,1154,1236,1258,1286,1333,1350,1368,1376,1385,1448,1508,1558,1596,1649,1658],{"type":345,"tag":411,"props":727,"children":728},{"class":413,"line":414},[729,735,741,746,752],{"type":345,"tag":411,"props":730,"children":732},{"style":731},"--shiki-default:#F97583",[733],{"type":354,"value":734},"import",{"type":345,"tag":411,"props":736,"children":738},{"style":737},"--shiki-default:#E1E4E8",[739],{"type":354,"value":740}," crypto ",{"type":345,"tag":411,"props":742,"children":743},{"style":731},[744],{"type":354,"value":745},"from",{"type":345,"tag":411,"props":747,"children":749},{"style":748},"--shiki-default:#9ECBFF",[750],{"type":354,"value":751}," \"node:crypto\"",{"type":345,"tag":411,"props":753,"children":754},{"style":737},[755],{"type":354,"value":756},";\n",{"type":345,"tag":411,"props":758,"children":759},{"class":413,"line":423},[760],{"type":345,"tag":411,"props":761,"children":762},{"emptyLinePlaceholder":490},[763],{"type":354,"value":493},{"type":345,"tag":411,"props":765,"children":766},{"class":413,"line":432},[767],{"type":345,"tag":411,"props":768,"children":770},{"style":769},"--shiki-default:#6A737D",[771],{"type":354,"value":772},"// rawBody: the exact bytes received (Buffer or string). secret: \"whsec_…\".\n",{"type":345,"tag":411,"props":774,"children":775},{"class":413,"line":441},[776,781,786,792,797,803,808,813,817,822,826,831,836,842],{"type":345,"tag":411,"props":777,"children":778},{"style":731},[779],{"type":354,"value":780},"export",{"type":345,"tag":411,"props":782,"children":783},{"style":731},[784],{"type":354,"value":785}," function",{"type":345,"tag":411,"props":787,"children":789},{"style":788},"--shiki-default:#B392F0",[790],{"type":354,"value":791}," verifyWebhook",{"type":345,"tag":411,"props":793,"children":794},{"style":737},[795],{"type":354,"value":796},"(",{"type":345,"tag":411,"props":798,"children":800},{"style":799},"--shiki-default:#FFAB70",[801],{"type":354,"value":802},"rawBody",{"type":345,"tag":411,"props":804,"children":805},{"style":737},[806],{"type":354,"value":807},", ",{"type":345,"tag":411,"props":809,"children":810},{"style":799},[811],{"type":354,"value":812},"headers",{"type":345,"tag":411,"props":814,"children":815},{"style":737},[816],{"type":354,"value":807},{"type":345,"tag":411,"props":818,"children":819},{"style":799},[820],{"type":354,"value":821},"secret",{"type":345,"tag":411,"props":823,"children":824},{"style":737},[825],{"type":354,"value":807},{"type":345,"tag":411,"props":827,"children":828},{"style":799},[829],{"type":354,"value":830},"toleranceSeconds",{"type":345,"tag":411,"props":832,"children":833},{"style":731},[834],{"type":354,"value":835}," =",{"type":345,"tag":411,"props":837,"children":839},{"style":838},"--shiki-default:#79B8FF",[840],{"type":354,"value":841}," 300",{"type":345,"tag":411,"props":843,"children":844},{"style":737},[845],{"type":354,"value":846},") {\n",{"type":345,"tag":411,"props":848,"children":849},{"class":413,"line":450},[850,855,860,864,869,874],{"type":345,"tag":411,"props":851,"children":852},{"style":731},[853],{"type":354,"value":854},"  const",{"type":345,"tag":411,"props":856,"children":857},{"style":838},[858],{"type":354,"value":859}," id",{"type":345,"tag":411,"props":861,"children":862},{"style":731},[863],{"type":354,"value":835},{"type":345,"tag":411,"props":865,"children":866},{"style":737},[867],{"type":354,"value":868}," headers[",{"type":345,"tag":411,"props":870,"children":871},{"style":748},[872],{"type":354,"value":873},"\"webhook-id\"",{"type":345,"tag":411,"props":875,"children":876},{"style":737},[877],{"type":354,"value":878},"];\n",{"type":345,"tag":411,"props":880,"children":881},{"class":413,"line":459},[882,886,891,895,899,904],{"type":345,"tag":411,"props":883,"children":884},{"style":731},[885],{"type":354,"value":854},{"type":345,"tag":411,"props":887,"children":888},{"style":838},[889],{"type":354,"value":890}," timestamp",{"type":345,"tag":411,"props":892,"children":893},{"style":731},[894],{"type":354,"value":835},{"type":345,"tag":411,"props":896,"children":897},{"style":737},[898],{"type":354,"value":868},{"type":345,"tag":411,"props":900,"children":901},{"style":748},[902],{"type":354,"value":903},"\"webhook-timestamp\"",{"type":345,"tag":411,"props":905,"children":906},{"style":737},[907],{"type":354,"value":878},{"type":345,"tag":411,"props":909,"children":910},{"class":413,"line":468},[911,915,920,924,928,933],{"type":345,"tag":411,"props":912,"children":913},{"style":731},[914],{"type":354,"value":854},{"type":345,"tag":411,"props":916,"children":917},{"style":838},[918],{"type":354,"value":919}," signatureHeader",{"type":345,"tag":411,"props":921,"children":922},{"style":731},[923],{"type":354,"value":835},{"type":345,"tag":411,"props":925,"children":926},{"style":737},[927],{"type":354,"value":868},{"type":345,"tag":411,"props":929,"children":930},{"style":748},[931],{"type":354,"value":932},"\"webhook-signature\"",{"type":345,"tag":411,"props":934,"children":935},{"style":737},[936],{"type":354,"value":878},{"type":345,"tag":411,"props":938,"children":939},{"class":413,"line":477},[940,945,950,955,960,965,970,975,979,983,988,993,998],{"type":345,"tag":411,"props":941,"children":942},{"style":731},[943],{"type":354,"value":944},"  if",{"type":345,"tag":411,"props":946,"children":947},{"style":737},[948],{"type":354,"value":949}," (",{"type":345,"tag":411,"props":951,"children":952},{"style":731},[953],{"type":354,"value":954},"!",{"type":345,"tag":411,"props":956,"children":957},{"style":737},[958],{"type":354,"value":959},"id ",{"type":345,"tag":411,"props":961,"children":962},{"style":731},[963],{"type":354,"value":964},"||",{"type":345,"tag":411,"props":966,"children":967},{"style":731},[968],{"type":354,"value":969}," !",{"type":345,"tag":411,"props":971,"children":972},{"style":737},[973],{"type":354,"value":974},"timestamp ",{"type":345,"tag":411,"props":976,"children":977},{"style":731},[978],{"type":354,"value":964},{"type":345,"tag":411,"props":980,"children":981},{"style":731},[982],{"type":354,"value":969},{"type":345,"tag":411,"props":984,"children":985},{"style":737},[986],{"type":354,"value":987},"signatureHeader) ",{"type":345,"tag":411,"props":989,"children":990},{"style":731},[991],{"type":354,"value":992},"return",{"type":345,"tag":411,"props":994,"children":995},{"style":838},[996],{"type":354,"value":997}," false",{"type":345,"tag":411,"props":999,"children":1000},{"style":737},[1001],{"type":354,"value":756},{"type":345,"tag":411,"props":1003,"children":1004},{"class":413,"line":486},[1005],{"type":345,"tag":411,"props":1006,"children":1007},{"emptyLinePlaceholder":490},[1008],{"type":354,"value":493},{"type":345,"tag":411,"props":1010,"children":1011},{"class":413,"line":496},[1012],{"type":345,"tag":411,"props":1013,"children":1014},{"style":769},[1015],{"type":354,"value":1016},"  // Reject old or future-dated timestamps to limit replay attacks.\n",{"type":345,"tag":411,"props":1018,"children":1020},{"class":413,"line":1019},11,[1021,1025,1030,1034,1039,1044,1049,1054,1059,1064,1069,1074,1079],{"type":345,"tag":411,"props":1022,"children":1023},{"style":731},[1024],{"type":354,"value":854},{"type":345,"tag":411,"props":1026,"children":1027},{"style":838},[1028],{"type":354,"value":1029}," age",{"type":345,"tag":411,"props":1031,"children":1032},{"style":731},[1033],{"type":354,"value":835},{"type":345,"tag":411,"props":1035,"children":1036},{"style":737},[1037],{"type":354,"value":1038}," Math.",{"type":345,"tag":411,"props":1040,"children":1041},{"style":788},[1042],{"type":354,"value":1043},"abs",{"type":345,"tag":411,"props":1045,"children":1046},{"style":737},[1047],{"type":354,"value":1048},"(Date.",{"type":345,"tag":411,"props":1050,"children":1051},{"style":788},[1052],{"type":354,"value":1053},"now",{"type":345,"tag":411,"props":1055,"children":1056},{"style":737},[1057],{"type":354,"value":1058},"() ",{"type":345,"tag":411,"props":1060,"children":1061},{"style":731},[1062],{"type":354,"value":1063},"/",{"type":345,"tag":411,"props":1065,"children":1066},{"style":838},[1067],{"type":354,"value":1068}," 1000",{"type":345,"tag":411,"props":1070,"children":1071},{"style":731},[1072],{"type":354,"value":1073}," -",{"type":345,"tag":411,"props":1075,"children":1076},{"style":788},[1077],{"type":354,"value":1078}," Number",{"type":345,"tag":411,"props":1080,"children":1081},{"style":737},[1082],{"type":354,"value":1083},"(timestamp));\n",{"type":345,"tag":411,"props":1085,"children":1087},{"class":413,"line":1086},12,[1088,1092,1096,1100,1105,1110,1115,1119,1124,1129,1134,1138,1142],{"type":345,"tag":411,"props":1089,"children":1090},{"style":731},[1091],{"type":354,"value":944},{"type":345,"tag":411,"props":1093,"children":1094},{"style":737},[1095],{"type":354,"value":949},{"type":345,"tag":411,"props":1097,"children":1098},{"style":731},[1099],{"type":354,"value":954},{"type":345,"tag":411,"props":1101,"children":1102},{"style":737},[1103],{"type":354,"value":1104},"Number.",{"type":345,"tag":411,"props":1106,"children":1107},{"style":788},[1108],{"type":354,"value":1109},"isFinite",{"type":345,"tag":411,"props":1111,"children":1112},{"style":737},[1113],{"type":354,"value":1114},"(age) ",{"type":345,"tag":411,"props":1116,"children":1117},{"style":731},[1118],{"type":354,"value":964},{"type":345,"tag":411,"props":1120,"children":1121},{"style":737},[1122],{"type":354,"value":1123}," age ",{"type":345,"tag":411,"props":1125,"children":1126},{"style":731},[1127],{"type":354,"value":1128},">",{"type":345,"tag":411,"props":1130,"children":1131},{"style":737},[1132],{"type":354,"value":1133}," toleranceSeconds) ",{"type":345,"tag":411,"props":1135,"children":1136},{"style":731},[1137],{"type":354,"value":992},{"type":345,"tag":411,"props":1139,"children":1140},{"style":838},[1141],{"type":354,"value":997},{"type":345,"tag":411,"props":1143,"children":1144},{"style":737},[1145],{"type":354,"value":756},{"type":345,"tag":411,"props":1147,"children":1149},{"class":413,"line":1148},13,[1150],{"type":345,"tag":411,"props":1151,"children":1152},{"emptyLinePlaceholder":490},[1153],{"type":354,"value":493},{"type":345,"tag":411,"props":1155,"children":1157},{"class":413,"line":1156},14,[1158,1162,1167,1171,1176,1180,1185,1190,1194,1198,1203,1208,1212,1216,1221,1226,1231],{"type":345,"tag":411,"props":1159,"children":1160},{"style":731},[1161],{"type":354,"value":854},{"type":345,"tag":411,"props":1163,"children":1164},{"style":838},[1165],{"type":354,"value":1166}," key",{"type":345,"tag":411,"props":1168,"children":1169},{"style":731},[1170],{"type":354,"value":835},{"type":345,"tag":411,"props":1172,"children":1173},{"style":737},[1174],{"type":354,"value":1175}," Buffer.",{"type":345,"tag":411,"props":1177,"children":1178},{"style":788},[1179],{"type":354,"value":745},{"type":345,"tag":411,"props":1181,"children":1182},{"style":737},[1183],{"type":354,"value":1184},"(secret.",{"type":345,"tag":411,"props":1186,"children":1187},{"style":788},[1188],{"type":354,"value":1189},"replace",{"type":345,"tag":411,"props":1191,"children":1192},{"style":737},[1193],{"type":354,"value":796},{"type":345,"tag":411,"props":1195,"children":1196},{"style":748},[1197],{"type":354,"value":1063},{"type":345,"tag":411,"props":1199,"children":1200},{"style":731},[1201],{"type":354,"value":1202},"^",{"type":345,"tag":411,"props":1204,"children":1206},{"style":1205},"--shiki-default:#DBEDFF",[1207],{"type":354,"value":683},{"type":345,"tag":411,"props":1209,"children":1210},{"style":748},[1211],{"type":354,"value":1063},{"type":345,"tag":411,"props":1213,"children":1214},{"style":737},[1215],{"type":354,"value":807},{"type":345,"tag":411,"props":1217,"children":1218},{"style":748},[1219],{"type":354,"value":1220},"\"\"",{"type":345,"tag":411,"props":1222,"children":1223},{"style":737},[1224],{"type":354,"value":1225},"), ",{"type":345,"tag":411,"props":1227,"children":1228},{"style":748},[1229],{"type":354,"value":1230},"\"base64\"",{"type":345,"tag":411,"props":1232,"children":1233},{"style":737},[1234],{"type":354,"value":1235},");\n",{"type":345,"tag":411,"props":1237,"children":1239},{"class":413,"line":1238},15,[1240,1244,1249,1253],{"type":345,"tag":411,"props":1241,"children":1242},{"style":731},[1243],{"type":354,"value":854},{"type":345,"tag":411,"props":1245,"children":1246},{"style":838},[1247],{"type":354,"value":1248}," expected",{"type":345,"tag":411,"props":1250,"children":1251},{"style":731},[1252],{"type":354,"value":835},{"type":345,"tag":411,"props":1254,"children":1255},{"style":737},[1256],{"type":354,"value":1257}," crypto\n",{"type":345,"tag":411,"props":1259,"children":1261},{"class":413,"line":1260},16,[1262,1267,1272,1276,1281],{"type":345,"tag":411,"props":1263,"children":1264},{"style":737},[1265],{"type":354,"value":1266},"    .",{"type":345,"tag":411,"props":1268,"children":1269},{"style":788},[1270],{"type":354,"value":1271},"createHmac",{"type":345,"tag":411,"props":1273,"children":1274},{"style":737},[1275],{"type":354,"value":796},{"type":345,"tag":411,"props":1277,"children":1278},{"style":748},[1279],{"type":354,"value":1280},"\"sha256\"",{"type":345,"tag":411,"props":1282,"children":1283},{"style":737},[1284],{"type":354,"value":1285},", key)\n",{"type":345,"tag":411,"props":1287,"children":1289},{"class":413,"line":1288},17,[1290,1294,1299,1303,1308,1313,1318,1323,1328],{"type":345,"tag":411,"props":1291,"children":1292},{"style":737},[1293],{"type":354,"value":1266},{"type":345,"tag":411,"props":1295,"children":1296},{"style":788},[1297],{"type":354,"value":1298},"update",{"type":345,"tag":411,"props":1300,"children":1301},{"style":737},[1302],{"type":354,"value":796},{"type":345,"tag":411,"props":1304,"children":1305},{"style":748},[1306],{"type":354,"value":1307},"`${",{"type":345,"tag":411,"props":1309,"children":1310},{"style":737},[1311],{"type":354,"value":1312},"id",{"type":345,"tag":411,"props":1314,"children":1315},{"style":748},[1316],{"type":354,"value":1317},"}.${",{"type":345,"tag":411,"props":1319,"children":1320},{"style":737},[1321],{"type":354,"value":1322},"timestamp",{"type":345,"tag":411,"props":1324,"children":1325},{"style":748},[1326],{"type":354,"value":1327},"}.`",{"type":345,"tag":411,"props":1329,"children":1330},{"style":737},[1331],{"type":354,"value":1332},")\n",{"type":345,"tag":411,"props":1334,"children":1336},{"class":413,"line":1335},18,[1337,1341,1345],{"type":345,"tag":411,"props":1338,"children":1339},{"style":737},[1340],{"type":354,"value":1266},{"type":345,"tag":411,"props":1342,"children":1343},{"style":788},[1344],{"type":354,"value":1298},{"type":345,"tag":411,"props":1346,"children":1347},{"style":737},[1348],{"type":354,"value":1349},"(rawBody)\n",{"type":345,"tag":411,"props":1351,"children":1353},{"class":413,"line":1352},19,[1354,1358,1363],{"type":345,"tag":411,"props":1355,"children":1356},{"style":737},[1357],{"type":354,"value":1266},{"type":345,"tag":411,"props":1359,"children":1360},{"style":788},[1361],{"type":354,"value":1362},"digest",{"type":345,"tag":411,"props":1364,"children":1365},{"style":737},[1366],{"type":354,"value":1367},"();\n",{"type":345,"tag":411,"props":1369,"children":1371},{"class":413,"line":1370},20,[1372],{"type":345,"tag":411,"props":1373,"children":1374},{"emptyLinePlaceholder":490},[1375],{"type":354,"value":493},{"type":345,"tag":411,"props":1377,"children":1379},{"class":413,"line":1378},21,[1380],{"type":345,"tag":411,"props":1381,"children":1382},{"style":769},[1383],{"type":354,"value":1384},"  // During a secret rotation the header carries two signatures: \"v1,\u003Ca> v1,\u003Cb>\".\n",{"type":345,"tag":411,"props":1386,"children":1388},{"class":413,"line":1387},22,[1389,1394,1399,1404,1408,1413,1418,1423,1428,1433,1438,1443],{"type":345,"tag":411,"props":1390,"children":1391},{"style":731},[1392],{"type":354,"value":1393},"  return",{"type":345,"tag":411,"props":1395,"children":1396},{"style":737},[1397],{"type":354,"value":1398}," signatureHeader.",{"type":345,"tag":411,"props":1400,"children":1401},{"style":788},[1402],{"type":354,"value":1403},"split",{"type":345,"tag":411,"props":1405,"children":1406},{"style":737},[1407],{"type":354,"value":796},{"type":345,"tag":411,"props":1409,"children":1410},{"style":748},[1411],{"type":354,"value":1412},"\" \"",{"type":345,"tag":411,"props":1414,"children":1415},{"style":737},[1416],{"type":354,"value":1417},").",{"type":345,"tag":411,"props":1419,"children":1420},{"style":788},[1421],{"type":354,"value":1422},"some",{"type":345,"tag":411,"props":1424,"children":1425},{"style":737},[1426],{"type":354,"value":1427},"((",{"type":345,"tag":411,"props":1429,"children":1430},{"style":799},[1431],{"type":354,"value":1432},"entry",{"type":345,"tag":411,"props":1434,"children":1435},{"style":737},[1436],{"type":354,"value":1437},") ",{"type":345,"tag":411,"props":1439,"children":1440},{"style":731},[1441],{"type":354,"value":1442},"=>",{"type":345,"tag":411,"props":1444,"children":1445},{"style":737},[1446],{"type":354,"value":1447}," {\n",{"type":345,"tag":411,"props":1449,"children":1451},{"class":413,"line":1450},23,[1452,1457,1462,1467,1471,1476,1481,1486,1491,1495,1499,1504],{"type":345,"tag":411,"props":1453,"children":1454},{"style":731},[1455],{"type":354,"value":1456},"    const",{"type":345,"tag":411,"props":1458,"children":1459},{"style":737},[1460],{"type":354,"value":1461}," [",{"type":345,"tag":411,"props":1463,"children":1464},{"style":838},[1465],{"type":354,"value":1466},"version",{"type":345,"tag":411,"props":1468,"children":1469},{"style":737},[1470],{"type":354,"value":807},{"type":345,"tag":411,"props":1472,"children":1473},{"style":838},[1474],{"type":354,"value":1475},"signature",{"type":345,"tag":411,"props":1477,"children":1478},{"style":737},[1479],{"type":354,"value":1480},"] ",{"type":345,"tag":411,"props":1482,"children":1483},{"style":731},[1484],{"type":354,"value":1485},"=",{"type":345,"tag":411,"props":1487,"children":1488},{"style":737},[1489],{"type":354,"value":1490}," entry.",{"type":345,"tag":411,"props":1492,"children":1493},{"style":788},[1494],{"type":354,"value":1403},{"type":345,"tag":411,"props":1496,"children":1497},{"style":737},[1498],{"type":354,"value":796},{"type":345,"tag":411,"props":1500,"children":1501},{"style":748},[1502],{"type":354,"value":1503},"\",\"",{"type":345,"tag":411,"props":1505,"children":1506},{"style":737},[1507],{"type":354,"value":1235},{"type":345,"tag":411,"props":1509,"children":1511},{"class":413,"line":1510},24,[1512,1517,1522,1527,1532,1537,1541,1546,1550,1554],{"type":345,"tag":411,"props":1513,"children":1514},{"style":731},[1515],{"type":354,"value":1516},"    if",{"type":345,"tag":411,"props":1518,"children":1519},{"style":737},[1520],{"type":354,"value":1521}," (version ",{"type":345,"tag":411,"props":1523,"children":1524},{"style":731},[1525],{"type":354,"value":1526},"!==",{"type":345,"tag":411,"props":1528,"children":1529},{"style":748},[1530],{"type":354,"value":1531}," \"v1\"",{"type":345,"tag":411,"props":1533,"children":1534},{"style":731},[1535],{"type":354,"value":1536}," ||",{"type":345,"tag":411,"props":1538,"children":1539},{"style":731},[1540],{"type":354,"value":969},{"type":345,"tag":411,"props":1542,"children":1543},{"style":737},[1544],{"type":354,"value":1545},"signature) ",{"type":345,"tag":411,"props":1547,"children":1548},{"style":731},[1549],{"type":354,"value":992},{"type":345,"tag":411,"props":1551,"children":1552},{"style":838},[1553],{"type":354,"value":997},{"type":345,"tag":411,"props":1555,"children":1556},{"style":737},[1557],{"type":354,"value":756},{"type":345,"tag":411,"props":1559,"children":1561},{"class":413,"line":1560},25,[1562,1566,1571,1575,1579,1583,1588,1592],{"type":345,"tag":411,"props":1563,"children":1564},{"style":731},[1565],{"type":354,"value":1456},{"type":345,"tag":411,"props":1567,"children":1568},{"style":838},[1569],{"type":354,"value":1570}," received",{"type":345,"tag":411,"props":1572,"children":1573},{"style":731},[1574],{"type":354,"value":835},{"type":345,"tag":411,"props":1576,"children":1577},{"style":737},[1578],{"type":354,"value":1175},{"type":345,"tag":411,"props":1580,"children":1581},{"style":788},[1582],{"type":354,"value":745},{"type":345,"tag":411,"props":1584,"children":1585},{"style":737},[1586],{"type":354,"value":1587},"(signature, ",{"type":345,"tag":411,"props":1589,"children":1590},{"style":748},[1591],{"type":354,"value":1230},{"type":345,"tag":411,"props":1593,"children":1594},{"style":737},[1595],{"type":354,"value":1235},{"type":345,"tag":411,"props":1597,"children":1599},{"class":413,"line":1598},26,[1600,1605,1610,1615,1620,1625,1629,1634,1639,1644],{"type":345,"tag":411,"props":1601,"children":1602},{"style":731},[1603],{"type":354,"value":1604},"    return",{"type":345,"tag":411,"props":1606,"children":1607},{"style":737},[1608],{"type":354,"value":1609}," received.",{"type":345,"tag":411,"props":1611,"children":1612},{"style":838},[1613],{"type":354,"value":1614},"length",{"type":345,"tag":411,"props":1616,"children":1617},{"style":731},[1618],{"type":354,"value":1619}," ===",{"type":345,"tag":411,"props":1621,"children":1622},{"style":737},[1623],{"type":354,"value":1624}," expected.",{"type":345,"tag":411,"props":1626,"children":1627},{"style":838},[1628],{"type":354,"value":1614},{"type":345,"tag":411,"props":1630,"children":1631},{"style":731},[1632],{"type":354,"value":1633}," &&",{"type":345,"tag":411,"props":1635,"children":1636},{"style":737},[1637],{"type":354,"value":1638}," crypto.",{"type":345,"tag":411,"props":1640,"children":1641},{"style":788},[1642],{"type":354,"value":1643},"timingSafeEqual",{"type":345,"tag":411,"props":1645,"children":1646},{"style":737},[1647],{"type":354,"value":1648},"(received, expected);\n",{"type":345,"tag":411,"props":1650,"children":1652},{"class":413,"line":1651},27,[1653],{"type":345,"tag":411,"props":1654,"children":1655},{"style":737},[1656],{"type":354,"value":1657},"  });\n",{"type":345,"tag":411,"props":1659,"children":1661},{"class":413,"line":1660},28,[1662],{"type":345,"tag":411,"props":1663,"children":1664},{"style":737},[1665],{"type":354,"value":1666},"}\n",{"type":345,"tag":346,"props":1668,"children":1669},{},[1670],{"type":354,"value":1671},"With Express, take the raw body for the webhook route:",{"type":345,"tag":714,"props":1673,"children":1674},{},[1675],{"type":345,"tag":401,"props":1676,"children":1678},{"className":719,"code":1677,"language":721,"meta":318,"style":318},"app.post(\"/webhooks\", express.raw({ type: \"application/json\" }), (req, res) => {\n  if (!verifyWebhook(req.body, req.headers, process.env.WEBHOOK_SECRET)) {\n    return res.status(401).end();\n  }\n  const event = JSON.parse(req.body);\n  // Deduplicate on req.headers[\"webhook-id\"], queue the work, then answer fast.\n  res.status(204).end();\n});\n",[1679],{"type":345,"tag":357,"props":1680,"children":1681},{"__ignoreMap":318},[1682,1755,1790,1829,1837,1872,1880,1913],{"type":345,"tag":411,"props":1683,"children":1684},{"class":413,"line":414},[1685,1690,1695,1699,1704,1709,1714,1719,1724,1729,1734,1738,1743,1747,1751],{"type":345,"tag":411,"props":1686,"children":1687},{"style":737},[1688],{"type":354,"value":1689},"app.",{"type":345,"tag":411,"props":1691,"children":1692},{"style":788},[1693],{"type":354,"value":1694},"post",{"type":345,"tag":411,"props":1696,"children":1697},{"style":737},[1698],{"type":354,"value":796},{"type":345,"tag":411,"props":1700,"children":1701},{"style":748},[1702],{"type":354,"value":1703},"\"/webhooks\"",{"type":345,"tag":411,"props":1705,"children":1706},{"style":737},[1707],{"type":354,"value":1708},", express.",{"type":345,"tag":411,"props":1710,"children":1711},{"style":788},[1712],{"type":354,"value":1713},"raw",{"type":345,"tag":411,"props":1715,"children":1716},{"style":737},[1717],{"type":354,"value":1718},"({ type: ",{"type":345,"tag":411,"props":1720,"children":1721},{"style":748},[1722],{"type":354,"value":1723},"\"application/json\"",{"type":345,"tag":411,"props":1725,"children":1726},{"style":737},[1727],{"type":354,"value":1728}," }), (",{"type":345,"tag":411,"props":1730,"children":1731},{"style":799},[1732],{"type":354,"value":1733},"req",{"type":345,"tag":411,"props":1735,"children":1736},{"style":737},[1737],{"type":354,"value":807},{"type":345,"tag":411,"props":1739,"children":1740},{"style":799},[1741],{"type":354,"value":1742},"res",{"type":345,"tag":411,"props":1744,"children":1745},{"style":737},[1746],{"type":354,"value":1437},{"type":345,"tag":411,"props":1748,"children":1749},{"style":731},[1750],{"type":354,"value":1442},{"type":345,"tag":411,"props":1752,"children":1753},{"style":737},[1754],{"type":354,"value":1447},{"type":345,"tag":411,"props":1756,"children":1757},{"class":413,"line":423},[1758,1762,1766,1770,1775,1780,1785],{"type":345,"tag":411,"props":1759,"children":1760},{"style":731},[1761],{"type":354,"value":944},{"type":345,"tag":411,"props":1763,"children":1764},{"style":737},[1765],{"type":354,"value":949},{"type":345,"tag":411,"props":1767,"children":1768},{"style":731},[1769],{"type":354,"value":954},{"type":345,"tag":411,"props":1771,"children":1772},{"style":788},[1773],{"type":354,"value":1774},"verifyWebhook",{"type":345,"tag":411,"props":1776,"children":1777},{"style":737},[1778],{"type":354,"value":1779},"(req.body, req.headers, process.env.",{"type":345,"tag":411,"props":1781,"children":1782},{"style":838},[1783],{"type":354,"value":1784},"WEBHOOK_SECRET",{"type":345,"tag":411,"props":1786,"children":1787},{"style":737},[1788],{"type":354,"value":1789},")) {\n",{"type":345,"tag":411,"props":1791,"children":1792},{"class":413,"line":432},[1793,1797,1802,1807,1811,1816,1820,1825],{"type":345,"tag":411,"props":1794,"children":1795},{"style":731},[1796],{"type":354,"value":1604},{"type":345,"tag":411,"props":1798,"children":1799},{"style":737},[1800],{"type":354,"value":1801}," res.",{"type":345,"tag":411,"props":1803,"children":1804},{"style":788},[1805],{"type":354,"value":1806},"status",{"type":345,"tag":411,"props":1808,"children":1809},{"style":737},[1810],{"type":354,"value":796},{"type":345,"tag":411,"props":1812,"children":1813},{"style":838},[1814],{"type":354,"value":1815},"401",{"type":345,"tag":411,"props":1817,"children":1818},{"style":737},[1819],{"type":354,"value":1417},{"type":345,"tag":411,"props":1821,"children":1822},{"style":788},[1823],{"type":354,"value":1824},"end",{"type":345,"tag":411,"props":1826,"children":1827},{"style":737},[1828],{"type":354,"value":1367},{"type":345,"tag":411,"props":1830,"children":1831},{"class":413,"line":441},[1832],{"type":345,"tag":411,"props":1833,"children":1834},{"style":737},[1835],{"type":354,"value":1836},"  }\n",{"type":345,"tag":411,"props":1838,"children":1839},{"class":413,"line":450},[1840,1844,1849,1853,1858,1862,1867],{"type":345,"tag":411,"props":1841,"children":1842},{"style":731},[1843],{"type":354,"value":854},{"type":345,"tag":411,"props":1845,"children":1846},{"style":838},[1847],{"type":354,"value":1848}," event",{"type":345,"tag":411,"props":1850,"children":1851},{"style":731},[1852],{"type":354,"value":835},{"type":345,"tag":411,"props":1854,"children":1855},{"style":838},[1856],{"type":354,"value":1857}," JSON",{"type":345,"tag":411,"props":1859,"children":1860},{"style":737},[1861],{"type":354,"value":613},{"type":345,"tag":411,"props":1863,"children":1864},{"style":788},[1865],{"type":354,"value":1866},"parse",{"type":345,"tag":411,"props":1868,"children":1869},{"style":737},[1870],{"type":354,"value":1871},"(req.body);\n",{"type":345,"tag":411,"props":1873,"children":1874},{"class":413,"line":459},[1875],{"type":345,"tag":411,"props":1876,"children":1877},{"style":769},[1878],{"type":354,"value":1879},"  // Deduplicate on req.headers[\"webhook-id\"], queue the work, then answer fast.\n",{"type":345,"tag":411,"props":1881,"children":1882},{"class":413,"line":468},[1883,1888,1892,1896,1901,1905,1909],{"type":345,"tag":411,"props":1884,"children":1885},{"style":737},[1886],{"type":354,"value":1887},"  res.",{"type":345,"tag":411,"props":1889,"children":1890},{"style":788},[1891],{"type":354,"value":1806},{"type":345,"tag":411,"props":1893,"children":1894},{"style":737},[1895],{"type":354,"value":796},{"type":345,"tag":411,"props":1897,"children":1898},{"style":838},[1899],{"type":354,"value":1900},"204",{"type":345,"tag":411,"props":1902,"children":1903},{"style":737},[1904],{"type":354,"value":1417},{"type":345,"tag":411,"props":1906,"children":1907},{"style":788},[1908],{"type":354,"value":1824},{"type":345,"tag":411,"props":1910,"children":1911},{"style":737},[1912],{"type":354,"value":1367},{"type":345,"tag":411,"props":1914,"children":1915},{"class":413,"line":477},[1916],{"type":345,"tag":411,"props":1917,"children":1918},{"style":737},[1919],{"type":354,"value":1920},"});\n",{"type":345,"tag":707,"props":1922,"children":1924},{"id":1923},"go",[1925],{"type":354,"value":1926},"Go",{"type":345,"tag":714,"props":1928,"children":1929},{},[1930],{"type":345,"tag":401,"props":1931,"children":1934},{"className":1932,"code":1933,"language":1923,"meta":318,"style":318},"language-go shiki shiki-themes github-dark","import (\n    \"crypto/hmac\"\n    \"crypto/sha256\"\n    \"encoding/base64\"\n    \"math\"\n    \"net/http\"\n    \"strconv\"\n    \"strings\"\n    \"time\"\n)\n\n// VerifyWebhook checks an Outbound Gateway delivery. body must be the exact bytes received.\nfunc VerifyWebhook(body []byte, header http.Header, secret string, tolerance time.Duration) bool {\n    id := header.Get(\"webhook-id\")\n    timestamp := header.Get(\"webhook-timestamp\")\n    signatures := header.Get(\"webhook-signature\")\n    if id == \"\" || timestamp == \"\" || signatures == \"\" {\n        return false\n    }\n    unix, err := strconv.ParseInt(timestamp, 10, 64)\n    if err != nil || math.Abs(time.Since(time.Unix(unix, 0)).Seconds()) > tolerance.Seconds() {\n        return false\n    }\n    key, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(secret, \"whsec_\"))\n    if err != nil {\n        return false\n    }\n    mac := hmac.New(sha256.New, key)\n    mac.Write([]byte(id + \".\" + timestamp + \".\"))\n    mac.Write(body)\n    expected := mac.Sum(nil)\n\n    // During a secret rotation the header carries two signatures: \"v1,\u003Ca> v1,\u003Cb>\".\n    for _, entry := range strings.Fields(signatures) {\n        version, signature, ok := strings.Cut(entry, \",\")\n        if !ok || version != \"v1\" {\n            continue\n        }\n        received, err := base64.StdEncoding.DecodeString(signature)\n        if err == nil && hmac.Equal(received, expected) {\n            return true\n        }\n    }\n    return false\n}\n",[1935],{"type":345,"tag":357,"props":1936,"children":1937},{"__ignoreMap":318},[1938,1950,1968,1984,2000,2016,2032,2048,2064,2080,2087,2094,2102,2204,2239,2271,2303,2363,2376,2384,2429,2527,2538,2545,2592,2615,2626,2633,2660,2719,2736,2772,2780,2789,2827,2862,2901,2910,2919,2945,2983,2997,3005,3013,3025],{"type":345,"tag":411,"props":1939,"children":1940},{"class":413,"line":414},[1941,1945],{"type":345,"tag":411,"props":1942,"children":1943},{"style":731},[1944],{"type":354,"value":734},{"type":345,"tag":411,"props":1946,"children":1947},{"style":737},[1948],{"type":354,"value":1949}," (\n",{"type":345,"tag":411,"props":1951,"children":1952},{"class":413,"line":423},[1953,1958,1963],{"type":345,"tag":411,"props":1954,"children":1955},{"style":748},[1956],{"type":354,"value":1957},"    \"",{"type":345,"tag":411,"props":1959,"children":1960},{"style":788},[1961],{"type":354,"value":1962},"crypto/hmac",{"type":345,"tag":411,"props":1964,"children":1965},{"style":748},[1966],{"type":354,"value":1967},"\"\n",{"type":345,"tag":411,"props":1969,"children":1970},{"class":413,"line":432},[1971,1975,1980],{"type":345,"tag":411,"props":1972,"children":1973},{"style":748},[1974],{"type":354,"value":1957},{"type":345,"tag":411,"props":1976,"children":1977},{"style":788},[1978],{"type":354,"value":1979},"crypto/sha256",{"type":345,"tag":411,"props":1981,"children":1982},{"style":748},[1983],{"type":354,"value":1967},{"type":345,"tag":411,"props":1985,"children":1986},{"class":413,"line":441},[1987,1991,1996],{"type":345,"tag":411,"props":1988,"children":1989},{"style":748},[1990],{"type":354,"value":1957},{"type":345,"tag":411,"props":1992,"children":1993},{"style":788},[1994],{"type":354,"value":1995},"encoding/base64",{"type":345,"tag":411,"props":1997,"children":1998},{"style":748},[1999],{"type":354,"value":1967},{"type":345,"tag":411,"props":2001,"children":2002},{"class":413,"line":450},[2003,2007,2012],{"type":345,"tag":411,"props":2004,"children":2005},{"style":748},[2006],{"type":354,"value":1957},{"type":345,"tag":411,"props":2008,"children":2009},{"style":788},[2010],{"type":354,"value":2011},"math",{"type":345,"tag":411,"props":2013,"children":2014},{"style":748},[2015],{"type":354,"value":1967},{"type":345,"tag":411,"props":2017,"children":2018},{"class":413,"line":459},[2019,2023,2028],{"type":345,"tag":411,"props":2020,"children":2021},{"style":748},[2022],{"type":354,"value":1957},{"type":345,"tag":411,"props":2024,"children":2025},{"style":788},[2026],{"type":354,"value":2027},"net/http",{"type":345,"tag":411,"props":2029,"children":2030},{"style":748},[2031],{"type":354,"value":1967},{"type":345,"tag":411,"props":2033,"children":2034},{"class":413,"line":468},[2035,2039,2044],{"type":345,"tag":411,"props":2036,"children":2037},{"style":748},[2038],{"type":354,"value":1957},{"type":345,"tag":411,"props":2040,"children":2041},{"style":788},[2042],{"type":354,"value":2043},"strconv",{"type":345,"tag":411,"props":2045,"children":2046},{"style":748},[2047],{"type":354,"value":1967},{"type":345,"tag":411,"props":2049,"children":2050},{"class":413,"line":477},[2051,2055,2060],{"type":345,"tag":411,"props":2052,"children":2053},{"style":748},[2054],{"type":354,"value":1957},{"type":345,"tag":411,"props":2056,"children":2057},{"style":788},[2058],{"type":354,"value":2059},"strings",{"type":345,"tag":411,"props":2061,"children":2062},{"style":748},[2063],{"type":354,"value":1967},{"type":345,"tag":411,"props":2065,"children":2066},{"class":413,"line":486},[2067,2071,2076],{"type":345,"tag":411,"props":2068,"children":2069},{"style":748},[2070],{"type":354,"value":1957},{"type":345,"tag":411,"props":2072,"children":2073},{"style":788},[2074],{"type":354,"value":2075},"time",{"type":345,"tag":411,"props":2077,"children":2078},{"style":748},[2079],{"type":354,"value":1967},{"type":345,"tag":411,"props":2081,"children":2082},{"class":413,"line":496},[2083],{"type":345,"tag":411,"props":2084,"children":2085},{"style":737},[2086],{"type":354,"value":1332},{"type":345,"tag":411,"props":2088,"children":2089},{"class":413,"line":1019},[2090],{"type":345,"tag":411,"props":2091,"children":2092},{"emptyLinePlaceholder":490},[2093],{"type":354,"value":493},{"type":345,"tag":411,"props":2095,"children":2096},{"class":413,"line":1086},[2097],{"type":345,"tag":411,"props":2098,"children":2099},{"style":769},[2100],{"type":354,"value":2101},"// VerifyWebhook checks an Outbound Gateway delivery. body must be the exact bytes received.\n",{"type":345,"tag":411,"props":2103,"children":2104},{"class":413,"line":1148},[2105,2110,2115,2119,2123,2128,2133,2137,2142,2147,2151,2155,2159,2163,2168,2172,2177,2182,2186,2191,2195,2200],{"type":345,"tag":411,"props":2106,"children":2107},{"style":731},[2108],{"type":354,"value":2109},"func",{"type":345,"tag":411,"props":2111,"children":2112},{"style":788},[2113],{"type":354,"value":2114}," VerifyWebhook",{"type":345,"tag":411,"props":2116,"children":2117},{"style":737},[2118],{"type":354,"value":796},{"type":345,"tag":411,"props":2120,"children":2121},{"style":799},[2122],{"type":354,"value":668},{"type":345,"tag":411,"props":2124,"children":2125},{"style":737},[2126],{"type":354,"value":2127}," []",{"type":345,"tag":411,"props":2129,"children":2130},{"style":731},[2131],{"type":354,"value":2132},"byte",{"type":345,"tag":411,"props":2134,"children":2135},{"style":737},[2136],{"type":354,"value":807},{"type":345,"tag":411,"props":2138,"children":2139},{"style":799},[2140],{"type":354,"value":2141},"header",{"type":345,"tag":411,"props":2143,"children":2144},{"style":788},[2145],{"type":354,"value":2146}," http",{"type":345,"tag":411,"props":2148,"children":2149},{"style":737},[2150],{"type":354,"value":613},{"type":345,"tag":411,"props":2152,"children":2153},{"style":788},[2154],{"type":354,"value":520},{"type":345,"tag":411,"props":2156,"children":2157},{"style":737},[2158],{"type":354,"value":807},{"type":345,"tag":411,"props":2160,"children":2161},{"style":799},[2162],{"type":354,"value":821},{"type":345,"tag":411,"props":2164,"children":2165},{"style":731},[2166],{"type":354,"value":2167}," string",{"type":345,"tag":411,"props":2169,"children":2170},{"style":737},[2171],{"type":354,"value":807},{"type":345,"tag":411,"props":2173,"children":2174},{"style":799},[2175],{"type":354,"value":2176},"tolerance",{"type":345,"tag":411,"props":2178,"children":2179},{"style":788},[2180],{"type":354,"value":2181}," time",{"type":345,"tag":411,"props":2183,"children":2184},{"style":737},[2185],{"type":354,"value":613},{"type":345,"tag":411,"props":2187,"children":2188},{"style":788},[2189],{"type":354,"value":2190},"Duration",{"type":345,"tag":411,"props":2192,"children":2193},{"style":737},[2194],{"type":354,"value":1437},{"type":345,"tag":411,"props":2196,"children":2197},{"style":731},[2198],{"type":354,"value":2199},"bool",{"type":345,"tag":411,"props":2201,"children":2202},{"style":737},[2203],{"type":354,"value":1447},{"type":345,"tag":411,"props":2205,"children":2206},{"class":413,"line":1156},[2207,2212,2217,2222,2227,2231,2235],{"type":345,"tag":411,"props":2208,"children":2209},{"style":737},[2210],{"type":354,"value":2211},"    id ",{"type":345,"tag":411,"props":2213,"children":2214},{"style":731},[2215],{"type":354,"value":2216},":=",{"type":345,"tag":411,"props":2218,"children":2219},{"style":737},[2220],{"type":354,"value":2221}," header.",{"type":345,"tag":411,"props":2223,"children":2224},{"style":788},[2225],{"type":354,"value":2226},"Get",{"type":345,"tag":411,"props":2228,"children":2229},{"style":737},[2230],{"type":354,"value":796},{"type":345,"tag":411,"props":2232,"children":2233},{"style":748},[2234],{"type":354,"value":873},{"type":345,"tag":411,"props":2236,"children":2237},{"style":737},[2238],{"type":354,"value":1332},{"type":345,"tag":411,"props":2240,"children":2241},{"class":413,"line":1238},[2242,2247,2251,2255,2259,2263,2267],{"type":345,"tag":411,"props":2243,"children":2244},{"style":737},[2245],{"type":354,"value":2246},"    timestamp ",{"type":345,"tag":411,"props":2248,"children":2249},{"style":731},[2250],{"type":354,"value":2216},{"type":345,"tag":411,"props":2252,"children":2253},{"style":737},[2254],{"type":354,"value":2221},{"type":345,"tag":411,"props":2256,"children":2257},{"style":788},[2258],{"type":354,"value":2226},{"type":345,"tag":411,"props":2260,"children":2261},{"style":737},[2262],{"type":354,"value":796},{"type":345,"tag":411,"props":2264,"children":2265},{"style":748},[2266],{"type":354,"value":903},{"type":345,"tag":411,"props":2268,"children":2269},{"style":737},[2270],{"type":354,"value":1332},{"type":345,"tag":411,"props":2272,"children":2273},{"class":413,"line":1260},[2274,2279,2283,2287,2291,2295,2299],{"type":345,"tag":411,"props":2275,"children":2276},{"style":737},[2277],{"type":354,"value":2278},"    signatures ",{"type":345,"tag":411,"props":2280,"children":2281},{"style":731},[2282],{"type":354,"value":2216},{"type":345,"tag":411,"props":2284,"children":2285},{"style":737},[2286],{"type":354,"value":2221},{"type":345,"tag":411,"props":2288,"children":2289},{"style":788},[2290],{"type":354,"value":2226},{"type":345,"tag":411,"props":2292,"children":2293},{"style":737},[2294],{"type":354,"value":796},{"type":345,"tag":411,"props":2296,"children":2297},{"style":748},[2298],{"type":354,"value":932},{"type":345,"tag":411,"props":2300,"children":2301},{"style":737},[2302],{"type":354,"value":1332},{"type":345,"tag":411,"props":2304,"children":2305},{"class":413,"line":1288},[2306,2310,2315,2320,2325,2329,2334,2338,2342,2346,2351,2355,2359],{"type":345,"tag":411,"props":2307,"children":2308},{"style":731},[2309],{"type":354,"value":1516},{"type":345,"tag":411,"props":2311,"children":2312},{"style":737},[2313],{"type":354,"value":2314}," id ",{"type":345,"tag":411,"props":2316,"children":2317},{"style":731},[2318],{"type":354,"value":2319},"==",{"type":345,"tag":411,"props":2321,"children":2322},{"style":748},[2323],{"type":354,"value":2324}," \"\"",{"type":345,"tag":411,"props":2326,"children":2327},{"style":731},[2328],{"type":354,"value":1536},{"type":345,"tag":411,"props":2330,"children":2331},{"style":737},[2332],{"type":354,"value":2333}," timestamp ",{"type":345,"tag":411,"props":2335,"children":2336},{"style":731},[2337],{"type":354,"value":2319},{"type":345,"tag":411,"props":2339,"children":2340},{"style":748},[2341],{"type":354,"value":2324},{"type":345,"tag":411,"props":2343,"children":2344},{"style":731},[2345],{"type":354,"value":1536},{"type":345,"tag":411,"props":2347,"children":2348},{"style":737},[2349],{"type":354,"value":2350}," signatures ",{"type":345,"tag":411,"props":2352,"children":2353},{"style":731},[2354],{"type":354,"value":2319},{"type":345,"tag":411,"props":2356,"children":2357},{"style":748},[2358],{"type":354,"value":2324},{"type":345,"tag":411,"props":2360,"children":2361},{"style":737},[2362],{"type":354,"value":1447},{"type":345,"tag":411,"props":2364,"children":2365},{"class":413,"line":1335},[2366,2371],{"type":345,"tag":411,"props":2367,"children":2368},{"style":731},[2369],{"type":354,"value":2370},"        return",{"type":345,"tag":411,"props":2372,"children":2373},{"style":838},[2374],{"type":354,"value":2375}," false\n",{"type":345,"tag":411,"props":2377,"children":2378},{"class":413,"line":1352},[2379],{"type":345,"tag":411,"props":2380,"children":2381},{"style":737},[2382],{"type":354,"value":2383},"    }\n",{"type":345,"tag":411,"props":2385,"children":2386},{"class":413,"line":1370},[2387,2392,2396,2401,2406,2411,2416,2420,2425],{"type":345,"tag":411,"props":2388,"children":2389},{"style":737},[2390],{"type":354,"value":2391},"    unix, err ",{"type":345,"tag":411,"props":2393,"children":2394},{"style":731},[2395],{"type":354,"value":2216},{"type":345,"tag":411,"props":2397,"children":2398},{"style":737},[2399],{"type":354,"value":2400}," strconv.",{"type":345,"tag":411,"props":2402,"children":2403},{"style":788},[2404],{"type":354,"value":2405},"ParseInt",{"type":345,"tag":411,"props":2407,"children":2408},{"style":737},[2409],{"type":354,"value":2410},"(timestamp, ",{"type":345,"tag":411,"props":2412,"children":2413},{"style":838},[2414],{"type":354,"value":2415},"10",{"type":345,"tag":411,"props":2417,"children":2418},{"style":737},[2419],{"type":354,"value":807},{"type":345,"tag":411,"props":2421,"children":2422},{"style":838},[2423],{"type":354,"value":2424},"64",{"type":345,"tag":411,"props":2426,"children":2427},{"style":737},[2428],{"type":354,"value":1332},{"type":345,"tag":411,"props":2430,"children":2431},{"class":413,"line":1378},[2432,2436,2441,2446,2451,2455,2460,2465,2470,2475,2479,2484,2489,2494,2499,2504,2509,2513,2518,2522],{"type":345,"tag":411,"props":2433,"children":2434},{"style":731},[2435],{"type":354,"value":1516},{"type":345,"tag":411,"props":2437,"children":2438},{"style":737},[2439],{"type":354,"value":2440}," err ",{"type":345,"tag":411,"props":2442,"children":2443},{"style":731},[2444],{"type":354,"value":2445},"!=",{"type":345,"tag":411,"props":2447,"children":2448},{"style":838},[2449],{"type":354,"value":2450}," nil",{"type":345,"tag":411,"props":2452,"children":2453},{"style":731},[2454],{"type":354,"value":1536},{"type":345,"tag":411,"props":2456,"children":2457},{"style":737},[2458],{"type":354,"value":2459}," math.",{"type":345,"tag":411,"props":2461,"children":2462},{"style":788},[2463],{"type":354,"value":2464},"Abs",{"type":345,"tag":411,"props":2466,"children":2467},{"style":737},[2468],{"type":354,"value":2469},"(time.",{"type":345,"tag":411,"props":2471,"children":2472},{"style":788},[2473],{"type":354,"value":2474},"Since",{"type":345,"tag":411,"props":2476,"children":2477},{"style":737},[2478],{"type":354,"value":2469},{"type":345,"tag":411,"props":2480,"children":2481},{"style":788},[2482],{"type":354,"value":2483},"Unix",{"type":345,"tag":411,"props":2485,"children":2486},{"style":737},[2487],{"type":354,"value":2488},"(unix, ",{"type":345,"tag":411,"props":2490,"children":2491},{"style":838},[2492],{"type":354,"value":2493},"0",{"type":345,"tag":411,"props":2495,"children":2496},{"style":737},[2497],{"type":354,"value":2498},")).",{"type":345,"tag":411,"props":2500,"children":2501},{"style":788},[2502],{"type":354,"value":2503},"Seconds",{"type":345,"tag":411,"props":2505,"children":2506},{"style":737},[2507],{"type":354,"value":2508},"()) ",{"type":345,"tag":411,"props":2510,"children":2511},{"style":731},[2512],{"type":354,"value":1128},{"type":345,"tag":411,"props":2514,"children":2515},{"style":737},[2516],{"type":354,"value":2517}," tolerance.",{"type":345,"tag":411,"props":2519,"children":2520},{"style":788},[2521],{"type":354,"value":2503},{"type":345,"tag":411,"props":2523,"children":2524},{"style":737},[2525],{"type":354,"value":2526},"() {\n",{"type":345,"tag":411,"props":2528,"children":2529},{"class":413,"line":1387},[2530,2534],{"type":345,"tag":411,"props":2531,"children":2532},{"style":731},[2533],{"type":354,"value":2370},{"type":345,"tag":411,"props":2535,"children":2536},{"style":838},[2537],{"type":354,"value":2375},{"type":345,"tag":411,"props":2539,"children":2540},{"class":413,"line":1450},[2541],{"type":345,"tag":411,"props":2542,"children":2543},{"style":737},[2544],{"type":354,"value":2383},{"type":345,"tag":411,"props":2546,"children":2547},{"class":413,"line":1510},[2548,2553,2557,2562,2567,2572,2577,2582,2587],{"type":345,"tag":411,"props":2549,"children":2550},{"style":737},[2551],{"type":354,"value":2552},"    key, err ",{"type":345,"tag":411,"props":2554,"children":2555},{"style":731},[2556],{"type":354,"value":2216},{"type":345,"tag":411,"props":2558,"children":2559},{"style":737},[2560],{"type":354,"value":2561}," base64.StdEncoding.",{"type":345,"tag":411,"props":2563,"children":2564},{"style":788},[2565],{"type":354,"value":2566},"DecodeString",{"type":345,"tag":411,"props":2568,"children":2569},{"style":737},[2570],{"type":354,"value":2571},"(strings.",{"type":345,"tag":411,"props":2573,"children":2574},{"style":788},[2575],{"type":354,"value":2576},"TrimPrefix",{"type":345,"tag":411,"props":2578,"children":2579},{"style":737},[2580],{"type":354,"value":2581},"(secret, ",{"type":345,"tag":411,"props":2583,"children":2584},{"style":748},[2585],{"type":354,"value":2586},"\"whsec_\"",{"type":345,"tag":411,"props":2588,"children":2589},{"style":737},[2590],{"type":354,"value":2591},"))\n",{"type":345,"tag":411,"props":2593,"children":2594},{"class":413,"line":1560},[2595,2599,2603,2607,2611],{"type":345,"tag":411,"props":2596,"children":2597},{"style":731},[2598],{"type":354,"value":1516},{"type":345,"tag":411,"props":2600,"children":2601},{"style":737},[2602],{"type":354,"value":2440},{"type":345,"tag":411,"props":2604,"children":2605},{"style":731},[2606],{"type":354,"value":2445},{"type":345,"tag":411,"props":2608,"children":2609},{"style":838},[2610],{"type":354,"value":2450},{"type":345,"tag":411,"props":2612,"children":2613},{"style":737},[2614],{"type":354,"value":1447},{"type":345,"tag":411,"props":2616,"children":2617},{"class":413,"line":1598},[2618,2622],{"type":345,"tag":411,"props":2619,"children":2620},{"style":731},[2621],{"type":354,"value":2370},{"type":345,"tag":411,"props":2623,"children":2624},{"style":838},[2625],{"type":354,"value":2375},{"type":345,"tag":411,"props":2627,"children":2628},{"class":413,"line":1651},[2629],{"type":345,"tag":411,"props":2630,"children":2631},{"style":737},[2632],{"type":354,"value":2383},{"type":345,"tag":411,"props":2634,"children":2635},{"class":413,"line":1660},[2636,2641,2645,2650,2655],{"type":345,"tag":411,"props":2637,"children":2638},{"style":737},[2639],{"type":354,"value":2640},"    mac ",{"type":345,"tag":411,"props":2642,"children":2643},{"style":731},[2644],{"type":354,"value":2216},{"type":345,"tag":411,"props":2646,"children":2647},{"style":737},[2648],{"type":354,"value":2649}," hmac.",{"type":345,"tag":411,"props":2651,"children":2652},{"style":788},[2653],{"type":354,"value":2654},"New",{"type":345,"tag":411,"props":2656,"children":2657},{"style":737},[2658],{"type":354,"value":2659},"(sha256.New, key)\n",{"type":345,"tag":411,"props":2661,"children":2663},{"class":413,"line":2662},29,[2664,2669,2674,2679,2683,2688,2693,2698,2703,2707,2711,2715],{"type":345,"tag":411,"props":2665,"children":2666},{"style":737},[2667],{"type":354,"value":2668},"    mac.",{"type":345,"tag":411,"props":2670,"children":2671},{"style":788},[2672],{"type":354,"value":2673},"Write",{"type":345,"tag":411,"props":2675,"children":2676},{"style":737},[2677],{"type":354,"value":2678},"([]",{"type":345,"tag":411,"props":2680,"children":2681},{"style":731},[2682],{"type":354,"value":2132},{"type":345,"tag":411,"props":2684,"children":2685},{"style":737},[2686],{"type":354,"value":2687},"(id ",{"type":345,"tag":411,"props":2689,"children":2690},{"style":731},[2691],{"type":354,"value":2692},"+",{"type":345,"tag":411,"props":2694,"children":2695},{"style":748},[2696],{"type":354,"value":2697}," \".\"",{"type":345,"tag":411,"props":2699,"children":2700},{"style":731},[2701],{"type":354,"value":2702}," +",{"type":345,"tag":411,"props":2704,"children":2705},{"style":737},[2706],{"type":354,"value":2333},{"type":345,"tag":411,"props":2708,"children":2709},{"style":731},[2710],{"type":354,"value":2692},{"type":345,"tag":411,"props":2712,"children":2713},{"style":748},[2714],{"type":354,"value":2697},{"type":345,"tag":411,"props":2716,"children":2717},{"style":737},[2718],{"type":354,"value":2591},{"type":345,"tag":411,"props":2720,"children":2722},{"class":413,"line":2721},30,[2723,2727,2731],{"type":345,"tag":411,"props":2724,"children":2725},{"style":737},[2726],{"type":354,"value":2668},{"type":345,"tag":411,"props":2728,"children":2729},{"style":788},[2730],{"type":354,"value":2673},{"type":345,"tag":411,"props":2732,"children":2733},{"style":737},[2734],{"type":354,"value":2735},"(body)\n",{"type":345,"tag":411,"props":2737,"children":2739},{"class":413,"line":2738},31,[2740,2745,2749,2754,2759,2763,2768],{"type":345,"tag":411,"props":2741,"children":2742},{"style":737},[2743],{"type":354,"value":2744},"    expected ",{"type":345,"tag":411,"props":2746,"children":2747},{"style":731},[2748],{"type":354,"value":2216},{"type":345,"tag":411,"props":2750,"children":2751},{"style":737},[2752],{"type":354,"value":2753}," mac.",{"type":345,"tag":411,"props":2755,"children":2756},{"style":788},[2757],{"type":354,"value":2758},"Sum",{"type":345,"tag":411,"props":2760,"children":2761},{"style":737},[2762],{"type":354,"value":796},{"type":345,"tag":411,"props":2764,"children":2765},{"style":838},[2766],{"type":354,"value":2767},"nil",{"type":345,"tag":411,"props":2769,"children":2770},{"style":737},[2771],{"type":354,"value":1332},{"type":345,"tag":411,"props":2773,"children":2775},{"class":413,"line":2774},32,[2776],{"type":345,"tag":411,"props":2777,"children":2778},{"emptyLinePlaceholder":490},[2779],{"type":354,"value":493},{"type":345,"tag":411,"props":2781,"children":2783},{"class":413,"line":2782},33,[2784],{"type":345,"tag":411,"props":2785,"children":2786},{"style":769},[2787],{"type":354,"value":2788},"    // During a secret rotation the header carries two signatures: \"v1,\u003Ca> v1,\u003Cb>\".\n",{"type":345,"tag":411,"props":2790,"children":2792},{"class":413,"line":2791},34,[2793,2798,2803,2807,2812,2817,2822],{"type":345,"tag":411,"props":2794,"children":2795},{"style":731},[2796],{"type":354,"value":2797},"    for",{"type":345,"tag":411,"props":2799,"children":2800},{"style":737},[2801],{"type":354,"value":2802}," _, entry ",{"type":345,"tag":411,"props":2804,"children":2805},{"style":731},[2806],{"type":354,"value":2216},{"type":345,"tag":411,"props":2808,"children":2809},{"style":731},[2810],{"type":354,"value":2811}," range",{"type":345,"tag":411,"props":2813,"children":2814},{"style":737},[2815],{"type":354,"value":2816}," strings.",{"type":345,"tag":411,"props":2818,"children":2819},{"style":788},[2820],{"type":354,"value":2821},"Fields",{"type":345,"tag":411,"props":2823,"children":2824},{"style":737},[2825],{"type":354,"value":2826},"(signatures) {\n",{"type":345,"tag":411,"props":2828,"children":2830},{"class":413,"line":2829},35,[2831,2836,2840,2844,2849,2854,2858],{"type":345,"tag":411,"props":2832,"children":2833},{"style":737},[2834],{"type":354,"value":2835},"        version, signature, ok ",{"type":345,"tag":411,"props":2837,"children":2838},{"style":731},[2839],{"type":354,"value":2216},{"type":345,"tag":411,"props":2841,"children":2842},{"style":737},[2843],{"type":354,"value":2816},{"type":345,"tag":411,"props":2845,"children":2846},{"style":788},[2847],{"type":354,"value":2848},"Cut",{"type":345,"tag":411,"props":2850,"children":2851},{"style":737},[2852],{"type":354,"value":2853},"(entry, ",{"type":345,"tag":411,"props":2855,"children":2856},{"style":748},[2857],{"type":354,"value":1503},{"type":345,"tag":411,"props":2859,"children":2860},{"style":737},[2861],{"type":354,"value":1332},{"type":345,"tag":411,"props":2863,"children":2865},{"class":413,"line":2864},36,[2866,2871,2875,2880,2884,2889,2893,2897],{"type":345,"tag":411,"props":2867,"children":2868},{"style":731},[2869],{"type":354,"value":2870},"        if",{"type":345,"tag":411,"props":2872,"children":2873},{"style":731},[2874],{"type":354,"value":969},{"type":345,"tag":411,"props":2876,"children":2877},{"style":737},[2878],{"type":354,"value":2879},"ok ",{"type":345,"tag":411,"props":2881,"children":2882},{"style":731},[2883],{"type":354,"value":964},{"type":345,"tag":411,"props":2885,"children":2886},{"style":737},[2887],{"type":354,"value":2888}," version ",{"type":345,"tag":411,"props":2890,"children":2891},{"style":731},[2892],{"type":354,"value":2445},{"type":345,"tag":411,"props":2894,"children":2895},{"style":748},[2896],{"type":354,"value":1531},{"type":345,"tag":411,"props":2898,"children":2899},{"style":737},[2900],{"type":354,"value":1447},{"type":345,"tag":411,"props":2902,"children":2904},{"class":413,"line":2903},37,[2905],{"type":345,"tag":411,"props":2906,"children":2907},{"style":731},[2908],{"type":354,"value":2909},"            continue\n",{"type":345,"tag":411,"props":2911,"children":2913},{"class":413,"line":2912},38,[2914],{"type":345,"tag":411,"props":2915,"children":2916},{"style":737},[2917],{"type":354,"value":2918},"        }\n",{"type":345,"tag":411,"props":2920,"children":2922},{"class":413,"line":2921},39,[2923,2928,2932,2936,2940],{"type":345,"tag":411,"props":2924,"children":2925},{"style":737},[2926],{"type":354,"value":2927},"        received, err ",{"type":345,"tag":411,"props":2929,"children":2930},{"style":731},[2931],{"type":354,"value":2216},{"type":345,"tag":411,"props":2933,"children":2934},{"style":737},[2935],{"type":354,"value":2561},{"type":345,"tag":411,"props":2937,"children":2938},{"style":788},[2939],{"type":354,"value":2566},{"type":345,"tag":411,"props":2941,"children":2942},{"style":737},[2943],{"type":354,"value":2944},"(signature)\n",{"type":345,"tag":411,"props":2946,"children":2948},{"class":413,"line":2947},40,[2949,2953,2957,2961,2965,2969,2973,2978],{"type":345,"tag":411,"props":2950,"children":2951},{"style":731},[2952],{"type":354,"value":2870},{"type":345,"tag":411,"props":2954,"children":2955},{"style":737},[2956],{"type":354,"value":2440},{"type":345,"tag":411,"props":2958,"children":2959},{"style":731},[2960],{"type":354,"value":2319},{"type":345,"tag":411,"props":2962,"children":2963},{"style":838},[2964],{"type":354,"value":2450},{"type":345,"tag":411,"props":2966,"children":2967},{"style":731},[2968],{"type":354,"value":1633},{"type":345,"tag":411,"props":2970,"children":2971},{"style":737},[2972],{"type":354,"value":2649},{"type":345,"tag":411,"props":2974,"children":2975},{"style":788},[2976],{"type":354,"value":2977},"Equal",{"type":345,"tag":411,"props":2979,"children":2980},{"style":737},[2981],{"type":354,"value":2982},"(received, expected) {\n",{"type":345,"tag":411,"props":2984,"children":2986},{"class":413,"line":2985},41,[2987,2992],{"type":345,"tag":411,"props":2988,"children":2989},{"style":731},[2990],{"type":354,"value":2991},"            return",{"type":345,"tag":411,"props":2993,"children":2994},{"style":838},[2995],{"type":354,"value":2996}," true\n",{"type":345,"tag":411,"props":2998,"children":3000},{"class":413,"line":2999},42,[3001],{"type":345,"tag":411,"props":3002,"children":3003},{"style":737},[3004],{"type":354,"value":2918},{"type":345,"tag":411,"props":3006,"children":3008},{"class":413,"line":3007},43,[3009],{"type":345,"tag":411,"props":3010,"children":3011},{"style":737},[3012],{"type":354,"value":2383},{"type":345,"tag":411,"props":3014,"children":3016},{"class":413,"line":3015},44,[3017,3021],{"type":345,"tag":411,"props":3018,"children":3019},{"style":731},[3020],{"type":354,"value":1604},{"type":345,"tag":411,"props":3022,"children":3023},{"style":838},[3024],{"type":354,"value":2375},{"type":345,"tag":411,"props":3026,"children":3028},{"class":413,"line":3027},45,[3029],{"type":345,"tag":411,"props":3030,"children":3031},{"style":737},[3032],{"type":354,"value":1666},{"type":345,"tag":346,"props":3034,"children":3035},{},[3036,3038,3045,3047,3053],{"type":354,"value":3037},"Any ",{"type":345,"tag":366,"props":3039,"children":3042},{"href":3040,"rel":3041},"https://github.com/standard-webhooks/standard-webhooks",[370],[3043],{"type":354,"value":3044},"Standard Webhooks library",{"type":354,"value":3046}," verifies these headers too. To check a captured request by hand, paste it into the ",{"type":345,"tag":366,"props":3048,"children":3050},{"href":3049},"/verify-standard-webhooks-signature",[3051],{"type":354,"value":3052},"Standard Webhooks signature verifier",{"type":354,"value":613},{"type":345,"tag":394,"props":3055,"children":3057},{"id":3056},"deduplicate-on-webhook-id",[3058,3060],{"type":354,"value":3059},"Deduplicate on ",{"type":345,"tag":357,"props":3061,"children":3063},{"className":3062},[],[3064],{"type":354,"value":382},{"type":345,"tag":346,"props":3066,"children":3067},{},[3068,3070,3075,3077,3082,3084,3089],{"type":354,"value":3069},"Delivery is ",{"type":345,"tag":350,"props":3071,"children":3072},{},[3073],{"type":354,"value":3074},"at least once",{"type":354,"value":3076},". The same message can arrive more than once, for example when your endpoint processed a request but timed out before answering, when a delivery is retried manually, or when failed deliveries are recovered. Every copy has the same ",{"type":345,"tag":357,"props":3078,"children":3080},{"className":3079},[],[3081],{"type":354,"value":382},{"type":354,"value":3083},". Store the IDs you have processed (with a unique constraint or a short-lived cache) and acknowledge repeats with a ",{"type":345,"tag":357,"props":3085,"children":3087},{"className":3086},[],[3088],{"type":354,"value":390},{"type":354,"value":3090}," without processing them again.",{"type":345,"tag":346,"props":3092,"children":3093},{},[3094],{"type":354,"value":3095},"Respond quickly. Do the slow work after acknowledging, from a queue. A response that takes longer than the endpoint timeout (15 seconds by default, configurable up to 60) counts as a failed attempt and is retried.",{"type":345,"tag":394,"props":3097,"children":3099},{"id":3098},"retries-and-backoff",[3100],{"type":354,"value":3101},"Retries and backoff",{"type":345,"tag":504,"props":3103,"children":3104},{},[3105,3121],{"type":345,"tag":508,"props":3106,"children":3107},{},[3108],{"type":345,"tag":512,"props":3109,"children":3110},{},[3111,3116],{"type":345,"tag":516,"props":3112,"children":3113},{},[3114],{"type":354,"value":3115},"Response",{"type":345,"tag":516,"props":3117,"children":3118},{},[3119],{"type":354,"value":3120},"Result",{"type":345,"tag":527,"props":3122,"children":3123},{},[3124,3148,3188,3211],{"type":345,"tag":512,"props":3125,"children":3126},{},[3127,3136],{"type":345,"tag":534,"props":3128,"children":3129},{},[3130,3131],{"type":354,"value":3037},{"type":345,"tag":357,"props":3132,"children":3134},{"className":3133},[],[3135],{"type":354,"value":390},{"type":345,"tag":534,"props":3137,"children":3138},{},[3139,3141,3147],{"type":354,"value":3140},"Delivered (",{"type":345,"tag":357,"props":3142,"children":3144},{"className":3143},[],[3145],{"type":354,"value":3146},"sent",{"type":354,"value":1417},{"type":345,"tag":512,"props":3149,"children":3150},{},[3151,3176],{"type":345,"tag":534,"props":3152,"children":3153},{},[3154,3160,3162,3168,3170],{"type":345,"tag":357,"props":3155,"children":3157},{"className":3156},[],[3158],{"type":354,"value":3159},"429",{"type":354,"value":3161}," or ",{"type":345,"tag":357,"props":3163,"children":3165},{"className":3164},[],[3166],{"type":354,"value":3167},"503",{"type":354,"value":3169}," with ",{"type":345,"tag":357,"props":3171,"children":3173},{"className":3172},[],[3174],{"type":354,"value":3175},"Retry-After",{"type":345,"tag":534,"props":3177,"children":3178},{},[3179,3181,3186],{"type":354,"value":3180},"Retried no sooner than ",{"type":345,"tag":357,"props":3182,"children":3184},{"className":3183},[],[3185],{"type":354,"value":3175},{"type":354,"value":3187}," (capped at one hour).",{"type":345,"tag":512,"props":3189,"children":3190},{},[3191,3200],{"type":345,"tag":534,"props":3192,"children":3193},{},[3194],{"type":345,"tag":357,"props":3195,"children":3197},{"className":3196},[],[3198],{"type":354,"value":3199},"410 Gone",{"type":345,"tag":534,"props":3201,"children":3202},{},[3203,3205,3210],{"type":354,"value":3204},"Fails for good and ",{"type":345,"tag":350,"props":3206,"children":3207},{},[3208],{"type":354,"value":3209},"disables the endpoint",{"type":354,"value":613},{"type":345,"tag":512,"props":3212,"children":3213},{},[3214,3240],{"type":345,"tag":534,"props":3215,"children":3216},{},[3217,3223,3225,3231,3232,3238],{"type":345,"tag":357,"props":3218,"children":3220},{"className":3219},[],[3221],{"type":354,"value":3222},"3xx",{"type":354,"value":3224},", other ",{"type":345,"tag":357,"props":3226,"children":3228},{"className":3227},[],[3229],{"type":354,"value":3230},"4xx",{"type":354,"value":1063},{"type":345,"tag":357,"props":3233,"children":3235},{"className":3234},[],[3236],{"type":354,"value":3237},"5xx",{"type":354,"value":3239},", timeout, connection error",{"type":345,"tag":534,"props":3241,"children":3242},{},[3243],{"type":354,"value":3244},"Retried on the schedule below.",{"type":345,"tag":346,"props":3246,"children":3247},{},[3248,3250,3255,3257,3262,3264,3270,3272,3278],{"type":354,"value":3249},"After a failed attempt, the next one is scheduled after ",{"type":345,"tag":350,"props":3251,"children":3252},{},[3253],{"type":354,"value":3254},"5 s, 5 min, 30 min, 2 h, 5 h, 10 h and 10 h",{"type":354,"value":3256},", for up to eight attempts within ",{"type":345,"tag":350,"props":3258,"children":3259},{},[3260],{"type":354,"value":3261},"48 hours",{"type":354,"value":3263}," of publication. A delivery that runs out of attempts is marked ",{"type":345,"tag":357,"props":3265,"children":3267},{"className":3266},[],[3268],{"type":354,"value":3269},"failed",{"type":354,"value":3271},", and it can be ",{"type":345,"tag":366,"props":3273,"children":3275},{"href":3274},"/docs/outbound/operating#recover-failed-deliveries-and-replay-missed-ones",[3276],{"type":354,"value":3277},"recovered",{"type":354,"value":3279}," for up to 35 days. Each endpoint is retried independently: one endpoint's failures never delay another endpoint's deliveries.",{"type":345,"tag":394,"props":3281,"children":3283},{"id":3282},"endpoint-states",[3284],{"type":354,"value":3285},"Endpoint states",{"type":345,"tag":504,"props":3287,"children":3288},{},[3289,3310],{"type":345,"tag":508,"props":3290,"children":3291},{},[3292],{"type":345,"tag":512,"props":3293,"children":3294},{},[3295,3300,3305],{"type":345,"tag":516,"props":3296,"children":3297},{},[3298],{"type":354,"value":3299},"State",{"type":345,"tag":516,"props":3301,"children":3302},{},[3303],{"type":354,"value":3304},"Deliveries",{"type":345,"tag":516,"props":3306,"children":3307},{},[3308],{"type":354,"value":3309},"How it gets there",{"type":345,"tag":527,"props":3311,"children":3312},{},[3313,3349,3370,3392],{"type":345,"tag":512,"props":3314,"children":3315},{},[3316,3325,3330],{"type":345,"tag":534,"props":3317,"children":3318},{},[3319],{"type":345,"tag":357,"props":3320,"children":3322},{"className":3321},[],[3323],{"type":354,"value":3324},"active",{"type":345,"tag":534,"props":3326,"children":3327},{},[3328],{"type":354,"value":3329},"Sent",{"type":345,"tag":534,"props":3331,"children":3332},{},[3333,3335,3341,3343,3348],{"type":354,"value":3334},"New endpoints. Any successful attempt returns a ",{"type":345,"tag":357,"props":3336,"children":3338},{"className":3337},[],[3339],{"type":354,"value":3340},"failing",{"type":354,"value":3342}," endpoint to ",{"type":345,"tag":357,"props":3344,"children":3346},{"className":3345},[],[3347],{"type":354,"value":3324},{"type":354,"value":613},{"type":345,"tag":512,"props":3350,"children":3351},{},[3352,3360,3365],{"type":345,"tag":534,"props":3353,"children":3354},{},[3355],{"type":345,"tag":357,"props":3356,"children":3358},{"className":3357},[],[3359],{"type":354,"value":3340},{"type":345,"tag":534,"props":3361,"children":3362},{},[3363],{"type":354,"value":3364},"Sent and retried",{"type":345,"tag":534,"props":3366,"children":3367},{},[3368],{"type":354,"value":3369},"5 failed attempts in a row, or one delivery that ran out of retries.",{"type":345,"tag":512,"props":3371,"children":3372},{},[3373,3382,3387],{"type":345,"tag":534,"props":3374,"children":3375},{},[3376],{"type":345,"tag":357,"props":3377,"children":3379},{"className":3378},[],[3380],{"type":354,"value":3381},"paused",{"type":345,"tag":534,"props":3383,"children":3384},{},[3385],{"type":354,"value":3386},"Skipped and recorded",{"type":345,"tag":534,"props":3388,"children":3389},{},[3390],{"type":354,"value":3391},"You paused the endpoint.",{"type":345,"tag":512,"props":3393,"children":3394},{},[3395,3404,3408],{"type":345,"tag":534,"props":3396,"children":3397},{},[3398],{"type":345,"tag":357,"props":3399,"children":3401},{"className":3400},[],[3402],{"type":354,"value":3403},"disabled",{"type":345,"tag":534,"props":3405,"children":3406},{},[3407],{"type":354,"value":3386},{"type":345,"tag":534,"props":3409,"children":3410},{},[3411,3413,3418,3420,3426],{"type":354,"value":3412},"The endpoint answered ",{"type":345,"tag":357,"props":3414,"children":3416},{"className":3415},[],[3417],{"type":354,"value":3199},{"type":354,"value":3419},", or ",{"type":345,"tag":357,"props":3421,"children":3423},{"className":3422},[],[3424],{"type":354,"value":3425},"auto_disable",{"type":354,"value":3427}," is on and 100 attempts in a row failed over at least 12 hours.",{"type":345,"tag":346,"props":3429,"children":3430},{},[3431,3433,3439,3441,3446],{"type":354,"value":3432},"Resuming a paused or disabled endpoint (",{"type":345,"tag":357,"props":3434,"children":3436},{"className":3435},[],[3437],{"type":354,"value":3438},"POST /v1/outbound/endpoints/{id}/resume",{"type":354,"value":3440},") reactivates it and resets its failure count. Messages skipped in the meantime are not sent automatically; ",{"type":345,"tag":366,"props":3442,"children":3443},{"href":3274},[3444],{"type":354,"value":3445},"replay them",{"type":354,"value":3447}," once the endpoint is ready.",{"type":345,"tag":346,"props":3449,"children":3450},{},[3451,3453,3459],{"type":354,"value":3452},"Endpoint failures belong to your customers' systems, so they never open incidents or send email to your account. Track them from ",{"type":345,"tag":366,"props":3454,"children":3456},{"href":3455},"/docs/outbound/operating#watch-endpoint-health",[3457],{"type":354,"value":3458},"endpoint health",{"type":354,"value":613},{"type":345,"tag":394,"props":3461,"children":3463},{"id":3462},"rotate-a-signing-secret",[3464],{"type":354,"value":3465},"Rotate a signing secret",{"type":345,"tag":346,"props":3467,"children":3468},{},[3469,3475,3477,3482,3484,3489,3491,3497],{"type":345,"tag":357,"props":3470,"children":3472},{"className":3471},[],[3473],{"type":354,"value":3474},"POST /v1/outbound/endpoints/{id}/secret/rotate",{"type":354,"value":3476}," returns a new secret. ",{"type":345,"tag":350,"props":3478,"children":3479},{},[3480],{"type":354,"value":3481},"For 24 hours, deliveries are signed with both the new and the previous secret",{"type":354,"value":3483},", so ",{"type":345,"tag":357,"props":3485,"children":3487},{"className":3486},[],[3488],{"type":354,"value":575},{"type":354,"value":3490}," carries two signatures and receivers that accept any match keep working while they switch to the new secret. You can't rotate again until the overlap ends. ",{"type":345,"tag":357,"props":3492,"children":3494},{"className":3493},[],[3495],{"type":354,"value":3496},"POST /v1/outbound/endpoints/{id}/secret/reveal",{"type":354,"value":3498}," returns the current secret.",{"type":345,"tag":714,"props":3500,"children":3501},{},[3502],{"type":345,"tag":401,"props":3503,"children":3507},{"className":3504,"code":3505,"language":3506,"meta":318,"style":318},"language-bash shiki shiki-themes github-dark","curl --user \"$RELAY_KEY:$RELAY_SECRET\" -X POST \\\n  https://my.webhookrelay.com/v1/outbound/endpoints/6f0c2c0e-5a3b-4f43-9d0a-4c4f7d7a2b11/secret/rotate\n# {\"secret\":\"whsec_…\"}\n","bash",[3508],{"type":345,"tag":357,"props":3509,"children":3510},{"__ignoreMap":318},[3511,3564,3572],{"type":345,"tag":411,"props":3512,"children":3513},{"class":413,"line":414},[3514,3519,3524,3529,3534,3539,3544,3549,3554,3559],{"type":345,"tag":411,"props":3515,"children":3516},{"style":788},[3517],{"type":354,"value":3518},"curl",{"type":345,"tag":411,"props":3520,"children":3521},{"style":838},[3522],{"type":354,"value":3523}," --user",{"type":345,"tag":411,"props":3525,"children":3526},{"style":748},[3527],{"type":354,"value":3528}," \"",{"type":345,"tag":411,"props":3530,"children":3531},{"style":737},[3532],{"type":354,"value":3533},"$RELAY_KEY",{"type":345,"tag":411,"props":3535,"children":3536},{"style":748},[3537],{"type":354,"value":3538},":",{"type":345,"tag":411,"props":3540,"children":3541},{"style":737},[3542],{"type":354,"value":3543},"$RELAY_SECRET",{"type":345,"tag":411,"props":3545,"children":3546},{"style":748},[3547],{"type":354,"value":3548},"\"",{"type":345,"tag":411,"props":3550,"children":3551},{"style":838},[3552],{"type":354,"value":3553}," -X",{"type":345,"tag":411,"props":3555,"children":3556},{"style":748},[3557],{"type":354,"value":3558}," POST",{"type":345,"tag":411,"props":3560,"children":3561},{"style":838},[3562],{"type":354,"value":3563}," \\\n",{"type":345,"tag":411,"props":3565,"children":3566},{"class":413,"line":423},[3567],{"type":345,"tag":411,"props":3568,"children":3569},{"style":748},[3570],{"type":354,"value":3571},"  https://my.webhookrelay.com/v1/outbound/endpoints/6f0c2c0e-5a3b-4f43-9d0a-4c4f7d7a2b11/secret/rotate\n",{"type":345,"tag":411,"props":3573,"children":3574},{"class":413,"line":432},[3575],{"type":345,"tag":411,"props":3576,"children":3577},{"style":769},[3578],{"type":354,"value":3579},"# {\"secret\":\"whsec_…\"}\n",{"type":345,"tag":346,"props":3581,"children":3582},{},[3583,3585,3591,3592,3598],{"type":354,"value":3584},"In the SDKs, use ",{"type":345,"tag":357,"props":3586,"children":3588},{"className":3587},[],[3589],{"type":354,"value":3590},"relay.outbound.endpoints.rotateSecret(id)",{"type":354,"value":3161},{"type":345,"tag":357,"props":3593,"children":3595},{"className":3594},[],[3596],{"type":354,"value":3597},"api.RotateOutboundEndpointSecret(id)",{"type":354,"value":613},{"type":345,"tag":3600,"props":3601,"children":3602},"style",{},[3603],{"type":354,"value":3604},"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":318,"searchDepth":432,"depth":432,"links":3606},[3607,3608,3612,3614,3615,3616],{"id":396,"depth":423,"text":399},{"id":646,"depth":423,"text":649,"children":3609},[3610,3611],{"id":709,"depth":432,"text":712},{"id":1923,"depth":432,"text":1926},{"id":3056,"depth":423,"text":3613},"Deduplicate on webhook-id",{"id":3098,"depth":423,"text":3101},{"id":3282,"depth":423,"text":3285},{"id":3462,"depth":423,"text":3465},"markdown","content:docs:outbound:3.receiving.md","content","docs/outbound/3.receiving.md","docs/outbound/3.receiving","md",{"loc":71},1791655669394]