Test GitHub webhooks (and verify the signature)

Before wiring a GitHub webhook into your app, it helps to see real deliveries: which events fire, what the payload looks like, and whether your secret produces the signature you expect.

1. Get a capture URL

$ curl https://catchhook.catchhook.workers.dev/new

2. Add it as a webhook on your repo

Repo → Settings → Webhooks → Add webhook:

GitHub immediately sends a ping event. Open your bin dashboard and it's there — including headers like X-GitHub-Event, X-GitHub-Delivery and X-Hub-Signature-256.

3. Verify the signature

In the bin's settings, choose GitHub as the signature scheme and paste the same secret. Every capture now shows a ✓ sig or ✗ sig badge, computed as HMAC-SHA256(secret, raw body) against the X-Hub-Signature-256 header — so you can confirm your secret handling before writing the verification code in your app.

Reference implementation for your handler (Node):

import crypto from 'node:crypto';
const sig = 'sha256=' + crypto.createHmac('sha256', secret)
  .update(rawBody).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(sig),
  Buffer.from(req.headers['x-hub-signature-256']));

Gotcha: always HMAC the raw request bytes, not the re-serialized JSON — re-serialization reorders keys and changes whitespace, which breaks the signature.

4. Push events to your real handler

Trigger a real event (push a commit, open an issue). When your handler is ready, use Replay on any capture to re-send it to your real endpoint — no need to keep pushing commits — or set auto-forward so every delivery is proxied to your dev server while you still see each one in the dashboard.

No signup needed. Or from your terminal: curl https://catchhook.catchhook.workers.dev/new

← All guides · Docs · CatchHook vs webhook.site