npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@smi0001/webhook-playground

v2.3.1

Published

Self-hosted webhook inspection and testing tool — capture, inspect, and debug incoming HTTP requests in real time

Readme

webhook-playground

Self-hosted microservice to use as webhook inspection and testing tool. Capture, inspect, and debug incoming HTTP requests in real time — like a private Webhook Collection that you run yourself. Built with Express.js, PostgreSQL, and Server-Sent Events (SSE) for live updates.


📋 Table of contents


✨ Features

  • Create named webhook endpoints with unique URLs
  • Capture any HTTP method (GET, POST, PUT, DELETE, PATCH, etc.)
  • Inspect headers, body, query params, and IP in real time via SSE
  • Optional per-webhook Basic Auth protection
  • Web dashboard UI included
  • Stores request history (up to 200 per webhook)
  • Forward incoming requests to any target URL and capture the response

🔧 Requirements

  • Node.js >= 18
  • PostgreSQL database

🗄️ Prerequisites: Set up a PostgreSQL database

Before running the app, create a dedicated database and user:

psql -U postgres
CREATE DATABASE webhook_db;
CREATE USER webhook_user WITH PASSWORD 'yourpassword';
GRANT ALL PRIVILEGES ON DATABASE webhook_db TO webhook_user;
\q

Then use these credentials in your .env:

DATABASE_URL=postgresql://webhook_user:yourpassword@localhost:5432/webhook_db

📦 Installation

Global install (recommended for team/internal use)

npm install -g @smi0001/webhook-playground

Or run without installing

npx @smi0001/webhook-playground

⬆️ Upgrading

Already installed an earlier version? Update the package and re-run migrations:

npm install -g @smi0001/webhook-playground@latest
webhook-play migrate

Migrations are idempotent — every .sql file in the migrations/ folder uses IF NOT EXISTS guards, so re-running on an existing database only applies new columns/tables and leaves existing data untouched.


🚀 Global install usage

After installing globally, create a working directory, add your .env file there, and run all commands from that directory:

mkdir my-webhooks && cd my-webhooks

Create a .env file:

DATABASE_URL=postgresql://user:password@localhost:5432/webhook_db
PORT=3000
BASE_URL=http://localhost:3000

Replace user, password, and webhook_db with your actual PostgreSQL credentials.

Run migrations once:

webhook-play migrate

Start the server:

webhook-play

⚙️ Usage

1. Configure environment

Copy the example env file and fill in your values:

cp .env.example .env
DATABASE_URL=postgresql://user:password@localhost:5432/webhook_db
PORT=3000
BASE_URL=http://localhost:3000

| Variable | Required | Description | |----------------|----------|----------------------------------------------------------| | DATABASE_URL | Yes | PostgreSQL connection string | | PORT | No | Port to listen on (default: 3000) | | BASE_URL | No | Public-facing URL shown in the dashboard for webhook URLs | | BASE_PATH | No | Sub-path prefix when served under a nested route (e.g. /webhook). See reverse proxy setup. | | DB_SSL | No | Set to true to enable SSL for the DB connection |

2. Run database migrations

webhook-play migrate

This creates the required tables (webhooks, webhook_requests) in your database.

3. Start the server

webhook-play
# or
webhook-play start

To run on a custom port:

PORT=8080 webhook-play
Webhook microservice running at http://localhost:8080

Open http://localhost:8080 in your browser to access the dashboard.


🌐 Deploying behind a reverse proxy (Nginx)

Root deployment (app served at /)

