hooksig

Webhook signatures, demystified

See how every webhook is signed.

One reference for how ten providers build and verify a signature, and one zero-dependency library to verify them in code. Paste a payload and secret below, then flip a byte and watch it break.

npm i hooksig

Try it โ€” live, in your browser

HMAC-SHA256 ยท hex ยท timestamped
Request โ€” edit anything
Verify this in code
import { verify } from "hooksig";

const result = await verify("stripe", {
  payload: rawBody,            // the RAW body, not parsed JSON
  headers: request.headers,
  secret: env.WEBHOOK_SECRET,
});

if (!result.verified) {
  return new Response(result.reason, { status: 400 });
}
no match โ€” signature invalid
Signed string
HMAC-SHA256( secret, signed string ) = expected
Expected vs provided
expected
provided
How it's built

    How it works

    1. Install

      One package, zero runtime dependencies.

      npm i hooksig
    2. Verify

      The same typed call for every provider. Pass the raw body, headers, and your secret.

      import { verify } from "hooksig";
      
      const result = await verify("stripe", {
        payload: rawBody,          // the RAW request body, not parsed JSON
        headers: request.headers,
        secret: env.STRIPE_WEBHOOK_SECRET,
      });
      
      if (!result.verified) {
        return new Response(result.reason, { status: 400 });
      }
    3. Ship

      It is built on WebCrypto alone, so it runs unchanged on Cloudflare Workers, Bun, Deno, and Node.

    Providers ยท 10

    Why hooksig

    Pricing

    $0

    Free and MIT licensed, forever. hooksig is a library you run, not a service you pay for. The reference site is free too.