Requex.me LogoRequex.me

Webhook FAQ

Real answers from someone who's debugged webhooks way too many times.

Q

What is Requex.me?

Requex.me is a free webhook testing and automation platform. It gives you an instant HTTPS webhook URL that captures every request in real time, and lets you return custom responses (any status code, custom headers and body, delays up to 30 seconds), forward requests to multiple destinations with automatic retries, host mock API servers, run scheduled cron jobs, and build no-code automation workflows with 30+ nodes including AI steps. Basic webhook testing needs no signup. Unlike webhook.site, custom responses on Requex.me are free instead of $9/month.
Q

How do I test a webhook without ngrok?

Use a hosted webhook URL instead of a tunnel. Requex.me generates a public HTTPS URL in one click, point Stripe, GitHub, Shopify, or any provider at it and every request appears in the dashboard in real time, with full headers, body, and query parameters. No install, no ngrok account, no tunnel that dies when your laptop sleeps. To get a captured payload into your local app, copy it and replay with curl or Postman, or set a forwarding rule. Full walkthrough: local webhook testing guide.
Q

How do I get a free webhook URL?

Open requex.me and a unique HTTPS webhook URL is generated instantly, no signup, no credit card. The URL accepts every HTTP method (GET, POST, PUT, PATCH, DELETE) and shows each incoming request live: headers, raw body, query parameters, and timestamp. The URL stays active, and creating an account later lets you keep it permanently and manage multiple webhooks.
Q

What is the best free RequestBin alternative?

Requex.me is a free RequestBin replacement. The original RequestBin was discontinued, and the current version requires a Pipedream account and workflow setup. Requex.me gives you an instant request bin with no login: real-time request inspection, custom response codes, and forwarding. Feature-by-feature comparison: RequestBin alternative.
Q

How do I edit the response my webhook URL returns?

On Requex.me, open Response Settings on your webhook and set any status code, custom headers, a custom body, and a delay up to 30 seconds, free. You can also switch to echo mode (returns what was sent) or use template variables like {{body.id}} in the response. This is the feature webhook.site puts behind its $9/month plan. On Requex.me it costs nothing, which is why teams testing retry logic and error handling switch.
Q

How do I create a mock API without building a backend?

Create a free Mock Server on Requex.me: you get a stable HTTPS base URL, then add routes (with :param support) and per-method responses, status code, JSON body, headers, and an optional delay per response. Your frontend or mobile app calls the mock URL exactly like a real API. No Docker, no Java, no local port, unlike WireMock, Mockoon, or json-server, the mock is hosted and shareable with your team. Details: Mock Server docs.
Q

How do I run a cron job online without a server?

Requex.me runs scheduled HTTP requests in the cloud for free. Define a schedule with a cron expression, point it at any URL, and get live execution logs plus failure alerts to Slack or Discord when a run errors or stops reporting. There is also a visual cron expression builder that generates and explains expressions in plain English. Start here: online cron job.
Q

Why is my n8n webhook not working?

The most common cause: using the n8n Test URL instead of the Production URL. The Test URL only listens while the workflow editor has "Listen for test event" active; the Production URL only works after the workflow is activated. Registering the wrong one with your provider silently drops every event. Other frequent causes: workflow not activated, wrong HTTP method on the webhook node, and payload mapping that expects a different body shape. To see what your provider actually sends, capture it on a Requex.me URL first, then compare. All nine causes with fixes: n8n webhook not working.
Q

How do I see what data a webhook is sending?

Point the webhook at a Requex.me URL and every request appears in the dashboard the moment it arrives, HTTP method, all headers, raw and formatted JSON body, and query parameters. No polling and no refresh; updates stream over WebSocket. This is the fastest way to answer "what does Stripe/GitHub/Shopify actually send?" before writing a single line of handler code. You can label captured requests and keep them for reference.
Q

How do I secure a public webhook endpoint?

Verify every request before processing it. The standard methods, all supported natively on Requex.me endpoints: HMAC signature verification (compute the HMAC of the raw body with your secret and compare against the signature header), bearer tokens, API keys, and basic auth. On Requex.me, requests that fail auth are still captured and labeled auth_failed so you can inspect what an attacker or misconfigured client sent, while the caller gets a 401/403. Production checklist: webhook security best practices.
Q

How do I forward a webhook to Slack or multiple destinations?

On Requex.me, add forwarding rules to any webhook: each rule sends incoming requests to a destination URL with independent retries, timeouts, and header/body pass-through controls. One inbound event can fan out to your app, Slack, and an analytics endpoint simultaneously. For formatted Slack messages (not raw JSON), use a Requex.me workflow with the Slack node, about five minutes, no code: webhook to Slack automation.
Q

