API
Verify Webhook Signatures
Validate NOCK webhook requests with HMAC-SHA256 before triggering side effects.
Every NOCK webhook includes a signature so your endpoint can prove the request came from NOCK and was not modified in transit.
Signature format
NOCK sends:
x-nock-signature: t=<timestamp>,v1=<hex_hmac>
x-nock-timestamp: <timestamp>The HMAC message is:
<timestamp>.<raw request body>The algorithm is HMAC-SHA256 using the endpoint signing secret shown when the webhook is created.
Node.js verification
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyNockWebhook({
rawBody,
secret,
signatureHeader,
timestampHeader,
}: {
rawBody: string;
secret: string;
signatureHeader: string;
timestampHeader: string;
}) {
const timestamp = Number(timestampHeader);
if (!Number.isFinite(timestamp)) return false;
const ageSeconds = Math.abs(Date.now() / 1000 - timestamp);
if (ageSeconds > 300) return false;
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const received = signatureHeader
.split(',')
.find((part) => part.startsWith('v1='))
?.slice(3);
if (!received) return false;
const receivedBuffer = Buffer.from(received, 'hex');
const expectedBuffer = Buffer.from(expected, 'hex');
if (receivedBuffer.length !== expectedBuffer.length) return false;
return timingSafeEqual(receivedBuffer, expectedBuffer);
}Implementation checklist
- Read the raw request body before parsing JSON.
- Reject requests older than 5 minutes.
- Use constant-time comparison for the HMAC.
- Use
x-nock-deliveryor payloadidfor idempotency. - Return a 2xx response only after your consumer has accepted the event.
Warning
Do not verify against a prettified or re-stringified JSON body. The signature is calculated over the exact raw body bytes sent by NOCK.