SOP: Email Deliverability for Web Applications
SOP: Email Deliverability for Web Applications
Section titled “SOP: Email Deliverability for Web Applications”Document Type: Standard Operating Procedure (SOP)
Version: 1.0
Status: Approved for Use
Audience: Technician
Confidentiality: Internal
Platforms Supported: Any web application sending transactional email
1. Purpose
Section titled “1. Purpose”To ensure that automated emails sent by web applications (account verification, password resets, order confirmations, notifications) are delivered to the recipient’s inbox — not their spam folder.
This SOP covers DNS authentication, email provider configuration, and a verification checklist that should be completed before any site goes live.
2. Scope
Section titled “2. Scope”This SOP applies to:
- Transactional email from web applications (auth emails, notifications, receipts)
- DNS record setup for email authentication (SPF, DKIM, DMARC)
- Email service provider domain verification
- Auth provider custom SMTP relay configuration
- Deliverability testing and scoring
Not included:
- Client-facing email accounts (see SOP: Email Setup Services)
- Email marketing campaigns
- Mailing list management
3. Responsibilities
Section titled “3. Responsibilities”Technician Responsibilities
- Configure sending subdomain and DNS records
- Set up email service provider and verify domain
- Configure auth provider SMTP relay
- Run deliverability tests and verify passing scores
- Document the sending configuration for the project
Project Manager Responsibilities
- Ensure email deliverability is included in project scope
- Verify testing is completed before go-live
- Confirm client has DNS access or delegate credentials
4. Requirements
Section titled “4. Requirements”4.1 Access Requirements
Section titled “4.1 Access Requirements”- DNS management access (e.g., Cloudflare, GoDaddy, Namecheap)
- Email service provider account (e.g., Resend, SendGrid, Postmark, Mailgun)
- Auth provider dashboard access (e.g., Supabase, Firebase, Auth0) — if auth emails are in scope
4.2 Tools
Section titled “4.2 Tools”- Terminal with
digcommand (for DNS verification) - mail-tester.com (for deliverability scoring)
- Access to Gmail, Outlook, and Yahoo test accounts (for cross-provider testing)
5. Procedure — Subdomain Strategy
Section titled “5. Procedure — Subdomain Strategy”5.1 Why a Subdomain
Section titled “5.1 Why a Subdomain”Never send transactional email from the root domain. Always use a dedicated subdomain.
| Concern | Root domain | Subdomain |
|---|---|---|
| Reputation isolation | If deliverability suffers, your entire domain is affected | Subdomain reputation is separate from root |
| Blocklist risk | Root domain blocklisted = all email affected (including business email) | Only the sending subdomain is at risk |
| DNS clarity | SPF/DKIM records mix with business email records | Clean separation of concerns |
5.2 Naming Conventions
Section titled “5.2 Naming Conventions”Choose a subdomain name that reflects its purpose:
| Subdomain | Use case |
|---|---|
updates.domain.com | General transactional (notifications, auth) |
mail.domain.com | Generic sending |
notify.domain.com | Notification-heavy apps |
send.domain.com | Simple, common convention |
The “From” address should be noreply@{subdomain} for automated emails.
Example:
noreply@updates.wizardtechservices.com
6. Procedure — DNS Record Setup
Section titled “6. Procedure — DNS Record Setup”Every sending subdomain needs four types of DNS records. SPF and DKIM do not inherit from the root domain — each subdomain must have its own.
6.1 SPF (Sender Policy Framework)
Section titled “6.1 SPF (Sender Policy Framework)”What it does: Tells receiving mail servers which IP addresses are allowed to send email for this domain.
Record type: TXT
Name: The sending subdomain (or a sub-subdomain like send.updates — check your provider)
Format:
v=spf1 include:{provider-spf-domain} ~allCommon provider SPF includes:
| Provider | SPF include |
|---|---|
| Resend (via Amazon SES) | include:amazonses.com |
| SendGrid | include:sendgrid.net |
| Postmark | include:spf.mtasv.net |
| Mailgun | include:mailgun.org |
Example (Resend + Cloudflare):
Type:TXT| Name:send.updates| Content:v=spf1 include:amazonses.com ~all
6.2 DKIM (DomainKeys Identified Mail)
Section titled “6.2 DKIM (DomainKeys Identified Mail)”What it does: Adds a cryptographic signature to every email, proving it hasn’t been tampered with in transit. The receiving server checks the signature against a public key in your DNS.
Record type: TXT or CNAME (varies by provider)
Name: Provider-specific (e.g., resend._domainkey.updates, s1._domainkey.send, etc.)
Value: Provided by the email service — this is a public key, not something you generate.
Example (Resend + Cloudflare):
Type:TXT| Name:resend._domainkey.updates| Content:p=MIGfMA0GCSq...(key from Resend dashboard)
6.3 MX (Mail Exchange)
Section titled “6.3 MX (Mail Exchange)”What it does: Enables the email provider to receive bounce notifications and complaint feedback for emails sent from this subdomain.
Record type: MX
Name: The sending subdomain
Priority: 10
Value: Provider’s feedback SMTP server
Example (Resend + Cloudflare):
Type:MX| Name:send.updates| Priority:10| Content:feedback-smtp.us-east-1.amazonses.com
6.4 DMARC (Domain-based Message Authentication, Reporting & Conformance)
Section titled “6.4 DMARC (Domain-based Message Authentication, Reporting & Conformance)”What it does: Tells receiving servers what to do with emails that fail SPF/DKIM checks, and where to send reports about authentication results.
Record type: TXT
Name: _dmarc.{subdomain} (e.g., _dmarc.updates)
Format:
v=DMARC1; p={policy}; rua=mailto:{reports-email}Policy values:
| Policy | Meaning | When to use |
|---|---|---|
p=none | Monitor only, don’t act on failures | Initial setup if unsure about all senders |
p=quarantine | Send failures to spam/junk | Recommended baseline for sending subdomains |
p=reject | Block failures entirely | After monitoring confirms no legitimate failures |
For a dedicated sending subdomain (where the only sender is your email provider), go straight to p=quarantine. There’s no risk of blocking legitimate email from other sources.
Example (Cloudflare):
Type:TXT| Name:_dmarc.updates| Content:v=DMARC1; p=quarantine; rua=mailto:support@domain.com
Also strengthen the root domain DMARC if it’s set to p=none:
v=DMARC1; p=quarantine; rua=mailto:support@domain.com; pct=1007. Procedure — Email Provider Domain Verification
Section titled “7. Procedure — Email Provider Domain Verification”This section walks through verifying a sending domain with your email provider. The steps are similar across providers.
7.1 Generic Steps
Section titled “7.1 Generic Steps”- Log in to your email service provider dashboard
- Navigate to Domains or Sender Authentication
- Click Add Domain → enter your sending subdomain (e.g.,
updates.domain.com) - The provider will generate the exact DNS records you need (SPF, DKIM, MX)
- Add each record to your DNS provider (see Section 6)
- Return to the email service dashboard and click Verify
- Wait for propagation (usually under 5 minutes with Cloudflare)
- All status indicators should turn green
7.2 Example — Resend
Section titled “7.2 Example — Resend”Note: Resend is used here as an example. The same pattern applies to SendGrid, Postmark, Mailgun, etc.
- Go to resend.com/domains
- Click Add Domain → enter
updates.clientdomain.com - Resend provides three records:
- DKIM: TXT record for
resend._domainkey.updates - SPF: TXT record for
send.updateswithinclude:amazonses.com - MX: MX record for
send.updatespointing tofeedback-smtp.us-east-1.amazonses.com
- DKIM: TXT record for
- Add all three in Cloudflare (set to DNS only, not Proxied)
- Add DMARC manually (Resend doesn’t generate this — see Section 6.4)
- Return to Resend and click Verify — all three should show green checkmarks
8. Procedure — Auth Provider SMTP Configuration
Section titled “8. Procedure — Auth Provider SMTP Configuration”If the web application uses a hosted auth provider (Supabase, Firebase, Auth0, etc.) for signup/login, the auth provider sends verification and password reset emails. By default these come from the provider’s own domain (e.g., noreply@mail.app.supabase.io), which looks unprofessional and may trigger spam filters.
Configure custom SMTP so auth emails route through your email service and use your verified sending domain.
8.1 Generic Steps
Section titled “8.1 Generic Steps”- In your email service provider, find or generate SMTP credentials (host, port, username, password)
- In your auth provider dashboard, go to Authentication → SMTP Settings (or equivalent)
- Enable custom SMTP and enter the credentials
- Set the Sender email to match your verified domain (e.g.,
noreply@updates.domain.com) - Save and send a test email
8.2 Example — Supabase Auth via Resend SMTP
Section titled “8.2 Example — Supabase Auth via Resend SMTP”Note: Supabase and Resend are used as examples. The pattern is the same for Firebase + SendGrid, Auth0 + Postmark, etc.
- In Resend, go to API Keys and generate an SMTP credential, or use the API key as the SMTP password
- In Supabase Dashboard → Project Settings → Authentication → SMTP Settings:
- Host:
smtp.resend.com - Port:
465 - Username:
resend - Password: Your Resend API key
- Sender email:
noreply@updates.clientdomain.com
- Host:
- Save and test by triggering a signup on the app
Critical: The “Sender email” must match the verified sending domain. If the domain in the “From” address doesn’t match what’s verified in your email provider, emails will fail DKIM/SPF.
9. Procedure — Google & Microsoft Sender Requirements (2025)
Section titled “9. Procedure — Google & Microsoft Sender Requirements (2025)”Major mailbox providers enforce strict sender authentication. Non-compliant emails are junked or rejected outright.
9.1 Google Gmail (enforced November 2025)
Section titled “9.1 Google Gmail (enforced November 2025)”Applies to: All senders to personal Gmail accounts (stricter for 5,000+ msgs/day)
| Requirement | Details |
|---|---|
| SPF or DKIM | At least one must pass (both recommended) |
| DMARC | Required with alignment to SPF or DKIM |
| TLS | Email must be sent over encrypted connection |
| Spam rate | Must stay below 0.3% |
| One-click unsubscribe | Required for marketing email (not transactional) |
9.2 Microsoft Outlook (enforced May 2025)
Section titled “9.2 Microsoft Outlook (enforced May 2025)”Applies to: Senders to Outlook.com, Hotmail, Live.com
| Requirement | Details |
|---|---|
| SPF + DKIM + DMARC | All three required with alignment |
| Valid From/Reply-To | Must use real, monitored addresses |
| Unsubscribe option | Required for bulk/marketing email |
| Compliance | Non-compliant emails blocked as of July 2025 |
Bottom line: If SPF, DKIM, and DMARC aren’t all passing, emails to Gmail and Outlook users will land in spam or be rejected entirely.
10. Validation / Verification
Section titled “10. Validation / Verification”10.1 DNS Verification Commands
Section titled “10.1 DNS Verification Commands”Run these from a terminal after adding DNS records. All should return values (not empty):
# Check SPFdig TXT send.updates.clientdomain.com +short
# Check DKIMdig TXT resend._domainkey.updates.clientdomain.com +short
# Check MXdig MX send.updates.clientdomain.com +short
# Check DMARC (subdomain)dig TXT _dmarc.updates.clientdomain.com +short
# Check DMARC (root)dig TXT _dmarc.clientdomain.com +shortReplace clientdomain.com, send.updates, and resend._domainkey.updates with the actual record names from your email provider.
10.2 Mail-Tester Score
Section titled “10.2 Mail-Tester Score”- Go to mail-tester.com
- Copy the test email address shown on the page
- Trigger an email from the app to that address (or send one via the provider’s API/dashboard)
- Click “Then check your score”
- Target: 9+/10 — anything below 7 indicates a problem
10.3 Email Header Check
Section titled “10.3 Email Header Check”Open a received test email and view the full headers (in Gmail: three dots → “Show original”). Confirm:
spf=passdkim=passdmarc=pass
All three must show pass. If any show fail, softfail, or none, go to Troubleshooting.
10.4 Cross-Provider Testing
Section titled “10.4 Cross-Provider Testing”Send test emails to accounts on each major provider and verify inbox delivery (not spam):
- Gmail
- Outlook / Hotmail
- Yahoo Mail
- Apple Mail (iCloud)
10.5 Pre-Launch Checklist
Section titled “10.5 Pre-Launch Checklist”| Check | Status |
|---|---|
| Sending subdomain chosen and documented | |
SPF record added and resolves via dig | |
DKIM record added and resolves via dig | |
MX record added and resolves via dig | |
DMARC record added for subdomain (p=quarantine minimum) | |
Root domain DMARC strengthened (p=quarantine or p=reject) | |
| Domain verified in email provider dashboard (all green) | |
| Auth provider custom SMTP configured and “From” matches domain | |
| mail-tester.com score 9+/10 | |
| Email headers show spf=pass, dkim=pass, dmarc=pass | |
| Test email delivered to inbox on Gmail | |
| Test email delivered to inbox on Outlook |
11. Troubleshooting (Common)
Section titled “11. Troubleshooting (Common)”| Problem | Cause | Fix |
|---|---|---|
| Emails land in spam | Missing or failing SPF/DKIM/DMARC | Verify all DNS records resolve correctly with dig |
spf=softfail in headers | SPF record uses ~all but provider not included | Add the correct include: for your email provider |
spf=fail in headers | No SPF record for the sending subdomain | SPF doesn’t inherit from root — add one for the subdomain |
dkim=fail in headers | DKIM record missing or wrong key | Re-copy the DKIM value from provider dashboard; check for typos |
dmarc=none in headers | No DMARC record for the sending subdomain | Add _dmarc.{subdomain} TXT record |
dmarc=fail in headers | ”From” domain doesn’t align with SPF/DKIM domain | Ensure the “From” address uses the same subdomain that has SPF/DKIM |
| Domain shows “Not Verified” in provider | DNS records haven’t propagated | Wait 5-15 minutes; Cloudflare is usually instant, other registrars can take up to 48 hours |
| Auth emails still come from provider’s domain | Custom SMTP not enabled or “From” not set | Check auth provider SMTP settings; ensure sender email matches verified domain |
| Bounces not being tracked | No MX record on sending subdomain | Add the MX record your email provider requires |
| mail-tester score below 7 | Multiple issues (check the report details) | mail-tester shows exactly what’s failing — fix each item listed |
| Emails to Outlook blocked entirely | Microsoft 2025 enforcement | Ensure SPF + DKIM + DMARC all pass with alignment |
12. Maintenance
Section titled “12. Maintenance”- Monitor DMARC reports: Check the
ruainbox periodically for aggregate reports — look for unexpected authentication failures - Review provider dashboard: Check bounce rates and complaint rates monthly; keep complaint rate below 0.1%
- DMARC policy progression: After 2-4 weeks of clean reports, upgrade from
p=quarantinetop=reject - Re-test after changes: Any DNS or provider change requires re-running the verification checklist (Section 10)
- Key rotation: If your email provider rotates DKIM keys, update the DNS record promptly
13. Notes / Warnings
Section titled “13. Notes / Warnings”- SPF and DKIM do not inherit from the root domain — every sending subdomain needs its own records
- Cloudflare-proxied (orange cloud) DNS records can interfere with email — set email-related records to DNS only (grey cloud)
p=noneDMARC provides zero protection and is treated as a red flag by Gmail and Outlook — always usep=quarantineor stronger for sending subdomains- Some email providers have sending limits on free tiers — verify limits before go-live
- Never store email API keys in client-side code — all email sending must happen server-side
14. Revision Control
Section titled “14. Revision Control”- Version: 1.0
- Editor: Wizard Tech Services
- Next Review: Within 90 Days