WebhookToolkit
GitHub

Test a GitHub webhook locally

To validate a GitHub webhook handler, there's no need to push commits or open real PRs. Generate a GitHub event signed with HMAC-SHA256, edit the payload (repo, branch, author) and send it to your local server. Your X-Hub-Signature-256 verification is tested right away.

Generate the signature to see the headers, the body and a ready-to-paste cURL command.

Verify the signature server-side

handler.js (Node)
import crypto from 'crypto';
const sig = req.headers['x-hub-signature-256'];
const expected = 'sha256=' + crypto
  .createHmac('sha256', process.env.WEBHOOK_SECRET)
  .update(rawBody)
  .digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));

To receive a real GitHub webhook on your machine without deploying, set the URL of your Relay tunnel in the repo settings.

Frequently asked questions

How do I simulate a GitHub push on my local server?

Pick the push event above, paste the webhook secret configured in your repo, enter your handler's URL (via Relay), then send. The X-Hub-Signature-256 header is computed with HMAC-SHA256 just like GitHub does.

What's the difference between X-Hub-Signature and X-Hub-Signature-256?

X-Hub-Signature uses SHA-1 (legacy), X-Hub-Signature-256 uses SHA-256 (recommended). The generator produces both headers to cover every case.

How do I verify the signature server-side?

Compute HMAC-SHA256(rawBody, secret) and compare it in constant time with the header value (after 'sha256='). See the code example below.

Can I test pull_request and issues too?

Yes, the push, pull_request and issues events are available, each with the correct X-GitHub-Event header.

Test a GitHub webhook locally — X-Hub-Signature-256 signed payload · Webhook Toolkit