Three things this is not
It is worth being blunt about these, because each one is a way a tunnel behaves differently. Metadata travels in headers so the body stays exactly what a webhook handler expects:
A handler that ignores all of them still works.
Narrow what you get
A local server that is not running yet does not end the session — that is the normal state while you are still starting your app. Each failure is reported and the CLI keeps listening; the exit code tells you afterwards that something was missed.
Watch without forwarding
tail prints events instead of forwarding them. With --json it prints one line per event, because a tail is a stream and has to be consumable a line at a time rather than as one document.
Send one
send posts the public ingest plane — the same URL a provider posts to — because there is no admin “send”. --endpoint takes an endpoint’s readable base slug, its id, its name, or a full workspace/project/slug path. Add --dataset raw to append a dataset segment, which stores the payload whole.
Run hookie listen in one terminal and hookie send in another and you have the whole round trip in front of you.
Replay a bad window
A replay cannot itself be replayed. The source row’s event id already carries a
#replay: marker, so a second one would be rejected. The CLI detects those, skips them, and says how many it skipped — rather than emitting deliveries that are guaranteed to fail.429, the run stops there rather than piling on.
Open the console where you are looking
A local Hookie
Everything above works against a localwrangler dev too, which is the default target:
HOOKIE_TOKEN, or just point at it. The remote gate only applies to origins that are not localhost.