Troubleshooting: my webhook isn't arriving
What this is: an ordered checklist for the single most common support question — "I registered an endpoint and nothing shows up." Work through it top to bottom; each step is more common than the one after it.
1. Is your public tunnel up?
If you're developing locally, InsurGrid can only reach you through a tunnel (ngrok or similar). Tunnels drop when:
The tunnel process was stopped or your machine went to sleep.
You're on a free plan whose URL changes every restart — and the dashboard still has the old one saved.
Fix: confirm the tunnel is running, copy its current https://… URL, and make sure it matches what's saved in the API section. See Expose your local endpoint.
2. Are you returning a 2xx — fast?
The single most common cause once your tunnel or deployment is confirmed up: your endpoint received the request but didn't acknowledge it correctly.
Confirm your route returns
200(or any2xx) on success — not204from a framework default you haven't checked, not a500from an unhandled exception in your handler.Confirm you're responding before doing slow work (database writes, downstream API calls). Do the slow work after you've already replied. See Set up a webhook endpoint.
Check your server's own error logs for exceptions thrown during the request — a crash before
res.send(...)looks identical to "never responded."
3. Check the delivery log
Look at the delivery log in the API section. It records every attempt InsurGrid made, whether or not your server responded — it tells you where in the chain things actually broke, instead of guessing.
Nothing in the log at all → InsurGrid never tried to deliver. Skip to step 4 (wrong URL/topic/environment) — this isn't a network or code problem yet.
An attempt is logged, but it shows a non-
2xxstatus or a timeout → confirms the issue is on your side; revisit step 2.An attempt is logged with
200→ delivery succeeded on InsurGrid's side. If you still don't see it in your own logs, the problem is downstream of your endpoint (a queue, a crash after the response, a logging gap) — not InsurGrid.
4. Is your endpoint URL saved for the right topic and environment?
A URL registered for client-submission never receives form-submission events, and a staging URL never receives events triggered against production (or vice versa). Double-check, in the API section:
The URL is saved under the topic you expect (
client-submissionfor policy data,form-submissionfor form submissions).You're looking at the right environment — a test event or a sandbox form submission goes to your staging URL, not production.
The URL is typed correctly, including the path (
/hooks/insurgridor whatever route you chose) — a URL that's missing the path but otherwise resolves can silently 404.
5. Is your endpoint reachable at all?
It must be HTTPS, not plain HTTP.
If it sits behind a firewall, load balancer, or VPN, confirm InsurGrid's requests aren't being blocked before they reach your application code.
Try
curl-ing your own endpoint's URL from outside your network to confirm it's actually public.
Signature check fails
You're receiving the webhook (it shows in the delivery log and your server logs a request), but your signature verification rejects it.
The #1 cause: you're hashing the parsed-and-re-serialized JSON instead of the exact raw bytes InsurGrid sent. Re-serializing a parsed object almost never reproduces the original bytes exactly (whitespace, key order, number formatting can all differ), so the hash won't match even though the request is genuine. Capture the raw body before your framework parses it. See Verify a webhook signature.
Confirm you're using the signing secret for the environment the event came from — a staging secret never validates a production signature, and vice versa.
Confirm you're comparing against the
x-signatureheader, not a different header, and that nothing upstream (a proxy, a framework middleware) is modifying the body before your handler sees it.If you deliberately configured a different auth scheme (Bearer, Basic, API key) during setup,
x-signaturewon't be present at all — check Register your endpoint & choose an auth type for what to verify instead.
Getting duplicates
You're processing the same event more than once.
This is expected, not a bug on InsurGrid's side: delivery is at-least-once, so the same event can legitimately arrive twice (for example, if a retry overlaps a slow success on your end).
The fix lives in your handler, not in delivery: derive a de-dupe key and make reprocessing it a no-op — use
data.submission_idfor form submissions, and a hash ofdatafor policy-data (which has no id field). See Delivery & de-duplication.If you're seeing duplicates you can't collapse — form submissions with different
submission_ids, or policy-data whose contents differ slightly — check whether your endpoint is registered twice (once directly, once through a proxy or a second dashboard entry); that produces two independent deliveries, not one retried delivery.
Still stuck?
Have your request_id or trace_id from the delivery log ready and see Support & contact.
