Self-hostable Webhook Inspector

TESTHOOKS

Capture, inspect, transform, and forward webhooks in real time.

A lightweight webhook.site replacement you own. Browser mode replaces ngrok — zero setup.

request flow
webhook --> /h/:slug --> WS --> browser --> localhost
Go Svelte 5 WebSocket WASM Postgres
How It Works

The Pipeline

Every webhook flows through a composable pipeline. Enable only what you need.

Capture

Receive any HTTP request

Store

Persist to PostgreSQL

Transform

JS/Lua/Jsonnet scripts

Forward

Relay to your services

Respond

Custom HTTP response

Example Pipeline
1. CAPTURE
POST /h/abc123
"event": "order.created"}
2. TRANSFORM
function transform(req) {
  req.body.ts = Date.now();
  return req;
}
3. FORWARD
POST https://api.yourapp.com
"event": "order.created",
"ts": 1711234567890
Core Features

Everything You Need for Webhook Development

From live inspection to programmable transforms — one tool for the full webhook lifecycle.

Localhost Friendly

Browser mode forwards via fetch() — reach localhost, Docker, anything your machine can see. No CLI, no daemon.

Privacy-first Mode

Browser mode: zero server storage. Payloads never touch disk. GDPR-friendly, ideal for sensitive data.

Real-time Streaming

WebSocket-powered live view. See every request the instant it arrives — headers, body, timing.

Script Transforms

JavaScript, Lua, or Jsonnet scripts transform payloads before forwarding. Runs in WASM — sandboxed and fast.

Smart Forwarding

Forward to any URL with sync or async mode. Sync mode captures the response for your handler scripts.

Full Inspection

Headers, query params, body with JSON/XML syntax highlighting. Copy as cURL, replay, export as JSON/CSV.

Two Modes

Choose Your Trade-off

Server mode for production reliability, Browser mode for privacy and local testing.

DEFAULT

Server Mode

Requests are stored in PostgreSQL. Transforms and forwarding run server-side, always-on even without a browser. Ideal for production webhooks.

Persistent storageAlways-onServer-side WASMRetry with backoff
TUNNEL KILLER

Browser Mode

Your tunnel replacement for local webhook testing. Webhooks hit Testhooks, stream to your browser via WebSocket, and fetch() delivers them to localhost. No CLI, no daemon, no port forwarding. Zero server storage.

Replaces ngrokReach localhostZero storageNo CLI needed
No CLI, No Daemon

Replace ngrok for Webhook Testing

Browser mode turns Testhooks into a webhook tunnel — without installing anything.

Stripe / GitHub / Slack

Sends webhook to
your Testhooks URL

Your Browser

Receives via WebSocket,
inspects, transforms, forwards

localhost:3000

Your app receives
the webhook via fetch()

ngrok / localtunnel
Testhooks Browser Mode
Setup
Install CLI, authenticate, run daemon
Open a browser tab
Inspect payloads
Separate logging or dashboard
Built-in live view with syntax highlighting
Transform before delivery
Not possible
JS, Lua, or Jsonnet in sandboxed WASM
Custom responses
Whatever your local server returns
Script-defined — test error handling without changing your app
Data privacy
Traffic routes through third-party servers
Payloads never stored — browser-only, zero disk

Works with any webhook provider — Stripe, GitHub, Slack, Shopify, Twilio, Linear, and more.
Just point their webhook URL at your Testhooks endpoint.

Ready to Own Your Webhooks?

Open source, self-hostable, no sign-up required. One binary, one database — and browser mode reaches localhost too.