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.
ngrok http 3000— copy thehttps://*.ngrok-free.appURL it prints. - 2. Register the URL via
POST /v1/webhook-endpoints— seturltohttps://<your-tunnel>.ngrok-free.app/eventsand pick thesubscribed_eventsyou actually want (or["*"]while iterating). - 3. Open
http://127.0.0.1:4040in a browser. Trigger an event from the provider side — a Telegram DM, a WhatsApp message — and watch it land. - 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:3000isn't reachable from the internet, so ngrok bridges the two — one command publishes ahttps://*.ngrok-free.appURL 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 toX-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.