Prompt
I’m building a local dev setup for testing webhooks from external providers
Latest observation
Oct 5, 2026
OpenAI APIWeb search: off
A solid local webhook-testing setup usually has 3 parts:
- Your local app
- A public tunnel so the external provider can reach your machine
- Request inspection/logging so you can see exactly what arrived
Recommended options
1) Use a tunnel tool
These expose localhost to the internet temporarily:
- ngrok — very common, easy to use, good dashboard
- Cloudflare Tunnel — great if you already use Cloudflare
- Tailscale Funnel — useful in Tailscale environments
- Localtunnel — simple, lightweight
- SSH reverse tunnel — good if you control a VPS
If you want the fastest path, ngrok is usually the easiest starting point.
Example:
ngrok http 3000
Then configure the webhook provider to call the generated public URL, like:
https://abc123.ngrok.io/webhook
2) Add a webhook receiver endpoint locally
Your app should:
- accept
POSTrequests - log headers and raw body
- verify signatures if the provider uses them
- return a fast
2xxresponse
Example Node/Express:
import express from 'express';
const app = express();
// Need raw body for signature verification in many providers
app.post('/webhook', express.raw({ type: '*/*' }), (req, res) => {
console.log('Headers:', req.headers);
console.log('Body:', req.body.toString('utf8'));
res.sendStatus(200);
});
app.listen(3000, () => console.log('Listening on 3000'));
3) Inspect and replay requests
Useful tools:
- RequestBin / webhook.site for quick inspection
- ngrok inspector for replaying requests
- mitmproxy if you want deeper traffic inspection
- local logging to file/JSON for test automation
4) Handle common webhook issues
Signature verification
Many providers require the exact raw payload and specific headers. Don’t parse JSON before verifying if the signature depends on the raw body.
Retry behavior
Most providers retry on non-2xx responses. Your handler should be idempotent.
Local environment variables
Keep secrets separate from code:
WEBHOOK_SECRET=...
Multiple services
If you’re testing several providers, route them to different local paths:
/webhooks/stripe/webhooks/github/webhooks/shopify
5) A practical dev workflow
- Start your app locally
- Start a tunnel
- Copy the tunnel URL into the provider’s webhook settings
- Trigger a test event from the provider
- Inspect logs / raw payload / signature verification
- Use replay tools to iterate quickly
Suggested stack
If you want a simple, reliable setup:
- Express/FastAPI/Flask local receiver
- ngrok or Cloudflare Tunnel
- structured logging to console
- optional: Docker Compose if you want repeatability
Security notes
- Don’t expose a debug endpoint publicly without access controls
- Rotate webhook secrets if you share URLs widely
- Validate source/signature when possible
- Avoid logging sensitive data in plaintext
If you want, I can help you set up:
- a Node.js webhook dev server
- a Python/FastAPI version
- a Docker Compose setup
- or a provider-specific setup like Stripe/GitHub/Shopify