Home/Email API/Secure webhooks

How to secure webhooks

A webhook endpoint is a public URL that mutates your system. Unverified, it's an open door: anyone who finds it can POST fake events. Signature first, everything else second.

Verified By George Hartley, Co-founder · Updated July 20, 2026

The threat is simpler than you think

Your webhook URL will leak: logs, browser history, a screenshot. The attack isn't exotic, it's curl: a forged "bounced" event that suppresses your best customer, or a fake "delivered" that corrupts your analytics. Any endpoint that acts on unverified POSTs hands write access to strangers.

The four controls

1. Verify the signature. Every Nitrosend event carries an HMAC-SHA256 signature computed over the payload with your webhook secret. Recompute, compare with a constant-time check, reject mismatches before parsing anything.

2. Bound the timestamp. Reject events older than a few minutes; that turns a captured payload into a dead one and kills replay attacks.

3. Process idempotently. Key on the event ID so a replayed or retried event changes nothing the second time.

4. Keep the secret a secret. Environment, not code; rotate it if it ever touches a log.

The same discipline applies when you're the one receiving a platform's webhooks. Our Shopify app runs an HMAC-verified install handler, returns exactly the status codes Shopify expects so it never gets silently deactivated, and implements all three mandatory GDPR webhooks. And a lesson from the abuse side of the fence: when you suspend anything, the block has to cover every send path. We once silenced an account and watched mail keep flowing through a path the block didn't reach, which is why a single gate now fronts them all. A control that covers most paths covers none.

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

Prove the controls work before production: test your webhook, including the wrong-signature and replay cases.

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.

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

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