Getting started
Tapeline is a local-first CLI for building and debugging webhook handlers. You run a small listener on your machine, point webhook traffic at it, and Tapeline records every request to an append-only store. From there you can watch events arrive, forward them to your app, and replay any captured event as many times as you need.
This page takes you from installation to your first forwarded event in about five minutes.
Requirements
Section titled “Requirements”- Node.js 22 or newer
- npm (bundled with Node.js)
- macOS, Linux, or Windows
Install the CLI
Section titled “Install the CLI”npm install --global tapelineCheck that the binary is on your path:
tapeline --versionCapture your first event
Section titled “Capture your first event”Start a listener with no arguments to use the defaults — port 8787, path
/hooks:
tapeline listen✔ listening on http://127.0.0.1:8787/hooks✔ recording to .tapeline/events.ndjsonThe listener accepts any HTTP method on /hooks and appends each request to
.tapeline/events.ndjson in your current directory. While nothing forwards
the event, Tapeline answers 202 Accepted so senders treat the delivery as
successful.
Send yourself a test event from a second terminal:
curl -X POST http://127.0.0.1:8787/hooks \ -H "Content-Type: application/json" \ -d '{"type":"ping","message":"hello tapeline"}'Then look at what was captured:
tapeline tail --last 112:04:11 POST /hooks ping → 202 stored as evt_2ah8vqThe event name column — ping here — is taken from the type field of a
JSON body when one exists, which matches the convention most providers use.
The evt_ id is how you refer to this exact request later, for example when
replaying it.
Forward events to your app
Section titled “Forward events to your app”Recording is useful on its own, but the everyday setup is Tapeline sitting in
front of the app you are building. Pass --forward with your local webhook
route:
tapeline listen --forward http://localhost:3000/webhooksNow every captured event is immediately re-sent to your app, and the tail
line shows your app’s response status and latency instead of 202:
12:06:47 POST /hooks ping → 200 in 41 ms stored as evt_5rw0dnReceive events from a real provider
Section titled “Receive events from a real provider”Tapeline never opens a public URL itself — it only binds to your machine. To receive events from an external provider, put any tunnel you already use in front of the listener:
cloudflared tunnel --url http://127.0.0.1:8787Paste the public URL the tunnel prints, plus the /hooks path, into your
provider’s webhook settings. Events now flow provider → tunnel → Tapeline →
your app, and every one of them is captured on the way through. The
forwarding guide walks through this end to end.
Where to next
Section titled “Where to next”- Configuration — pin your setup in a
tapeline.tomlinstead of repeating flags. - Forward webhooks to your app — the full provider-to-localhost workflow.
- Replay and filter events — find one event among hundreds and resend it.