DEV Community

Kuba
Kuba

Posted on

Customer Called Me raged at Midnight

I Built a Webhook Inspector After a Customer Called Me at Midnight

Two weeks ago I was integrating Stripe webhooks for a client project.
Everything was working fine in development. I deployed to production,
went to sleep, and woke up to a message:

"Hey, payments aren't going through."

I spent 3 hours debugging. The webhook was firing. My server was
receiving it. But something in the payload had changed silently —
no announcement, no deprecation warning. Just a broken handler
and an angry customer.

That's when I decided to build HookScope.


The Problem Nobody Talks About

Webhooks sound simple. Provider sends a POST, you handle it. Easy.

Until you're integrating 5 different providers simultaneously.

Stripe has its signature format. GitHub has another. Shopify does
it differently. Clerk uses Svix under the hood. Przelewy24 — the
Polish payment provider — has its own completely custom verification
flow that I had to reverse-engineer from their docs.

Every provider:

  • Different header names
  • Different HMAC algorithms
  • Different payload formats
  • Different retry logic

And none of them tell you when they change something.


Two Weeks, One Tool

I gave myself two weeks to build something I'd actually want to use.

The core idea was simple: one place to inspect, debug, and monitor
all your webhooks — regardless of provider.

The technical challenge that took the longest wasn't the inspector
itself. It was combining the CLI tunnel with the dashboard in a way
that felt seamless.

You run one command:

hookscope forward 3000
Enter fullscreen mode Exit fullscreen mode

And instantly your local server is receiving webhooks from Stripe,
GitHub, or any other provider — with full inspection in the dashboard,
signature verification handled automatically, and real-time updates
via WebSockets.

Getting that end-to-end flow to feel instant took most of the two weeks.


The Feature I'm Most Proud Of

Schema drift detection.

Every webhook payload gets flattened into a map of dot-notation
paths and types:

{
  "data.object.amount": "number",
  "data.object.currency": "string",
  "type": "string"
}
Enter fullscreen mode Exit fullscreen mode

On every new request, HookScope diffs the current schema against
the stored baseline. If anything changes — a field removed, a type
changed, a new required field added — you get an alert immediately.

Before your handler crashes. Before a customer calls you.

And for paid users, HookScope automatically generates updated
TypeScript, Zod, Go, and Python types via AI. Schema changes,
types update automatically.


What I Launched With

After two weeks I had:

  • CLI tunnel written in Go (distributed via Homebrew)
  • Real-time webhook inspector with WebSocket updates
  • Automatic signature verification for 5 providers
  • Schema drift detection with alerts
  • Email, Slack and Discord notifications
  • Duplicate detection
  • Silence detection (alerts when webhooks stop coming)
  • AI-powered DTO generation

Was it perfect? No. But it solved the exact pain point that woke
me up at midnight two weeks earlier.


The Lesson

The best tools come from real pain.

I didn't build HookScope because it seemed like a good SaaS idea.
I built it because I needed it — and every developer integrating
webhooks needs it too, they just don't know it yet.

If you've ever been burned by a silent webhook change or spent
hours debugging a mysterious 400, give it a try.

It's free to start: app.hookscope.dev

The CLI installs in one command:

brew tap nowackikuba/hookscope
brew install hookscope
hookscope login
hookscope forward 3000
Enter fullscreen mode Exit fullscreen mode

Building in public. Feedback welcome in the comments.

Top comments (0)