@smi0001/webhook-playground
v2.3.1
Published
Self-hosted webhook inspection and testing tool — capture, inspect, and debug incoming HTTP requests in real time
Maintainers
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
- 🔧 Requirements
- 🗄️ Prerequisites: Set up a PostgreSQL database
- 📦 Installation
- ⬆️ Upgrading
- 🚀 Global install usage
- ⚙️ Usage
- 🌐 Deploying behind a reverse proxy (Nginx)
- 💻 CLI reference
- 📡 API reference
- 🪝 Webhook receiver
- 🗂️ Project structure
- 🆕 What's new
- 📄 License
✨ 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 postgresCREATE DATABASE webhook_db;
CREATE USER webhook_user WITH PASSWORD 'yourpassword';
GRANT ALL PRIVILEGES ON DATABASE webhook_db TO webhook_user;
\qThen 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-playgroundOr 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 migrateMigrations 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-webhooksCreate a .env file:
DATABASE_URL=postgresql://user:password@localhost:5432/webhook_db
PORT=3000
BASE_URL=http://localhost:3000Replace
user,password, andwebhook_dbwith your actual PostgreSQL credentials.
Run migrations once:
webhook-play migrateStart the server:
webhook-play⚙️ Usage
1. Configure environment
Copy the example env file and fill in your values:
cp .env.example .envDATABASE_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 migrateThis creates the required tables (webhooks, webhook_requests) in your database.
3. Start the server
webhook-play
# or
webhook-play startTo run on a custom port:
PORT=8080 webhook-playWebhook microservice running at http://localhost:8080Open 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=/webhook2. 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 nginxThe app will then be accessible at https://yourdomain.com/webhook/.
Note: The
BASE_PATHvalue must match the Nginxlocationprefix exactly (e.g. both must be/webhook).
🩺 Health check endpoint
Useful for verifying a fresh install without needing any existing data:
GET /api/healthReturns 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/:idendpoint in the API reference and corrected thePUT /api/webhooks/:uuiddescription 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_PATHenvironment 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/healthendpoint — 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-mstowebhook-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
