Envello
Tutorial

Security alert emails: what to send, without crying wolf

Envello Team·2026-07-17·6 min read

Security alert emails exist to get a user's attention for something that actually needs it. Send too many, for events that don't warrant real concern, and users start ignoring or filtering them, which defeats the purpose the one time it actually matters.

What actually warrants an email

  • A new device or location signing in, especially one clearly outside the user's normal pattern
  • A password or email address change on the account
  • A new API key created or an existing one's permissions changed, for products where that's account-level access
  • Account recovery flows being initiated, since this is exactly the kind of event an attacker triggers

What belongs in an activity log instead

Routine, expected logins from a known device and location don't need an email, they'd just train users to ignore security emails entirely. Keep a queryable account activity log for that lower-signal information, and reserve email for events that genuinely warrant interrupting someone.

What the email should actually say

Be specific: what happened, when, and from where (approximate location, device type) if you have that data, plus a clear, immediate action if the user didn't do this (a "secure your account" link, not just "contact support"). Vague alerts ("unusual activity detected") without specifics train users to dismiss them just as effectively as sending too many alerts does.

Rate-limiting alerts without missing real ones

A single misbehaving script or a user rapidly toggling settings can generate a burst of technically-real security events in a short window. Debounce alerts of the same type for the same account within a short window (a few minutes is usually enough) rather than firing one email per event, and combine them into a single summary if several fire close together. The goal is one email that accurately represents what happened, not five that each look individually alarming.

Implementation: webhook-triggered vs. application-triggered

Two common patterns. Application-triggered: your own auth logic detects the event (new device fingerprint, password change) and calls the email API directly at that moment, giving you full control over the debouncing and content logic described above. Webhook-triggered: if you use a third-party auth provider (Clerk, Auth0, Supabase Auth), their webhooks fire on relevant events and your handler builds and sends the alert from that payload. Either pattern works, the debouncing and specificity guidance applies the same way regardless of which system detects the event.

Privacy-conscious location data

IP-based geolocation is approximate and can be wrong (VPNs, mobile carriers, corporate proxies), so phrase location in the alert as "approximate" rather than stating a specific city with false confidence. Under GDPR, an IP address is personal data, log it for the alert itself but don't retain a long-term history of every login location beyond what's needed for the account activity log's own retention window.

Testing security alerts without spamming real users

Trigger these flows against a test account with test-mode sending enabled, so you can verify the alert fires on the right conditions and reads correctly without either spamming a real user's inbox during development or, worse, accidentally suppressing the alert path entirely because it was never actually tested end to end.

Envello

EU-hosted transactional email, done right by default.