← All tools
Our notes

Local development for UnifyPort webhooks with ngrok

UnifyPort delivers events to a public HTTPS URL. If your handler lives on localhost — which it does, most days — you need a tunnel. ngrok has been our default for years.

What ngrok solves

One command and you get a public HTTPS URL that forwards every request to a local port. Everything passing through is captured by a request inspector at http://127.0.0.1:4040 — headers, body, timing, and replay button included. That second part is the reason we still use ngrok even when free tunnel alternatives exist; the inspector compresses what would otherwise be a logging sprint into a glance.

Five-minute setup for a UnifyPort handler

Assuming your handler is listening on port 3000:

  1. 1. ngrok http 3000 — copy the https://*.ngrok-free.app URL it prints.
  2. 2. Register the URL via POST /v1/webhook-endpoints — set url to https://<your-tunnel>.ngrok-free.app/events and pick the subscribed_events you actually want (or ["*"] while iterating).
  3. 3. Open http://127.0.0.1:4040 in a browser. Trigger an event from the provider side — a Telegram DM, a WhatsApp message — and watch it land.
  4. 4. Use the replay button to retry the same delivery against an updated handler. This is what makes ngrok faster than re-triggering events from the provider every time you change code.

Verifying the signature locally

The free ngrok tunnel terminates TLS upstream, so by the time your handler sees the request, the body is already decoded — exactly what UnifyPort signed. That means signature verification works the same as in production: compute hex(HMAC-SHA256(secret, timestamp + "." + body)) and compare against the X-Device-Signature header. If you want to confirm by hand before adding code, our CyberChef recipe walks through the same algorithm in a browser.

When ngrok stops being the right answer

  • Staging or demo environments. The free URL rotates on every restart, which breaks long-lived configurations. Reach for a paid reserved domain — or switch to Cloudflare Tunnel for a free stable hostname.
  • High-frequency load tests. Free-tier ngrok throttles aggressively. Either upgrade or run your handler in a real environment.
  • Pure webhook-only workflows with no other HTTP traffic. smee.io is lighter — no binary to install, just a client script.

Common questions

Why do I need ngrok for UnifyPort webhooks?
UnifyPort delivers events to a public HTTPS URL. A handler running on localhost:3000 isn't reachable from the internet, so ngrok bridges the two — one command publishes a https://*.ngrok-free.app URL that forwards every request to your local port.
Does ngrok break HMAC signature verification?
No. The free ngrok tunnel terminates TLS upstream, but the body bytes your handler receives are exactly the bytes UnifyPort signed. Signature verification works identically to production: compute hex(HMAC-SHA256(secret, timestamp + "." + body)) and compare to X-Device-Signature.
Is ngrok safe to use with real signing secrets?
For local dev with development-only secrets, yes — traffic is encrypted end-to-end and ngrok's inspector runs locally. For staging environments, demos, or production-grade traffic, prefer a paid reserved ngrok domain or switch to Cloudflare Tunnel, which gives you a stable free hostname.

Recommended UnifyPort dev loop

One bot/account dedicated to local dev, ngrok tunnel kept running in a terminal pane, handler reload-on-save, and the 4040 inspector pinned in a browser tab. When something looks off, replay from 4040 against the rebuilt handler — almost always faster than re-coaxing the provider into firing the same event.