DEV Community

Cover image for I built a webhook testing API in one day and listed it on RapidAPI for free
Brian Omondi Amol
Brian Omondi Amol

Posted on

I built a webhook testing API in one day and listed it on RapidAPI for free

The Problem

Every developer integrating M-Pesa, Stripe, GitHub, or any service
that sends webhooks hits the same wall during development:

You need a URL to receive the webhook. But your app is running on
localhost. So you either:

  • Deploy just to test (slow)
  • Use ngrok (another tool to manage)
  • Hard-code a URL and hope for the best

I got tired of this on every project. So I built an API that solves
it in one call.

What I Built

WebhookBox — an API that gives you instant, disposable webhook
URLs for capturing, inspecting, and replaying HTTP payloads.

// Step 1: Create a webhook URL
const response = await fetch(
  'https://webhookbox-api-production.up.railway.app/webhooks/create',
  { method: 'POST' }
)
const { webhook_url, webhook_id } = await response.json()

// Step 2: Point M-Pesa/Stripe/GitHub at webhook_url
// Step 3: Inspect what was received
const payloads = await fetch(
  `https://webhookbox-api-production.up.railway.app/webhooks/${webhook_id}/payloads`
)
Enter fullscreen mode Exit fullscreen mode

That's it. No setup. No config. No ngrok.

What It Does

  • Create a disposable webhook URL instantly
  • Capture any HTTP method — POST, GET, PUT, PATCH
  • Inspect full payload: headers, body, query params, timestamp
  • Replay any captured payload to a target URL
  • Auto-expires after 24 hours

The Stack

  • Node.js + Express
  • Upstash Redis (for payload storage with TTL)
  • Deployed on Railway (free tier)
  • Listed on RapidAPI

Why This Is Useful in CI/CD

The real power is automating webhook testing in your pipeline:

// In your test file
const { webhook_id, webhook_url } = await createWebhook()

// Trigger your payment flow
await triggerMpesaPayment({ callback_url: webhook_url })

// Wait, then assert
await sleep(3000)
const { payloads } = await getPayloads(webhook_id)
assert(payloads[0].body.ResultCode === 0)
Enter fullscreen mode Exit fullscreen mode

No human sitting watching a browser tab. Fully automated.

Try It Free

Listed on RapidAPI with a free tier:
šŸ‘‰ https://rapidapi.com/Brianamol/api/webhookbox

Built this in one day. Would love feedback from the community —
what features would make this more useful for your workflow?

Top comments (0)