Webhook tester: see every request, then misbehave on purpose
Most webhook testers answer one question: what did my service send? This one also answers the expensive question: what does my service do when the receiver is slow, flaky or down? You get a URL that logs every request and answers with exactly the status, delay, error rate or scripted failure you choose.
How it works
Create an endpoint
You get a URL like https://your-slug.supercrontab.com/ that accepts any method on any path, including trailing slashes and sub-paths.
Point your service at it
Paste the URL where your app, Stripe, GitHub or Zapier expects a webhook target, then send a test event.
Read the log
Every request is stored with method, path, query, headers, up to 16 KB of body, the caller IP and the status you answered with.
Shape the response
Return any status, body and headers, add a delay, fail a percentage of calls, or script a fault sequence per Idempotency-Key.
What a logged request looks like
Send anything to your URL and it shows up in the endpoint's log on refresh. Credential headers are redacted before storage; everything else is kept as sent.
curl -i -X POST https://your-slug.supercrontab.com/orders/42 \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 7f3c9a10' \
-d '{"type":"invoice.paid"}'2026-09-20 09:14:02 UTC POST /orders/42 202 203.0.113.24
content-type: application/json
idempotency-key: 7f3c9a10
user-agent: Stripe/1.0 (+https://stripe.com/docs/webhooks)
stripe-signature: t=1789895642,v1=5257a869e7ecebeda32a...
authorization: [redacted]
{"id":"evt_1Q2w","type":"invoice.paid","data":{"object":{"id":"in_1Q2v","amount_paid":600}}}The same log is available as JSON from GET /v1/endpoints/{id}/requests, so a CI job can assert on what your service sent.
Webhook cheat sheet: signatures, deadlines and retries
What the big senders put in the request, how long they wait, and what they do when you fail. The deadline column is the number to beat with the delay setting when you test timeouts. Providers change these; check their docs before you rely on a number.
| Sender | Signature header | How it is signed | Answer within | On failure |
|---|---|---|---|---|
| Stripe | Stripe-Signature | HMAC-SHA256 over "timestamp.body", sent as t=...,v1=... | answer 2xx promptly, before doing slow work | retries with backoff for up to 3 days in live mode |
| GitHub | X-Hub-Signature-256 | HMAC-SHA256 of the raw body, hex, prefixed sha256= | 10 seconds | no automatic retry; failed deliveries are redelivered by hand or API |
| Slack Events API | X-Slack-Signature | HMAC-SHA256 over "v0:timestamp:body", prefixed v0= | 3 seconds | up to 3 retries, marked with X-Slack-Retry-Num |
| Shopify | X-Shopify-Hmac-Sha256 | HMAC-SHA256 of the raw body, base64 | 5 seconds | retries over several hours, then removes the subscription after repeated failures |
| Twilio | X-Twilio-Signature | HMAC-SHA1 over the full URL plus sorted POST params, base64 | 15 seconds | no retry by default; configurable per webhook |
Five tests worth running
Each one is a setting on the endpoint form, not code. The second uses fault sequences, which make a specific failure reproducible in CI.
Does my sender time out correctly?
Set the delay just above the provider deadline (11,000 ms for GitHub, 3,500 ms for Slack) and answer 200. A correct sender gives up and treats it as failed even though the status was fine.
Does a retry create a duplicate?
Use a fault sequence: step one drop, step two respond 200. The first delivery is logged and cut, the retry with the same Idempotency-Key succeeds. You should see two requests in the log and one side effect in your system.
What happens when the receiver is flaky?
Status 202, delay 3,000 ms, error rate 10%. One call in ten returns your error status. Leave it running for a day and count what your sender lost.
Do I sign requests correctly?
Turn on inbound auth: Basic, Bearer, an API key header, or HMAC-SHA256 of the raw body in hex with an optional prefix (the GitHub scheme). A wrong signature gets 401, and a failed auth never consumes a sequence step.
Does my alerting fire?
Answer 500 for every call and wait. If nothing pages you within the window you expect, you found the gap before production did.
When another tool is the better pick
If you need a throwaway URL in five seconds and never want to see it again, an anonymous request bin is faster: there is no signup. If you need to forward webhooks to localhost, a tunnel such as ngrok or Cloudflare Tunnel does that and this does not.
Use this one when the URL should still exist tomorrow, when the log must be private to you, when you want the receiver to fail in a controlled way, or when you want a scheduled job calling the same endpoint so the whole loop is tested end to end.
Questions
Is the webhook tester free?
Yes. The free plan has 3 endpoints, 30 requests a minute and 500 a day, keeps the newest 25 requests per endpoint, and does not expire. Paid plans raise those limits.
Why do I need an account to receive webhooks?
Anonymous receivers get used as drop boxes for data nobody should be storing. Tying each receiver to an account keeps logs private to you and lets you delete them. If you only need to see a canned response, the 112 demo endpoints need no account.
Are secrets in the request stored?
Authorization, Cookie, Proxy-Authorization, X-Api-Key and X-Signature headers are redacted before the request is written to the log. Bodies are stored as sent, up to 16 KB, so do not send production secrets in the body.
Can it verify Stripe or Slack signatures?
Not directly. Those schemes sign a timestamp together with the body, while the built-in HMAC check covers a plain HMAC-SHA256 of the raw body (the GitHub scheme). For Stripe and Slack, read the signature header from the log and verify it in your own code.
Can I replay a logged request to my local machine?
Not yet. Today you copy the logged body and headers into curl. Replaying to another URL and exporting a log as HAR are the two features planned next.
How is a dropped connection simulated?
The endpoint runs on Cloudflare Workers, which can cut a response in the middle of the body but not before the status line. A drop step therefore looks like a truncated response: curl exits with code 18, and most HTTP clients raise a read error, which is the same retry path as a reset.