Public Beta: Direct engineering support available. Join Discord →
Guides
How do I test a webhook without sending real data?

How do I test a webhook without sending real data?

Save one sample payload per event type, sign it with a test secret exactly the way the sender signs, and POST it to your own endpoint. Your handler cannot tell it from a real event, so the test exercises signature checking, parsing and your writes with no real customer or order behind it. Point it at a local or staging endpoint configured with the test secret, never at production.

Send a signed test event

import { createHmac } from 'node:crypto'
 
// POST a saved sample payload to your endpoint, signed the way the sender signs.
// The defaults are hex-encoded HMAC-SHA256 over the raw body with no prefix;
// set header, encoding ('hex' or 'base64') and prefix to match your sender.
export async function sendTestWebhook ({ url, secret, payload, header = 'x-signature', encoding = 'hex', prefix = '', fetchImpl = fetch }) {
  const body = JSON.stringify(payload)
  const signature = prefix + createHmac('sha256', secret).update(body).digest(encoding)
  const res = await fetchImpl(url, {
    method: 'POST',
    headers: { 'content-type': 'application/json', [header]: signature },
    body,
  })
  return res.status
}

Match the sender's scheme

The header, the encoding and the prefix are part of the contract; get one wrong and your own verifier rejects the test. The recipes state each sender's values — for example GitHub sends a hex digest prefixed with sha256= in x-hub-signature-256, and QuickBooks sends a base64 digest with no prefix in intuit-signature. Stripe signs a timestamp together with the body, and Square signs the notification URL together with the body, so neither matches this body-only function.

What this does not test

Whether the sender actually delivers to your URL. Once your handler passes, send one test event from the sender's own dashboard and confirm it arrives.

Need somewhere for the next project's webhooks to land? Slashbin's Free plan takes an account, not a card.

Start Free

(opens in a new tab)

Related