// use case
Test Stripe webhooks against your localhost in 30 seconds
Reserve your stable subdomain
On the free plan you keep one reserved subdomain forever. Pick a name Stripe can paste into its dashboard once and never again. If `stripe-dev` is already taken by someone else, the CLI offers three friendly fallbacks like `curious-otter`, `floppy-panda`, `swift-axolotl` — pick one and the rest of the steps stay the same.
$ lrok reserve stripe-dev 'stripe-dev' is already reserved on lrok.io. Suggestions: 1) curious-otter 2) floppy-panda 3) swift-axolotl Reserve one? [1/2/3/n] 1 Reserved https://curious-otter.lrok.ioRun your webhook handler
Run your app on whatever port handles the webhook route.
$ npm run dev # or rails s, ./bin/start, etc.Tunnel it
Use the name you reserved (your own or a suggested one) as the --hint. Skip --hint entirely and lrok generates a random name on every run — handy when you don't need a stable URL.
$ lrok http 4242 --hint stripe-dev Forwarding https://stripe-dev.lrok.io -> http://127.0.0.1:4242Paste the URL into Stripe
Stripe Dashboard → Developers → Webhooks → Add endpoint. Paste https://stripe-dev.lrok.io/webhook (or whatever your route is).
Replay any request from /dashboard
Each delivered webhook lands in the live request inspector — body, headers, status, latency. Click replay to re-deliver against your local handler.
// why lrok for this
The stable subdomain is free. ngrok charges for that on Pro plans; [localtunnel](/compare/localtunnel) and [Serveo](/compare/serveo) do not guarantee names survive restarts. lrok is [$9/mo flat — no SSO tax, no enterprise upsell](/blog/no-sso-tax-pricing). For a deeper look at why random URLs break webhook integrations daily and how lrok's implementation works, read [Killing the ngrok URL-rotation problem](/blog/killing-the-url-rotation-problem).