# 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
1. 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.
2. 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.
3. 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.
4. On success, handle the event and return 200. On verification failure, return 400 and log it. Never process an unverified payload.
5. 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.