Home/Email API/Test a webhook

How to test a webhook

Inspect the payload before you write the handler, tunnel to localhost while you build it, and verify the signature before you trust it. Three stages, in that order.

Verified By Kam Low, Co-founder · Updated July 20, 2026

Stage one: see the payload

Before writing a line of handler code, point the webhook at a request bin, a throwaway URL that captures whatever arrives (webhook.site and friends exist exactly for this). Fire a test event and read the actual payload: field names, types, timestamp format. Real payloads beat documentation every time.

Stages two and three: localhost, then trust

While building the handler, tunnel production events to your machine: an ngrok-style tunnel gives your localhost a public URL, so real events hit your debugger. Send yourself a message, watch delivered fire, force a bounce with a bad address, watch that fire too.

Before production, test the paranoid paths: replay the same event twice and confirm nothing double-processes, send a payload with a wrong signature and confirm your handler rejects it. Nitrosend signs every event with HMAC-SHA256; a handler that skips verification is an open door with logging.

Test against events, not API responses. I once trusted a live response that read "sent: 0, failed: 2, status: completed" and shipped the campaign again as a resend. It was the third copy. The response told me the request finished. Only the event stream tells you what actually happened.

Test data shapes what you can test, too. QA on one of our re-engagement flows surfaced a 404 on the unsubscribe link, and the cause was the test path itself: the legacy test-send used recipients that weren't real contacts, so there was no contact to bind an unsubscribe token to. The fix was routing test sends through the real transactional endpoint with real contacts, so every link works because nothing is mocked. If your test path and your production path differ, you're testing the test path.

Full parameters and responses live in the REST API docs and the API reference.

Incoming webhook
{ "event": "delivered" … }
X-Nitrosend-Signature:
sha256=7f3a…c91e
Your server verifies
hmac_sha256(secret, body)
== header signature?
match → process ✓ no match → drop
Anyone can POST to a public URL. Only Nitrosend can sign with your secret. Same figure, second crop, works for /webhook-test.

Go deeper

The signature check and the rest of the hardening: how to secure webhooks. The mechanism itself: webhooks explained. Testing the receipt is one layer of deliverability testing, and the events it delivers are what surface bounce rate.

First send in thirty seconds.

Simple pricing. Unlimited contacts.

Every plan includes full stack emailing: Flows, Newsletter Campaigns and Transactional Email, plus our NitroWheel LLM and all agent integrations (Claude, ChatGPT, Codex, Cursor and others). Pay for what you send, not who you store.

Plan limits are ceilings, not guaranteed immediate send headroom; only mature, clean volume sent through that exact sender can raise its capacity.

Free
$0
forever
  • Emails 8,000then 500/mo
  • Email types Transactional & Marketing
  • AI actions 20/mo
  • Contacts Free & Unlimited
  • Brands 3
  • Seats 1
  • Commercial recipients / rolling 24h 50
  • Email validation Prepaid only
Start free
Ultra
$100
per month
  • Emails 125,000/month
  • AI actions 5,000/mo
  • Brands 10
  • Seats 10 · Domains 10
  • Frontier AI Included
  • Dedicated IP Available
  • Commercial recipients / rolling 24h 62,500
  • Email validation Prepaid only
Get started
Enterprise
$300
per month
  • AI actions Unlimited
  • Unlimited brands & domains Included
  • SSO / SAML Included
  • 99.9% SLA Included
  • Commercial recipients / rolling 24h Contracted
  • Email validation Prepaid only
Get started

Free forever. No credit card required. See full comparison →