Skip to content

Destinations must be publicly reachable, so http://localhost:3000 cannot be one. Instead the whk CLI holds an authenticated stream open and replays each webhook against your local URL — nothing on your machine is exposed, and no tunnel is involved. If you are weighing this against ngrok and the other forwarding options, see ngrok alternatives for webhooks.

Download the whk binary for your platform from the releases page, make it executable and put it on your PATH:

Terminal window
chmod +x whk
sudo mv whk /usr/local/bin/
whk --version

Builds are published for Linux, macOS (Intel and Apple Silicon) and Windows.

Create an API key in the dashboard, then:

Terminal window
whk login --server https://app.webhooker.eu

The key is prompted for without echoing and saved to your user config directory, together with the server. whk whoami prints the workspace it resolved, which is the quickest check that the key is good.

The key can also come from the environment, which is what CI should do:

Terminal window
export WEBHOOKER_SERVER=https://app.webhooker.eu
export WEBHOOKER_API_KEY=whk_

Both have --server and --api-key flags on every command if you would rather pass them inline. whk logout deletes the saved credentials again.

Terminal window
whk tail stripe-prod

A source can be named by its name, its id or its ingest token. The stream prints one line per event as it arrives — method, size, verification result. Add --json for one JSON object per line, which pipes into jq.

This is metadata only: cheap, and enough to confirm a provider is really sending.

Terminal window
whk listen stripe-prod --forward http://localhost:3000/hooks

Each webhook is replayed against that URL with its original method and body. The command keeps running until you stop it.

Useful flags:

FlagEffect
--forward <url>Where to replay each webhook. Required.
--header "Name: Value"Extra header on the local request. Repeatable.
--skip-verifyAlso forward events whose inbound verification failed.
--jsonOne JSON object per line instead of human-readable output.
Terminal window
whk listen stripe-prod \
--forward http://localhost:3000/hooks \
--header "X-Env: local" \
--json

Two patterns work well:

  • A separate source. stripe-test with the provider’s test-mode endpoint pointed at it. Production keeps its own source, gateways and history.
  • One source, two gateways. Your deployed endpoint stays a gateway; you listen on the same source while you develop. Both see the same events.

Because events are stored, you do not need the provider to keep sending: trigger one event, then resend it from the event log as often as you like while you iterate on the handler. To fire synthetic events with a valid signature instead of waiting on the provider, the webhook mock sender sends Stripe, GitHub and Shopify payloads from your own machine.

SymptomCause
whk: command not foundThe binary is not on your PATH.
Login failsWrong key, or the wrong --server. Check with whk whoami.
tail connects but prints nothingNo events are arriving. Send a test event from the provider, or curl the ingest URL.
Too many open streamsYour plan caps concurrent live streams. Close other tail/listen sessions and dashboard tabs.
Events with failed verification never appearThey are withheld by default. Add --skip-verify while you debug a secret.
listen forwards, your app sees nothingCheck the local URL and port, and that the handler accepts the method the provider used.