Forward webhooks to localhost with one npx command
webhook-toolkit gives you a public URL, prints every request in your terminal and re-sends it to your local server. No install, no account, no config file.
npx webhook-toolkit listen --forward http://localhost:3000/webhooks
What you see
✓ Webhook URL https://webhook-toolkit.com/r/Qx7pL2mN9aZk
Inspector https://webhook-toolkit.com/e/Qx7pL2mN9aZk
Forwarding → http://localhost:3000/webhooks
12:04:31 POST / stripe · checkout.session.completed 1.8 KB
→ 200 OK 23 ms
12:04:33 POST / stripe · invoice.paid 2.1 KB
→ 400 Bad Request 9 ms (your handler rejected it)The sender and the event are detected automatically (Stripe, GitHub, Shopify, Slack, Twilio, PayPal, Svix, Paddle…). Open the inspector link to see the full headers and body, or to let AI explain the payload.
Commands
| Command | What it does |
|---|---|
| listen [--forward <url>] | Create (or reuse) a webhook URL, stream requests live, forward each one to a local URL. |
| relay --to <port|url> | Real tunnel: the sender receives your local server's response. Needs the Pass or Pro. |
| sign <provider> --secret <s> | Build a payload with a valid signature (stripe, github, shopify, slack, twilio, mailgun, svix, paddle) and print a curl — or --send it. |
| verify <provider> --secret <s> | Check a signature against a raw body and tell you why it fails. |
| replay <token> <id> --to <url> | Re-send a captured request from your machine (localhost works). |
| requests <token> | List the requests captured by a URL (--json for scripts). |
| login --key whk_… | Tie the URLs you create to your account (they stop expiring). |
| mcp | Start the MCP server so Claude Code, Cursor or VS Code can use all of the above. |
Test a Stripe handler without Stripe
Generate an event with a valid Stripe-Signature for your own whsec_ secret and send it to your local handler:
npx webhook-toolkit sign stripe \
--secret whsec_your_test_secret \
--payload '{"type":"checkout.session.completed","data":{"object":{"id":"cs_test_1"}}}' \
--send http://localhost:3000/api/stripe/webhookWait for a webhook in your test suite
import { WebhookToolkit } from "webhook-toolkit";
const wt = new WebhookToolkit({ apiKey: process.env.WEBHOOK_TOOLKIT_KEY });
test("checkout sends the order webhook", async () => {
const endpoint = await wt.createEndpoint({ name: "ci" });
await placeOrder({ webhookUrl: endpoint.url });
const req = await wt.waitForRequest(endpoint.token, {
timeoutMs: 30_000,
filter: (r) => r.event === "order.paid",
});
expect(JSON.parse(req.body).data.amount).toBe(4900);
});Free, Pass or Pro?
listen, sign, verify, replay and mcp are free. Anonymous URLs last 7 days; a free account keeps one URL forever. relay, AI explanations, 25 permanent URLs and 30-day history come with the 7-day Pass (€5, no subscription) or Pro (€9/month).
Source code and issues: github.com/THE-KIPDEV/webhook-toolkit · Package: npmjs.com/package/webhook-toolkit
Preguntas frecuentes
How do I forward a webhook to localhost?
Run npx webhook-toolkit listen --forward http://localhost:3000/webhooks. You get a public URL; give it to Stripe, GitHub, Shopify or any sender. Each request is printed in your terminal and re-sent to your local server with the same method, headers and raw body, so signature verification keeps working.
Is it an alternative to smee.io and ngrok?
For webhooks, yes. listen works like the smee.io client (the sender gets the URL's configured response, your local server gets a copy). When the sender needs your local server's real answer — Twilio TwiML, Slack interactivity, Shopify timing checks — use webhook-toolkit relay, which tunnels the response back like ngrok, dedicated to webhooks.
Do I need an account?
No. Without an account the URL lasts 7 days. With a free account (npx webhook-toolkit login --key whk_…) the URL is permanent and tied to your dashboard. The Relay tunnel needs the 7-day Pass (€5) or Pro.
Which Node.js version do I need?
Node.js 18.17 or later. Nothing else to install: npx downloads the package on first use. You can also install it globally with npm i -g webhook-toolkit and use the short alias whtk.
Can I use it in automated tests?
Yes: import { WebhookToolkit } from 'webhook-toolkit', create a URL, point the system under test at it, then await wt.waitForRequest(token, { filter }) to assert on the webhook it sends. It works in Vitest, Jest, Mocha and Playwright.
Is the source code available?
Yes, the CLI, the testing library and the MCP server are MIT-licensed on GitHub: github.com/THE-KIPDEV/webhook-toolkit.