wbhk listen tails the endpoint and re-delivers each event to your loopback target, preserving the original body and headers. No tunnel to configure, no public URL to expose — the events were already captured, so this just replays them to your machine. Capture a real webhook once, then replay it as many times as you like while you iterate on the handler.
This is a CLI capability: forwarding to localhost only makes sense from the machine running your server, so it lives where localhost lives.
At-least-once, cursor-gated
listen --forward advances its cursor only after your local handler returns a 2xx. Records and acks happen post-success, so if your server is down, throws, or your laptop sleeps mid-batch, the un-acked events are re-read on the next run rather than lost. You get at-least-once delivery to localhost — design your handler to be idempotent.
The target must be a loopback address (localhost / 127.0.0.1). A non-loopback URL is rejected: a captured payload and its signature must never be replayed out to some arbitrary host from your terminal.
Choose where to start
By defaultlisten starts from now — only events captured after you connect. Point it elsewhere with --since:
Related flags:
--resume— start from the last acked cursor for this profile and endpoint, and keep saving it as you go.--reset— forget that saved cursor before starting.--max-backlog <n>— refuse to start if more thannevents are waiting, so you don’t fire a large backlog at your dev server by surprise.
Drive it interactively
Runwbhk listen in a terminal (a TTY) and it shows a live table of events as they arrive. Move with the arrow keys and press r to replay the selected event to your --forward target on demand — the tight loop for debugging one specific payload against a handler you’re editing.
The local-dev loop
- Trigger the webhook in your provider once (or
curlyour ingest URL). It’s captured. wbhk listen <endpoint-id> --forward http://localhost:3000/webhooks --since beginning.- Edit your handler. Press
rto replay the same event, or re-run with--reset --since beginningto replay the batch. Repeat until it’s right.