webhook.site earned its place: it hands you a URL instantly, no account, and every request that hits it shows up in the browser. That is exactly what you need at 2 a.m. when a provider refuses to deliver and you want to see what it sends. It is also, by design, a public endpoint: the URL is the only secret, and anyone who has it sees every payload that arrives — which is why teams eventually look for an alternative.

What people actually want from a catcher

  • A URL that is not a public bucket. Payloads here contain real tokens, customer emails, signed links and sometimes personal data.
  • Revocation. When the debugging session ends, the URL should stop accepting traffic.
  • History, not just the last request. Retries from a provider are the interesting part: comparing attempt 1 with attempt 4 explains most integration bugs.
  • Read-only sharing. A teammate should be able to watch the traffic without holding the account.
  • Machine-readable output. A script (or an AI assistant) should be able to read the captured request without screenshots.
  • A clear answer to “where does this live, and for how long?” — especially if your test payloads are close to production data.

The options

Option What it is Trade-off
webhook.site hosted catcher, URL without an account the URL is the only credential; requests live on their servers; the free tier has limits and URLs can expire
RequestBin-style services (for example Pipedream) hosted catcher with a dashboard and an account accounts and limits; still a third party holding the payloads
A tunnel (ngrok, cloudflared) exposes your local server to the internet it is a transport, not a catcher: no history, no sharing, and the URL usually changes
Production webhook infrastructure (Hookdeck and friends) delivery, retries and queues for real traffic it is built for production webhooks, not for reading one payload by hand
This instance hosted private catcher with accounts, share links and a JSON export not self-hostable, and it is not free of accounts (one user per developer)
Your own endpoint 30 lines that log to disk full control, and full ownership of uptime, retention and access

How this instance answers the checklist

Concern What happens here
Who can see the payload only accounts of this instance; a URL is secret, and access is authenticated
Revocation the URL can be deleted, and shared links expire and can be revoked at any time
Indexing every capture and share link answers noindex, nofollow, noarchive, so a payload with a real token never ends up in a search index
History every request is kept (with the retention window configured on the instance), retries included — compare attempt 1 with attempt 4
Sharing read-only links with an expiry, revocable, no account needed for the reader
Machine-readable a share link answers as JSON or plain text, so scripts and AI assistants can read it
Email too the same address accepts SMTP, so mail and callbacks are in one place

If self-hosting is a hard requirement

A catcher is a small service, and writing your own is a legitimate option: accept any method, store method, path, headers, body and time, render a page, protect it with a token. What you then own is the boring part — uptime, retention, disk space and a way to revoke access that is not "delete the container". Run your own if the payloads must never leave your infrastructure; use a hosted catcher if the point is not to maintain anything. The two requirements contradict each other, so decide which one you actually have.

Moving off a public catcher in four steps

  1. Create a catcher URL in the tool you picked, and treat its token as a credential rather than a link to paste into chat.
  2. Register the new URL with the provider (Stripe, GitHub, Telegram …) and trigger one event.
  3. Confirm the request arrived whole — method, path, query, headers, body and client IP. A capture missing the body usually means the provider sent a content type you did not expect.
  4. Delete the old endpoint after the first successful delivery, and if the old URL was shared anywhere, assume whatever it captured has been read.

If you chose the public service because it needed no account, that is the one thing you give up here — and in exchange the URL stops being readable by whoever happens to find it.

Next steps