Test Sume webhooks locally with ngrok or a Cloudflare Tunnel

Sume refuses localhost webhook URLs. Expose your handler with ngrok or a Cloudflare Quick Tunnel, send a signed test, then redeliver real events.

5 min readSume
All posts

To test Sume webhooks on localhost, run your handler on a local port, expose it with ngrok http 8080 or cloudflared tunnel --url http://localhost:8080, and register the tunnel's HTTPS URL plus your handler's path as the webhook URL. Sume refuses localhost, private-network, and non-HTTPS webhook URLs, so a public HTTPS tunnel is what makes a local handler reachable.

Sume ships no connector for either tool; each one forwards Sume's POST to your port like any other public request. Sume facts come from Webhooks and Run webhooks; tunnel behavior comes from ngrok's and Cloudflare's own docs, read 2026-09-27. For a deployed endpoint that stops receiving events, see Sume webhook not received?

Why can't Sume send webhooks to localhost?

The webhook POST comes from Sume, not from your machine, so the URL has to be reachable from the public internet. The docs say webhook URLs must be public HTTPS; localhost, private-network, and non-HTTPS URLs are rejected with 400 invalid_request when you submit, and the URL is checked again at delivery time. Current code also refuses hostnames ending in .local, .internal, or .test, and any explicit non-default port, so http://localhost:8080/hooks/sume and https://my-laptop.local:8443/hooks/sume both fail.

A tunnel gives you a public HTTPS hostname on the default port that forwards to your machine. Webhook URL rejected as invalid? lists every rule and the exact error.

Should I use ngrok or a Cloudflare Quick Tunnel?

Both give your local port a public HTTPS URL. ngrok's free plan shows a browser warning page, but only on HTML browser traffic; its docs say it does not affect APIs or programmatic requests. Cloudflare says Quick Tunnels are for testing and development only.

From ngrok's Free Plan Limits and Share Localhost Quickstart, Cloudflare's Quick Tunnels docs, and try.cloudflare.com, read 2026-09-27.
Detailngrok free planCloudflare Quick Tunnel
Startngrok config add-authtoken $YOUR_TOKEN, then ngrok http 8080cloudflared tunnel --url http://localhost:8080
AccountAn ngrok account and its auth tokenNo Cloudflare account required
Public URLOne dev domain assigned to your account, such as your-assigned-name.ngrok-free.app, served over HTTPSA random subdomain on trycloudflare.com, with automatic HTTPS
Limits20,000 HTTP requests a month; 4,000 a minute200 in-flight requests, then 429; no SLA or uptime guarantee
LifetimeFree endpoints have no timeoutEnds with the cloudflared process

How do I run the local loop?

Start the handler, open the tunnel, and register the full URL with its path. Sume does not follow redirects: a 3xx, such as a framework's trailing-slash redirect, is a failed attempt. Prove the tunnel and your signing secret with Send test, which POSTs a signed dummy webhook.test event to the URL you name, applies the same URL rules as a real submit, and returns the status_code your handler answered; the debugging guide covers its fields.

Then submit a real job or run with the tunnel URL as its webhook URL. You cannot point an existing job at the tunnel: Redeliver never sends to a different URL, and for jobs a new URL means a new job.

# Terminal 1: your handler listens on localhost:8080. Expose it:
ngrok http 8080
# or, with no account:
cloudflared tunnel --url http://localhost:8080

# Terminal 2: send a signed test event to the printed HTTPS URL plus your path
curl -X POST https://api.sume.com/v1/webhooks/test-deliveries \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "webhook_url": "https://your-assigned-name.ngrok-free.app/hooks/sume" }'

Should I replay from ngrok's inspector or use Sume's Redeliver?

ngrok's Traffic Inspector shows each request's headers and body, and Replay resends a captured request with the same method, headers, and body as the original. For a Sume delivery that includes the original x-sume-webhook-timestamp and signature. Sume's docs tell receivers to reject timestamps outside a replay window, five minutes being a reasonable default, so an inspector replay only verifies inside that window.

For anything older, use Sume's Redeliver: POST /v1/jobs/{job_id}/webhook/redeliver with jobs:write, or POST /v1/format-runs/{run_id}/webhook/redeliver with formats:write. It re-POSTs the real terminal event with a fresh timestamp and signature, works after the automatic attempts are exhausted, and does not use up one of the 10.

What breaks during a local session?

Three things to watch:

  • Restarting a Quick Tunnel. Each launch generates a new random trycloudflare.com subdomain, and the webhook URL is stored with each job or run and checked again at delivery. Work you submitted before the restart still targets the old hostname, while ngrok's free plan keeps one dev domain on your account.
  • Breakpoints. Each attempt gets 10 seconds, and a slow endpoint burns the budget and gets retried. Job deliveries retry up to 10 attempts at a fixed delay, 30 seconds by default; run deliveries back off exponentially. Store the event, answer 2xx, then debug.
  • Tunnel limits. Past 200 in-flight requests a Quick Tunnel answers 429, which Sume treats as a failed attempt and retries; run deliveries also honor Retry-After on a 429.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume