DEV Community

Cover image for Stop Using ngrok for Webhook Testing (There's a Much Better Way Now)
Mahesh Srinivasan
Mahesh Srinivasan

Posted on • Edited on

Stop Using ngrok for Webhook Testing (There's a Much Better Way Now)

Debugging webhooks has always been… annoying.

If you've worked with Stripe, GitHub, or any webhook-based system, you probably know this flow:

  • Start your local server
  • Run ngrok
  • Copy the public URL
  • Paste it into your provider
  • Restart ngrok → URL changes
  • Repeat everything again

It works… but it's not smooth.

The Real Problems

After using this workflow for a while, I realized ngrok isn't just inconvenient — it has fundamental gaps:

  • URLs change on every restart — you're constantly updating provider dashboards
  • No replay — if you missed a request, it's gone
  • No visibility into what your server returned — you're debugging blind
  • Signature verification is manual — you write the HMAC check yourself every time
  • No history — you can't go back and look at past requests
  • Tunnel management is a whole side job

What I Wanted Instead

I wanted one tool that:

  • Gives me a stable, permanent URL for each provider I test against
  • Streams requests to my terminal in real-time
  • Forwards them to localhost automatically
  • Shows me what my server actually returned
  • Lets me replay missed requests with one command
  • Handles signature verification so I don't have to

So I Built Anonymily

A webhook development platform — not just a tunnel.

How It Works

Start your local server, then run:

npx @anonymilyhq/cli listen 3000
Enter fullscreen mode Exit fullscreen mode

You instantly get:

Forwarding to http://localhost:3000
Webhook URL: https://api.anonymily.com/h/abc12345
Enter fullscreen mode Exit fullscreen mode

Send your webhook to that URL. Anonymily captures it, streams it to your CLI in real-time, forwards it to localhost:3000, and captures your server's response — all in one shot.

POST /webhook 200 OK (120ms)
Enter fullscreen mode Exit fullscreen mode

What's Different From ngrok

Stable Named Endpoints (Pro)

This is the biggest quality-of-life upgrade. Instead of a random URL that changes every session, you can claim a permanent slug:

npx @anonymilyhq/cli listen 3000 --id stripe-dev --token <PAT>
Enter fullscreen mode Exit fullscreen mode

Your webhook URL is now https://api.anonymily.com/h/stripe-dev. Set it in your Stripe dashboard once and never touch it again — even if you restart the CLI, redeploy, or switch machines.

Replay Any Request

Missed a webhook while your server was down? Replay it:

npx @anonymilyhq/cli replay <hookId> <requestId>
Enter fullscreen mode Exit fullscreen mode

The CLI fetches the original request body, method, and headers, then re-sends it to your localhost. You can override the method or body inline, or re-sign the payload with your signing secret.

Response Capture

The CLI automatically captures what your local server returns and streams it back to the dashboard. You can see status code, latency, headers, and body — without touching your server logs.

Signature Verification Built In

Anonymily auto-detects and verifies HMAC signatures for Stripe, GitHub, Shopify, Slack, and Razorpay. You see immediately whether a request is valid or forged — before it even hits your code.

Real-Time Dashboard

Beyond the CLI, there's a full web dashboard at anonymily.com. Every request shows up instantly with headers, body, the signature verification result, your server's response, and a one-click replay button.

Search and Filter

When you've got hundreds of test requests piling up, you can filter by method, status code, or search across headers and body to find exactly what you need.

AI Features (Pro)

This is where it gets interesting for debugging.

AI Diagnosis — When something goes wrong (signature mismatch, 500 from your server, unexpected payload shape), you can ask for an AI diagnosis. It reads the full exchange — request, signature result, your server's response — and explains exactly what went wrong and how to fix it.

AI Handler Generation — Point it at a captured request and it generates a production-ready handler in Express, Next.js, or NestJS, grounded in your actual payload shape. Not a generic template — code that handles your specific webhook structure.

Synthetic Event Triggers — Fire realistic test events for any supported provider without needing the real service to send them:

npx @anonymilyhq/cli trigger stripe payment_intent.succeeded --hook stripe-dev --token <PAT>
Enter fullscreen mode Exit fullscreen mode

Events are correctly signed with your hook's signing secret.

Use It From Claude Code (MCP)

If you use Claude Code, you can connect Anonymily as an MCP server and call all these features directly from your AI assistant:

{
  "mcpServers": {
    "anonymily": {
      "command": "npx",
      "args": ["@anonymilyhq/mcp-server"],
      "env": {
        "ANONYMILY_TOKEN": "<your-PAT>"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

From there, Claude can list your captured requests, replay them, trigger synthetic events, and generate handler code — all without leaving your editor.

Pricing

Free — No account needed. Get a random endpoint instantly. 200 requests stored, 48-hour history, 5 replays per day.

Pro ($9/month) — Custom named endpoints, 2,000 requests stored, 30-day history, unlimited replays, signature verification, AI features, signing secrets.

The free tier requires zero signup. If you just want a quick endpoint to test a webhook right now, run the npx command and you're done.

Works With Anything

  • Stripe webhooks
  • GitHub events
  • Shopify hooks
  • Slack events
  • Razorpay payment events
  • Any custom HTTP webhook

If it sends HTTP requests, it works.

Try It

npx @anonymilyhq/cli listen 3000
Enter fullscreen mode Exit fullscreen mode

That's it. No install, no account, no config.

If you're building something that involves webhooks — local dev, CI testing, provider integration — give it a try:

👉 https://anonymily.com

Feedback Welcome

This is still early, and I'm actively iterating. Would love to hear:

  • What's missing for your workflow?
  • What providers would you want synthetic events for?
  • Any friction in the CLI or dashboard?

Drop thoughts below or open an issue. 👇

Top comments (0)