Can I automate workflows from a webhook without code?

Yes. Requex.me includes a visual workflow builder with 30+ nodes: HMAC verify, AI classify and transform (turn messy payloads into clean JSON), Slack and Google Sheets, state storage, conditionals, and custom webhook responses. Trigger a workflow from any webhook and it runs hosted, no VPS, Docker, or self-hosted n8n instance to maintain. It is free during beta and works as a developer-focused alternative to Zapier, Make, and n8n Cloud: workflow automation.
Q

What's a webhook tester and why do I need one?

A webhook tester gives you a public URL that captures incoming webhook requests in real-time. You point Stripe, GitHub, Shopify, whoever, at that URL, and you see exactly what they're sending you. Why? Because you can't always SSH into your production server to watch logs when testing a payment flow. A webhook tester sits in between and shows you the raw request: headers, signature, body, everything. Best part: no setup. Generate a URL, test your webhook handler without deploying anything, then move to production when you're confident.
Q

Is Requex completely free?

Yes, Requex.me is completely free: unlimited webhooks, custom response codes, response delays, and forwarding rules, with no account needed for basic testing. webhook.site charges $9/month if you want to return a 500 status code or delay responses. Requex includes that for free. That's the main difference.
Q

How do webhooks differ from APIs?

APIs are pull. You ask "Do you have new data?" every 30 seconds. Waste of bandwidth if nothing changed. Webhooks are push. The service tells you instantly when something happens. Payment processed? You get notified right now, not in 30 seconds. That's it. Webhooks win for real-time updates.
Q

I'm getting a 401 Unauthorized on my webhook. What now?

Three things to check: 1. **Missing auth header**, Is your endpoint checking for Authorization, Bearer token, API key, etc.? Is it actually there in the request? 2. **Wrong secret**, If you're doing signature verification (HMAC), your webhook secret in the code must match what the provider has. Stripe rotates keys sometimes. 3. **Raw body not captured**, This trips up everyone. If you parse JSON first then do HMAC, it won't match. You need the raw bytes. Quick fix: capture your request in Requex, check if the Authorization header exists, and look at its value. That'll tell you what's actually being sent.
Q

How do I verify HMAC signatures from Stripe?

