validateWebhookSignature()v3.2.30
Validates that the signature that was received by a webhook endpoint is authentic. If the validation fails, an error is thrown.
API
The function accepts an object with three key-value pairs:
secret
The same webhook secret that was passed to renderMediaOnLambda()'s webhook options.
body
The body that was received by the endpoint.
Pass the raw request body - a string or a Buffer - to check the exact bytes that were signed. A parsed JSON object is accepted as well, but it is serialized again before it gets hashed, which only produces the same signature if parsing and serializing round-trips exactly. The Go, Python, PHP and Ruby helpers take the raw request body.
signatureHeader
The X-Remotion-Signature header from the request that was received by the endpoint.
Example
In the following Next.JS webhook endpoint, an error gets thrown if the signature does not match the one expected one or is missing..
pages/api/webhook.tsimport {validateWebhookSignature ,WebhookPayload } from '@remotion/lambda/client'; export default async functionhandler (req :NextApiRequest ,res :NextApiResponse ) {validateWebhookSignature ({secret :process .env .WEBHOOK_SECRET as string,body :req .body ,signatureHeader :req .headers ['x-remotion-signature'] as string, }); // If code reaches this path, the webhook is authentic. constpayload =req .body asWebhookPayload ; if (payload .type === 'success') { // ... } else if (payload .type === 'timeout') { // ... }res .status (200).json ({success : true, }); }
See Webhooks for an Express example.
Verifying the raw bodyv4.0.538
The signature covers the exact bytes that were sent, so the most reliable way to verify a request is to read the body first and verify it before decoding it. Parsing the JSON and serializing it again can reorder keys and change whitespace, which would make a genuine request fail the check.
The following Express endpoint keeps the raw bytes around for that:
server.jsimport express from 'express'; import {validateWebhookSignature} from '@remotion/lambda/client'; const router = express(); // Keep the raw bytes so they can be checked against the signature. const rawParser = express.raw({type: 'application/json'}); router.post('/webhook', rawParser, (req, res) => { validateWebhookSignature({ secret: process.env.REMOTION_WEBHOOK_SECRET, body: req.body, signatureHeader: req.header('X-Remotion-Signature'), }); // The request is authentic. Parse the body only now. const payload = JSON.parse(req.body.toString()); if (payload.type === 'success') { // ... } res.status(200).json({success: true}); });
Passing a parsed JSON object still works, and keeps the examples above short. The body is then serialized again before it gets hashed, so it only matches the signature if parsing and serializing round-trips exactly.
Compatibility
| Servers | Environments | |||||
|---|---|---|---|---|---|---|
Node.js | Bun | Serverless Functions | ||||
Node.js runtime | ||||||
For serverless functions, use the light client.