verifyWebhook
Constant-time HMAC-SHA256 verification for inbound Sonny Labs webhook deliveries, plus VerifyWebhookOptions for replay-window tolerance and clock injection.
verifyWebhook validates the Sonny-Signature header on an inbound
webhook delivery. The backend signs each delivery with
Sonny-Signature: t=<unix>,v1=<hex> where <hex> is
HMAC-SHA256(secret, "${t}.${body}"). Receivers must verify the MAC
and reject deliveries whose timestamp falls outside a 5-minute
replay window — the helper enforces both in one call.
Signature
import { verifyWebhook } from "@sonnylabs/sdk";
function verifyWebhook(
body: string | Uint8Array,
header: string,
secret: string,
options?: VerifyWebhookOptions,
): boolean;Returns true if both the HMAC and the timestamp window check
pass; false otherwise. Never throws on a malformed header — that's
just an invalid signature.
| Parameter | Description |
|---|---|
body | The raw request body bytes (NOT a re-serialised object). HMAC is computed over the exact bytes the server signed. |
header | The value of the Sonny-Signature header. |
secret | The webhook signing secret returned at webhook registration / rotation. Store in your secrets manager; never log it. |
options | Optional VerifyWebhookOptions — replay-window tolerance and a clock-injection hook for unit tests. |
import express from "express";
import { verifyWebhook } from "@sonnylabs/sdk";
const app = express();
app.post(
"/webhooks/sonny",
// Express must give us the raw bytes — re-serialising via express.json()
// breaks HMAC verification.
express.raw({ type: "*/*" }),
(req, res) => {
const ok = verifyWebhook(
req.body,
req.header("sonny-signature") ?? "",
process.env.SONNY_WEBHOOK_SECRET!,
);
if (!ok) return res.status(400).send("invalid signature");
// ... process the event
res.status(204).end();
},
);VerifyWebhookOptions
Prop
Type
ProblemEnvelope
The duck-typed RFC 9457 application/problem+json shape the SDK consumes, plus the per-field ProblemFieldError used by validation errors.
Python SDK reference
Auto-generated symbol reference for sonnylabs (PyPI) — every public class, method, options bag, exception subclass, and helper, rendered from the docstrings on the source.