The provider sends a signature header (e.g., X-Stripe-Signature). You compute the same HMAC with your webhook secret and compare. const crypto = require('crypto'); app.post('/webhook', express.raw({ type: 'application/json' }), // Critical: raw body first (req, res) => { const sig = req.headers['x-stripe-signature']; const secret = process.env.STRIPE_WEBHOOK_SECRET; const hash = crypto .createHmac('sha256', secret) .update(req.body) // Raw bytes .digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(hash))) { return res.status(401).send('Nope'); } const event = JSON.parse(req.body); console.log('Verified:', event.type); res.status(200).send('ok'); } ); The tricky part: use raw body bytes, not parsed JSON. And use timingSafeEqual so nobody can guess your secret through timing attacks.
Q

Can I simulate 500 errors and timeouts?

Yep. In your Requex dashboard, hit Response Settings and pick: - Status code (200, 500, anything) - Delay (up to 30 seconds) - Custom headers or body Why? You want to verify your client actually retries when it gets a 500. Or that it doesn't hang forever waiting for a response.
Q

How do I test Stripe webhooks locally?

Three ways: **Easiest (Requex):** Make a webhook here, add it to Stripe Dashboard → Developers → Webhooks. Test card is 4242 4242 4242 4242. Done. **Best (Stripe CLI):** Download stripe-cli, run: stripe listen --forward-to localhost:3000/webhook stripe trigger payment_intent.succeeded This forwards real Stripe events to your local port. You get the HMAC and everything. **Manual:** Capture payload in Requex, copy it, use Postman or curl to replay it locally. Slower but teaches you what's actually being sent.
Q

How do I prevent duplicate webhook processing?

Webhooks retry. If your handler crashes or times out, the provider sends it again. You need to handle that. Every webhook has an ID (Stripe calls it event.id). Store it in your database: app.post('/webhook', async (req, res) => { const eventId = req.body.id; // Already processed? const existing = await db.webhookEvents.findOne({ eventId }); if (existing) { return res.status(200).send('Already got this'); } // Process it await processPayment(req.body); // Mark as done await db.webhookEvents.create({ eventId }); res.status(200).send('ok'); }); Simple: one record per eventId. If it exists, skip. If not, process and create record. Now duplicate webhooks are harmless.
Q

I keep hitting rate limits on Stripe API calls from my webhook. Why?

Your webhook handler is calling Stripe API to do something (fetch user, create invoice, whatever). Stripe limits you to ~100 requests/second. If you process 200 webhooks concurrently, you'll hit that. Solution: queue your work instead of processing inline. const queue = require('bull'); const webhookQueue = new queue('webhooks'); app.post('/webhook', async (req, res) => { // Queue immediately, return 200 await webhookQueue.add(req.body); res.status(200).send('ok'); }); // Process at your own pace webhookQueue.process(async (job) => { // This will retry if it fails await processPaymentAndCallStripe(job.data); }); This way you return 200 instantly (so the provider doesn't retry), then process at whatever pace your rate limits allow. Job queue handles retries automatically.
Q

What's the difference between Requex and webhook.site?

Requex.me is a free webhook.site alternative, the custom responses webhook.site charges $9/month for are free on Requex.me. Both tools work; here is the honest breakdown. Requex has: - Custom responses free (webhook.site charges $9/mo) - WebSocket updates (webhook.site polls) - Dark mode webhook.site has: - Longer history (been around longer) - Slightly more documentation Honestly? Use Requex. Same job, better features free.
Q

How do I test GitHub webhooks?

GitHub dashboard → Settings → Webhooks → Add. Pick events (push, pull_request, issues) and paste your Requex URL. Then either push a commit or manually trigger in the Recent Deliveries section. You'll see the exact payload GitHub sent. The payload includes commit details, branch, author, timestamp. Useful for triggering CI/CD or updating project management tools.
Q

How do I test Shopify webhooks?

Shopify Admin → Settings → Apps and integrations → Webhooks → Create. Pick event (orders/created, products/updated, etc.) and paste your URL. You can send a test notification to see sample data. Common events: - orders/created → sync to accounting - products/updated → sync to marketplace - inventory_levels/update → update WMS Sign them with HMAC-SHA256, same as Stripe.
Q

What are the common webhook errors?

**400 Bad Request**, You sent malformed JSON or missing expected field. **401 Unauthorized** — Missing or wrong auth (bearer token, API key, HMAC signature). **404 Not Found** — Endpoint URL doesn't exist or got deleted. Provider stops sending after 8 tries. **429 Too Many Requests** — You're calling provider API too fast. Implement backoff. **500 Internal Server Error** — You crashed. Provider will retry this, which is good. **503 Service Unavailable** — Your server is down. Provider will retry. Tip: if you're not sure what's failing, capture it in Requex. Raw request, all headers. Way easier to debug.
Q

Do I need to respond immediately or can I process async?

Respond 200 immediately. Then queue your work. The provider waits about 5 seconds for a 200 response. If you don't respond fast, the provider thinks you're dead and retries. If you're doing heavy processing (calling APIs, updating database), that takes time. Better pattern: app.post('/webhook', (req, res) => { webhookQueue.add(req.body); // Queue it res.status(200).send('ok'); // Return fast }); webhookQueue.process(async (job) => { // Do expensive work here, no time pressure await heavyProcessing(job.data); }); Return 200 instantly. Process in background. This prevents timeouts and retries.
Q

How do I test Discord webhooks?

Discord webhooks are different from typical API webhooks. You're not receiving callbacks, you're sending messages. Server → Settings → Webhooks → New Webhook. Copy the URL. Send a POST request: curl -X POST https://discord.com/api/webhooks/123/abc -H "Content-Type: application/json" -d '{ "content": "Order #12345 complete", "embeds": [{ "title": "Payment Received", "description": "$99.99" }] }' Good for alerts, notifications, order updates. Not for receiving webhooks from Discord (they'd send via a different integration).
Q

How do I handle CORS errors in webhooks?

CORS errors happen in the browser, not on webhooks. Webhooks are server-to-server, no CORS involved. If you're getting a CORS error with a webhook tool, it's probably the testing tool itself having issues, not your handler. If your webhook handler makes requests to a different domain, that's not CORS, it's a normal API call. The server doesn't care about origins. What you might actually be hitting: missing auth headers, wrong endpoint URL, or firewall blocking.
Q

How do I forward incoming webhooks to multiple destinations?

Sometimes you want to send the same webhook to multiple places (your app AND a third-party service). Simple way: app.post('/webhook', async (req, res) => { // Send to multiple places at once await Promise.all([ fetch('https://slack.com/api/chat.postMessage', { /* ... */ }), fetch('https://analytics.example.com/events', { /* ... */ }), fetch('https://backup.example.com/webhooks', { /* ... */ }) ]); res.status(200).send('ok'); }); Better way: queue it. If one destination fails, don't retry them all: app.post('/webhook', async (req, res) => { // Queue three separate jobs await Promise.all([ forwardQueue.add({ dest: 'slack', data: req.body }), forwardQueue.add({ dest: 'analytics', data: req.body }), forwardQueue.add({ dest: 'backup', data: req.body }) ]); res.status(200).send('ok'); }); // Each destination retries independently forwardQueue.process(async (job) => { const { dest, data } = job.data; await sendToDestination(dest, data); });
Q

How do I test n8n or Make webhooks?

n8n and Make let you build automations visually. Webhooks are part of that. To test webhooks n8n sends: 1. Create a Webhook node in your workflow 2. Copy the Requex URL into that node 3. Execute the workflow 4. See the payload in Requex To test webhooks received by n8n: 1. Create a Webhook trigger in n8n 2. Copy the generated n8n URL 3. Paste it into another service (Stripe, GitHub, etc.) 4. When events happen, n8n receives them This is useful for debugging data transformations without needing a real backend.
Q

How do I handle webhook timeouts?

Webhook provider waits ~5 seconds for a 200 response. If your handler takes longer, it times out and the provider retries. Solution: return 200 immediately, process async. But what if you legitimately need time? For instance, processing a large order. That's what queues are for: app.post('/webhook', async (req, res) => { // Queue it NOW await queue.add(req.body); // Return 200 immediately res.status(200).send('ok'); }); // Process takes 30 seconds, no timeout queue.process(async (job) => { await expensiveProcessing(job.data); }); The provider doesn't care how long you actually process, it just needs the 200 response fast.
Q

How do I test Slack webhooks?

Slack webhooks are like Discord, you send messages, not receive them. Workspace → Settings → Apps → Custom Integrations → Incoming Webhooks → Create. POST to the URL: { "text": "New order received", "blocks": [{ "type": "section", "text": { "type": "mrkdwn", "text": "*Order #12345*\nAmount: $99.99" } }] } Good for alerts and notifications. If you need Slack to send webhooks to you, use their Events API instead (different setup).
Q

What's the max payload size for webhooks?

Depends on the provider. Most are generous: - Stripe: ~1MB - GitHub: ~25MB - Shopify: ~1MB But just because you can send 1MB doesn't mean you should. Larger payloads = slower processing. If a provider is sending huge payloads, consider: 1. Ask them to send minimal data + fetch details via API 2. Stream the request if possible 3. Set up gzip compression In practice, most webhooks are <100KB. If you're seeing >1MB, something's probably wrong.
Q

How do I test webhook retries?

Want to see if your handler actually handles retries? Use Requex to return an error: 1. Trigger a webhook 2. In Requex dashboard, set Response to 500 3. Provider sees the error and queues a retry 4. Few seconds later, another request arrives 5. Change Response back to 200 6. Second request succeeds This proves your provider implements retries. Good to know before production. For testing your own retry logic, use a job queue with exponential backoff. If processing fails, the queue retries automatically after 2s, 4s, 8s, etc.
Q

Can I use webhooks for real-time updates in a frontend?

Sort of, but it's complicated. Webhooks are server-to-server. Your frontend can't directly receive them without exposing an endpoint. Better approach: webhook hits your backend, backend pushes to frontend via WebSocket. // Backend receives webhook app.post('/webhook', async (req, res) => { const event = req.body; // Broadcast to connected clients via WebSocket io.emit('order_update', { orderId: event.data.id, status: 'paid' }); res.status(200).send('ok'); }); // Frontend listens socket.on('order_update', (data) => { console.log('Order paid:', data.orderId); updateUIImmediately(); }); This way your frontend gets instant updates when webhooks arrive.
Q

What's the difference between webhooks and pub/sub?

Webhooks: Service A sends HTTP POST to Service B. Direct, synchronous (mostly). Pub/Sub: Service A publishes to a message queue (Redis, Kafka, RabbitMQ). Service B subscribes. Decoupled. Webhooks: Simple, no infrastructure. Use for: alerts, notifications, triggered actions. Pub/Sub: More complex, but flexible. Use for: real-time systems, multiple consumers, guaranteed delivery. Webhooks are easier to start. If you outgrow them (need guaranteed delivery, multiple consumers, ordering), switch to pub/sub.
Q

How do I validate webhook timestamps to prevent replay attacks?

Some providers send a timestamp header. Check it to prevent old webhooks from being replayed. Example with Stripe: const signature = req.headers['x-stripe-signature']; const [timestamp, sig] = signature.split(',').map(p => p.split('=')[1]); // Reject if older than 5 minutes const now = Math.floor(Date.now() / 1000); if (now - parseInt(timestamp) > 300) { return res.status(401).send('Timestamp too old'); } // Then verify signature normally const hash = crypto .createHmac('sha256', secret) .update(`${timestamp}.${req.body}`) .digest('hex'); if (sig !== hash) { return res.status(401).send('Invalid signature'); } This prevents someone from capturing an old webhook and replaying it.
Q

How do I monitor webhook health?

Log every webhook: app.post('/webhook', async (req, res) => { const startTime = Date.now(); try { await processWebhook(req.body); logger.info('webhook_success', { type: req.body.type, duration: Date.now() - startTime }); res.status(200).send('ok'); } catch (err) { logger.error('webhook_failed', { type: req.body.type, error: err.message, duration: Date.now() - startTime }); res.status(500).send('error'); } }); Then set up alerts for: - More than 5 consecutive failures - Processing time > 5 seconds - Missing signature headers (possible attackers) Simple monitoring catches problems before they cascade.
Q

What's the difference between sync and async webhooks?

Sync: You process the webhook while the provider waits. Good for quick operations (<1s). Async: You queue it and return 200 immediately. Provider doesn't wait. Almost always use async. Here's why: if processing takes >5 seconds, the provider times out and retries. Now you have duplicates. So just queue it and return fast. The only time sync makes sense: simple validation. "Is this user allowed?" Nope, even then, queue it.
Q

How do I handle webhook encoding issues?

Webhooks usually come as UTF-8 JSON. But sometimes providers send weird encodings or special characters. Handle it: app.post('/webhook', express.json({ charset: 'utf-8' }), (req, res) => { // Normalize strings const text = req.body.text || ''; const normalized = text.normalize('NFD'); // Decompose accents // Or just ignore unprintable characters const clean = text.replace(/[^ -~]/g, ''); res.status(200).send('ok'); }); Most of the time this isn't an issue. But if you're processing user input from webhooks, normalize it.
Q

Can I use webhooks for notifications without a database?

Sure, but it's weird. Webhook hits your endpoint, you send a notification (email, SMS, Slack) immediately. app.post('/webhook', async (req, res) => { const order = req.body; // Send email immediately await mailer.send({ to: 'customer@example.com', subject: 'Order shipped', body: `Your order ${order.id} has shipped` }); res.status(200).send('ok'); }); Works fine for simple cases. But if email sending fails, the webhook fails. Better approach: queue it. And if you need to reference that webhook later ("Did we send a shipping notification?"), you need a database anyway.
Q

How do I load test my webhook endpoint?

Use a tool like k6: npm install -g k6 // load-test.js import http from 'k6/http'; export const options = { stages: [ { duration: '10s', target: 10 }, // Ramp to 10 users { duration: '30s', target: 50 }, // Ramp to 50 users { duration: '10s', target: 0 }, // Ramp down ], }; export default function () { http.post('https://requex.me/webhook-id', JSON.stringify({ type: 'payment.succeeded', data: { amount: 99.99 } })); } // Run it k6 run load-test.js Watch for: response times, error rate, queue backlog. If it all stays healthy under 50 concurrent requests, you're probably fine.
Q

What's the best way to debug webhook issues?

1. Capture in Requex, See the actual request, headers, body, signature 2. Log everything, Request received, processing start, processing end, errors 3. Isolate, Is it a parsing issue? Auth issue? Processing issue? 4. Replay, Capture the request, manually replay it with curl or Postman 5. Minimize, Test with the smallest possible payload first Most webhook problems are: - Wrong secret in environment variable - Raw body not captured (signature verification fails) - Timeout because processing takes too long - Some field is missing or renamed Use Requex to see the actual data, then debug locally.
Q

Can I send webhooks from my own app?

Yes. Just POST JSON to a URL. But don't reinvent the wheel. Use a webhook service like: - Svix, production-grade webhooks - Hookdeck, queuing + retries - Inngest, event triggering Or DIY with a queue: // User does something app.post('/api/order', async (req, res) => { const order = await db.orders.create(req.body); // Queue webhook await webhookQueue.add({ event: 'order.created', data: order }); res.json({ orderId: order.id }); }); // Send webhooks to subscribers webhookQueue.process(async (job) => { const subscribers = await db.webhookSubscriptions.findAll(); for (const sub of subscribers) { try { await fetch(sub.url, { method: 'POST', body: JSON.stringify(job.data), headers: { 'X-Webhook-Signature': signRequest(job.data, sub.secret) } }); } catch (err) { // Retry logic throw err; } } }); Hard part: retry logic, signature verification, subscriber management. That's why services exist.

Didn't find your answer?

Ask us directly. We're developers too, we get it.

Email us