Requex.me LogoRequex.me

Documentation

Browse by section

Keep all guides, tool docs, automation recipes, and comparison pages in one navigable place.

Docs Home
Docs

Foundation docs for getting started fast, understanding key terms, and tracking what has changed.

Guides

Start with fundamentals, then move into provider-specific webhook testing and production hardening.

Tool Docs

These pages explain what each tool does, when to use it, and how it fits into a webhook debugging workflow.

Automation Docs

Use these setup guides when you want forwarding rules, custom responses, security checks, or multi-destination fanout.

Compare

Use these pages to compare developer workflows, pricing tradeoffs, and feature differences between webhook tools.

Looking to edit the custom response on webhook.site for free? That's a different topic — see how to edit webhook.site responses without paying →

How to Test Webhooks on Localhost in 2026?

Requex.me provides the ultimate guide and toolset for testing webhooks on localhost, enabling developers to receive, inspect, and replay HTTP requests from services like Stripe and GitHub that cannot natively reach local developer machines. This guide covers three approaches to receive, inspect, and debug webhooks during local development.

Last updated: April 2026 • 11 min read • 2026 Version

What is the localhost webhook problem?

When developing locally, your application typically runs on http://localhost:3000 or a similar local address. External services like Stripe, GitHub, or Shopify cannot reach this address because it's behind your router's NAT, your firewall, or simply not connected to the public internet.

This creates a fundamental challenge: webhooks need a publicly accessible URL to deliver events. You can't tell Stripe to send webhook events to http://localhost:3000/webhooks: it would simply fail with a connection error.

Three approaches exist, each with different trade-offs.

Capture and Replay

The simplest approach is to capture webhook payloads online and replay them locally. This two-step process separates receiving from processing and gives you complete control over both.

Step 1: Capture with Requex.me

Visit Requex.me and copy your unique webhook URL. Configure your provider (Stripe, GitHub, etc.) to send webhooks to this URL. Trigger an event and the incoming request appears instantly in your dashboard.

Inspect the full request: headers, body, query parameters. Copy the JSON payload to your clipboard using the built-in copy button.

Step 2: Replay Locally with cURL

Now paste the captured payload into a cURL command and send it to your local server:

curl -X POST http://localhost:3000/api/webhooks \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Signature: abc123..." \
  -d '{"type":"payment_intent.succeeded","data":{"object":{...}}}'

This approach has several advantages: you can replay the same event dozens of times while debugging, you don't need any tunnel software, and you can modify the payload to test edge cases before sending it.

💡 Pro Tip: Save your captured payloads as JSON files in a test fixtures folder. This way, you can build automated tests that replay real-world webhook data.

Tunneling (ngrok, Cloudflare Tunnel)

Tunneling creates a public URL that forwards traffic directly to your local server. The most popular tool is ngrok, which creates a secure tunnel from a public URL to your localhost.

# Install ngrok
brew install ngrok  # macOS
# or download from ngrok.com

# Start a tunnel to your local server
ngrok http 3000

# Output:
# Forwarding: https://abc123.ngrok.io -> http://localhost:3000

Copy the https://abc123.ngrok.io URL and use it as your webhook endpoint. All requests will be forwarded to your local server in real-time.

Pros and Cons of Tunneling

Pros

  • • Real-time forwarding to localhost
  • • Works with any webhook provider
  • • HTTPS support out of the box

Cons

  • • URL changes every time you restart (free tier)
  • • Adds latency to requests
  • • Requires internet connection
  • • Free tier has rate limits

Provider CLI Tools

Some webhook providers offer their own CLI tools that can forward events to your localhost. These are often the most reliable option because they're purpose-built for their specific webhook format.

Stripe CLI

# Install Stripe CLI
brew install stripe/stripe-cli/stripe

# Login to your Stripe account
stripe login

# Forward webhook events to your local server
stripe listen --forward-to localhost:3000/api/webhooks

# Trigger a test event
stripe trigger payment_intent.succeeded

GitHub CLI

GitHub doesn't have a built-in forwarding CLI, but you can use their webhook delivery logs in the repository settings to redeliver events. Combined with a tunnel, this provides a complete local testing experience.

When No CLI Exists

For providers without a CLI tool (most smaller SaaS platforms), the capture-and-replay approach with Requex.me is your best bet. It works universally with zero provider-specific setup.

Comparison: Which Approach Should You Use?

ApproachBest ForDifficulty
Capture & ReplayInitial development, learning payload structuresEasy
Tunneling (ngrok)Real-time integration testingMedium
Provider CLIProvider-specific deep testingMedium

Best Practices for Local Webhook Development

  • 1. Save real payloads as test fixtures. Every unique webhook payload you capture should be saved as a JSON file you can replay in automated tests.
  • 2. Separate development and production webhook secrets. Never use your production signing secret when testing locally.
  • 3. Test idempotency by replaying events multiple times. Your handler should produce the same result whether an event is processed once or five times.
  • 4. Simulate failures. Use custom response codes in Requex.me to return 500 errors and test your provider's retry behavior.
  • 5. Log everything during development. Log the raw request body, parsed payload, and every processing step. Remove verbose logging before going to production.
  • 6. Use environment variables to switch between test and production webhook URLs automatically.

Common Local Webhook Errors (and How to Fix Them)

Connection refused on localhost:3000

Your local server isn't running, or it's listening on a different port. Run lsof -i :3000 to check what's using the port, or look at your app's startup logs for the actual port number.

Signature verification fails on replayed payloads

When you replay a captured payload, the X-Signature header was computed for the original URL and timestamp. Your handler will reject it if you verify signatures strictly. During local testing, disable signature verification or use your provider's test signing secret specifically for development.

ngrok URL changes on every restart

The free tier of ngrok generates a random URL on every startup. You'll need to update your webhook URL in the provider dashboard each time. Workarounds: use ngrok's paid static domain, or switch to Cloudflare Tunnel which allows persistent hostnames for free.

Provider stops retrying before you can test

If your local server was down when the provider first tried to deliver, you may have missed the retry window. Use the capture-and-replay approach instead: capture the payload to Requex.me first, then replay it manually to your localhost as many times as you need.

Quick Reference: Local Webhook Testing Commands

Copy these commands for the most common local testing tasks:

Replay a captured JSON payload to localhost:

curl -X POST http://localhost:3000/webhooks \
  -H "Content-Type: application/json" \
  -d @payload.json

Start an ngrok tunnel:

ngrok http 3000

Forward Stripe events to localhost:

stripe listen --forward-to localhost:3000/webhooks

Trigger a specific Stripe test event:

stripe trigger payment_intent.succeeded

Language-Specific Webhook Handlers

Once you've captured and replayed a payload, you'll need to write the handler. These guides cover complete implementations for each language:

Start Capturing Webhooks Now

Get a free public URL to capture payloads. Replay them locally for debugging.

Open Webhook Tester →