Reference
CLI
catchook listen, replay and events — command and option reference.
npm i -g @catchook/cli # then: catchook listen …
npx @catchook/cli listen # or no install at all
Needs Node 22+ (for a global WebSocket) or any recent Bun. The published
binary is a single bundled file with no dependencies.
Commands
| Command | |
|---|---|
login | Prompts for an API key, verifies it, and saves it to $XDG_CONFIG_HOME/catchook/config.json with mode 600 |
listen | Streams events as they arrive and forwards each to a local URL |
replay [event] | Re-sends an event already received. With no argument, the most recent one |
events | Lists recent events, to pick an id from |
Options
| Option | |
|---|---|
--forward-to <url> | Where to send the request. Remembered, so later runs need no flag |
--endpoint <end_…> | Only handle this endpoint. Filtered server-side for listen |
--last <n> | replay: the last n events, oldest first |
--to-destinations | replay: send through real delivery instead of to your machine |
--sign-with <secret> | Add a catchook-signature computed exactly as production does |
--limit <n> | events: how many rows. Default 20 |
--timeout <ms> | How long to wait for your local server. Default 30000 |
--print | Non-interactive only: print the body and the response |
--json | NDJSON on stdout, for jq |
listen is a full-screen view
Given a terminal, listen takes over the screen: events on the left, the
selected one in full on the right — headers, body, and every attempt at
putting it on your machine.
catchook listen http://localhost:3000 ● live · 4 ev · 3 ✓ · 1 ✗
─ events (4) ───────────────────────────────┬─ detail ───────────────────────────────
15:05:12 stripe 200 1ms │ evt_d70ac86334f448f78e20822e647c583d
▸ 15:05:11 stripe 500 1ms ×2 │
15:05:10 github ✗ │ endpoint end_60e42bf9513149f2b89ddd…
│ provider stripe
│ signature valid
│ ── local forwards ───────────────────
│ 15:05:11 live 200 1ms
│ 15:05:15 replay 500 1ms
│ ↩ TypeError: cannot read property
| Key | |
|---|---|
↑ ↓ / k j | Move through the events |
pgup pgdn, g G | Page, jump to newest / oldest |
enter / r | Replay the selected event onto your machine |
a | Replay the whole session, oldest first |
tab | Switch focus between list and detail, then scroll it |
space | Pause / resume forwarding |
w | Pretty or raw body |
c | Clear the session |
q | Quit |
Piped, redirected, or with --json, none of this applies: the output is one
plain line per event, which is what grep and jq expect.
Configuration
Precedence is flag > environment > saved config > default.
| Variable | |
|---|---|
CATCHOOK_API_KEY | API key, instead of login |
CATCHOOK_API_URL | Control-plane base URL |
CATCHOOK_EVENTS_URL | Event-stream base URL |
CATCHOOK_FORWARD_TO | Default --forward-to |
Known limits
- The reconnect gap. The stream only pushes to subscribers connected at
that instant; anything that arrives during an outage reaches nobody. The
CLI says so on reconnect —
catchook replay --last Nis the answer. - A refused handshake carries no HTTP status. The CLI asks the API whether your key is at fault: if so it stops, otherwise it retries and tells you the key is fine so you look at your server.
- 14-day retention. Past that an event is no longer replayable.
- 100 KB per body. An ingestion limit, not a CLI one.