Use this when webhook-playground is the only app on the domain or subdomain (e.g. https://webhooks.example.com).

The app runs on its internal port (default 3000) and Nginx forwards all traffic to it.

server {
    listen 80;
    server_name webhooks.example.com;

    location / {
        proxy_pass      http://127.0.0.1:3000;
        proxy_set_header Host $host;
        include proxy_params;
    }
}

No BASE_PATH needed in .env for this setup.


Sub-path deployment (app served at a nested route)

Use this when webhook-playground shares a domain with another app — for example, your main app is already at / and you want webhook-playground accessible at /webhook.

When to use: The server already has an Nginx config routing / or /api/ to a different application, and you need webhook-playground to live alongside it under its own path prefix.

1. Add to your .env:

BASE_PATH=/webhook

2. Add to your Nginx config — place these blocks before any existing location /api/ block, since Nginx matches more specific locations first:

# Redirect /webhook to /webhook/ (trailing slash required)
location = /webhook {
    return 301 /webhook/;
}

# Proxy all /webhook/ traffic to the webhook-playground app
location /webhook/ {
    proxy_pass      http://127.0.0.1:3000/webhook/;
    proxy_set_header Host $host;
    include proxy_params;
}

3. Reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

The app will then be accessible at https://yourdomain.com/webhook/.

Note: The BASE_PATH value must match the Nginx location prefix exactly (e.g. both must be /webhook).


🩺 Health check endpoint

Useful for verifying a fresh install without needing any existing data:

GET /api/health

Returns 200 { "status": "ok", "db": "connected" } when the app and database are both reachable. Returns 503 if the database is unreachable.

With a sub-path deployment: GET /webhook/api/health


💻 CLI reference

webhook-play              Start the server
webhook-play start        Start the server (explicit)
webhook-play migrate      Run database migrations

📡 API reference

| Method | Endpoint | Description | |----------|----------------------------------------|------------------------------------| | GET | /api/health | Health check (app + DB status) | | POST | /api/webhooks | Create a new webhook | | GET | /api/webhooks | List all webhooks | | GET | /api/webhooks/:uuid | Get a single webhook | | PUT | /api/webhooks/:uuid | Update webhook name / auth / forwarding | | DELETE | /api/webhooks/:uuid | Delete a webhook | | GET | /api/webhooks/:uuid/requests | List captured requests (max 200) | | GET | /api/webhooks/:uuid/requests/:id | Get a single request | | PATCH | /api/webhooks/:uuid/requests/:id | Update a request's remark (bookmark) | | DELETE | /api/webhooks/:uuid/requests/:id | Delete a single request | | DELETE | /api/webhooks/:uuid/requests | Clear all requests for a webhook | | GET | /api/webhooks/:uuid/stream | SSE stream for real-time updates | | * | /microservices/webhook/:uuid | Webhook receiver endpoint |

When using BASE_PATH, all endpoints are prefixed — e.g. /webhook/api/health, /webhook/microservices/webhook/:uuid.


🪝 Webhook receiver

Send any HTTP request to:

POST http://localhost:3000/microservices/webhook/<uuid>

The request is recorded immediately and pushed to any open dashboard via SSE.

If Basic Auth is enabled on the webhook, include credentials:

curl -u username:password \
  -X POST http://localhost:3000/microservices/webhook/<uuid> \
  -H "Content-Type: application/json" \
  -d '{"event": "order.created", "id": 42}'

🗂️ Project structure

webhook-microservice/
├── bin/
│   └── cli.js               # CLI entry point (webhook-play command)
├── migrations/
│   ├── migrate.js            # Migration runner
│   └── schema.sql            # Database schema
├── public/
│   ├── css/style.css
│   ├── js/
│   │   ├── dashboard.js      # Webhook dashboard UI logic
│   │   └── landing.js        # Landing page logic
│   ├── index.html            # Landing page
│   └── webhook.html          # Per-webhook dashboard
├── src/
│   ├── app.js                # Express app setup & server entry
│   ├── config/
│   │   └── database.js       # PostgreSQL pool
│   ├── routes/
│   │   ├── api.js            # REST API routes
│   │   └── webhookReceiver.js# Incoming webhook handler
│   └── sse.js                # Server-Sent Events manager
├── .env.example
└── package.json

🆕 What's new

2.3.1

  • 📝 Documented the new PATCH /api/webhooks/:uuid/requests/:id endpoint in the API reference and corrected the PUT /api/webhooks/:uuid description to reflect forwarding-settings updates

2.3.0

  • 🔎 Added a search box in the dashboard sidebar — filter requests by path, method, body, headers, query params, IP, or remark
  • 🔖 Added per-request remarks — add a note to any request to bookmark it for later reference
  • 📑 Bookmarks dropdown in the sidebar lists all bookmarked requests; click to jump straight to one

2.2.1

  • 📝 Added Upgrading section to README with instructions for updating an existing install and re-running migrations

2.2.0

  • ➕ Toggle request forwarding on/off in real-time from the dashboard — no need to recreate the webhook
  • ✏️ Destination URL is editable inline; changes apply immediately
  • 🕘 When the forwarding URL is changed, the previous value is retained and shown with strikethrough for quick reference
  • 🐛 Fixed response body "Copy" button that was broken when the body contained double quotes

2.1.2

  • ➕ Added BASE_PATH environment variable support — serve the app under a sub-path (e.g. /webhook) when sharing a domain with another application
  • 🔗 All frontend API calls and navigation use the base path automatically via injected window.APP_BASE
  • 🛠️ HTML asset paths updated to be relative, resolving correctly at any prefix depth
  • 📝 Added Nginx reverse proxy documentation for both root and sub-path deployments

2.1.1

  • ➕ Added GET /api/health endpoint — returns app and database status without requiring any existing data; useful for verifying a fresh install

2.1.0

  • ➕ Added request forwarding — forward incoming webhook requests to any destination URL and capture the response status
  • 📡 Forward status shown in the dashboard in real time via SSE

2.0.1

  • 📝 Documentation improvements: PostgreSQL setup prerequisites, credential placeholder notes

2.0.0

  • 🎉 Rebranded package to webhook-playground
  • 🔄 CLI command renamed to webhook-play
  • 🚀 Added global install support with working directory workflow

1.0.2

  • 🐛 Fixed README CLI command references

1.0.1

  • 🔄 Renamed CLI command from webhook-ms to webhook-play

1.0.0

  • 🎉 Initial release — webhook inspection microservice with Express.js, PostgreSQL, SSE real-time updates, Basic Auth support, and web dashboard UI

📄 License

MIT