Immutable solution version
Resend webhook signature verification in Node and Edge runtimes
Complete solution
Shows how to fix resend webhook signature verification in Node and Edge runtimes. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
Keep it in an environment variable, never in code. In Next.js App Router use req.text(). In Express, use express.raw() for the webhook route, not express.json().
When to use
You are seeing this: Resend signs webhooks using the Svix standard. Use this skill when you run into "Resend webhook signature verification in Node and Edge runtimes".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
Verify every Resend webhook: Svix signatures, raw body, Node and Edge
Resend signs webhooks using the Svix standard. Every request carries three headers: svix-id (unique message id), svix-timestamp, and svix-signature. Verification is required, not optional.
Steps
- Get the signing secret value it starts with whsec_, from the webhook create response or the dashboard. Keep it in an environment variable, never in code.
- Read the RAW request body. In Next.js App Router use req.text(). In Express, use express.raw() for the webhook route, not express.json(). Parsing and re-stringifying the JSON before verifying breaks the signature every time.
- Call the SDK verifier with the payload, the three headers, and the secret. In the resend Node SDK that is resend.webhooks.verify. It throws when the webhook is invalid.
- On success, handle the event and return 200. On verification failure, return 400 and log it. Never process an unverified payload.
- The svix-signature header can hold multiple space-separated v1 signatures (this is how secret rotation works: both secrets sign for 24 hours). Accept the request if ANY v1 signature verifies. Checking only the first breaks rotation.
The trap
The parsed-body trap: your framework helpfully parses JSON, you verify against the re-serialized string, and every legitimate webhook fails verification. Always verify against the exact bytes Resend sent. The second trap is skipping verification "temporarily" in development and shipping it. Webhook endpoints are unauthenticated POST URLs; without signature verification, anyone who finds the URL can inject fake delivery, bounce, and complaint events into your system.
Evidence
The Svix header set (svix-id, svix-timestamp, svix-signature), the whsec_ signing secret, the resend.webhooks.verify SDK call, and the raw-body requirement are documented in the official resend-skills webhooks reference at https://raw.githubusercontent.com/resend/resend-skills/HEAD/skills/resend/references/webhooks.md. The multiple-signature rotation behavior is documented in the same reference.
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_ccvqUcoBNe22rlNYaD62lA" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Resend webhook signature verification in Node and Edge runtimes <span>— Vectle</span></a>