How I Would Fix emails landing in spam in a React Native and Expo AI-built SaaS app Using Launch Ready.
If your users are saying 'I never got the email' or 'it went to spam,' I treat that as a delivery problem first and a product trust problem second. In a...
How I Would Fix emails landing in spam in a React Native and Expo AI-built SaaS app Using Launch Ready
If your users are saying "I never got the email" or "it went to spam," I treat that as a delivery problem first and a product trust problem second. In a React Native and Expo SaaS app, the most likely root cause is usually bad sender authentication, weak domain reputation, or an email provider misconfiguration tied to an AI-built codebase that shipped without proper DNS and secrets setup.
The first thing I would inspect is the sending domain, the SMTP or email API account, and the DNS records for SPF, DKIM, and DMARC. If those are wrong or missing, everything else is noise.
Triage in the First Hour
1. Check the inbox placement symptoms.
- Ask which email types are affected: verification, magic link, password reset, onboarding, invoices.
- Confirm whether messages are landing in spam, promotions, or not arriving at all.
- Compare Gmail, Outlook, and iCloud because each filters differently.
2. Open the email provider dashboard.
- Review send logs for bounces, deferrals, complaints, and suppressions.
- Look for rate spikes, blocked recipients, or authentication failures.
- Check whether messages were accepted by the provider but rejected later by mailbox providers.
3. Inspect DNS for the sending domain.
- Verify SPF includes only approved senders.
- Confirm DKIM signing is enabled and aligned with the visible From domain.
- Check DMARC policy and reporting address.
4. Review app environment variables and secrets.
- Confirm API keys are set in production only.
- Make sure no test keys or staging sender domains are being used in live builds.
- Check if secrets were exposed in the Expo config or committed to git.
5. Inspect recent deployments.
- Identify whether the issue started after a release.
- Check if the sender name, reply-to address, or template changed.
- Review any new third-party scripts or backend changes that could affect email payloads.
6. Test one real message end to end.
- Send to a Gmail seed account and inspect headers.
- Confirm SPF pass, DKIM pass, DMARC pass.
- Verify links point to the correct production domain with SSL.
7. Check monitoring and alerting.
- Look for bounce rate above 2 percent or complaint rate above 0.1 percent.
- Confirm uptime monitoring is watching both app and email provider status pages.
## Quick checks I would run from my laptop dig TXT yourdomain.com dig TXT selector._domainkey.yourdomain.com dig TXT _dmarc.yourdomain.com
Root Causes
| Likely cause | What it looks like | How I confirm it | |---|---|---| | SPF is missing or too broad | Gmail marks messages as suspicious | DNS lookup shows no SPF record or multiple conflicting records | | DKIM is not enabled | Messages fail authentication even if sent successfully | Email headers show DKIM fail or no signature | | DMARC is absent | Mailbox providers have no policy signal | `_dmarc` record missing or set to `none` with no reporting review | | Shared sender reputation is poor | Everything works but lands in spam anyway | Provider dashboard shows high complaint rate or shared IP issues | | Bad content patterns | Spammy subject lines or broken HTML trigger filters | Seed tests show one provider accepting while another filters heavily | | Wrong production config in Expo app | App sends through staging API key or old domain | Build env vars point to non-production values |
The cyber security lens matters here because email delivery depends on identity trust. If your app cannot prove who it is sending from, mailbox providers treat it like a spoofing risk.
The Fix Plan
I would fix this in a controlled order so we do not create a bigger mess while trying to improve deliverability.
1. Lock down sender identity first.
- Use one sending domain for production only.
- Set SPF to include only your actual provider.
- Enable DKIM signing with 2048-bit keys if supported.
- Publish DMARC with at least `p=none` initially so we can collect reports without blocking legitimate mail.
2. Separate environments cleanly.
- Use different domains or subdomains for staging and production.
- Keep test emails off the customer-facing sender identity.
- Store all mail API keys in secure environment variables, not inside Expo client code.
3. Clean up message content.
- Remove aggressive subject lines like "Act now" or "Urgent."
- Add plain-text versions for every transactional email.
- Make sure links use your real HTTPS domain and not shortened URLs unless absolutely necessary.
4. Fix alignment across headers and templates.
- The visible From domain should match authenticated sending infrastructure as closely as possible.
- Reply-To should be valid and monitored by a real inbox.
- Avoid using random personal addresses from free providers for product mail.
5. Move transactional mail onto a reliable provider path.
- For SaaS apps I usually prefer a dedicated transactional service over DIY SMTP on day one.
- If volume is low, keep it simple and stable rather than over-engineering warmup flows too early.
6. Validate mobile app behavior separately from email delivery.
- In React Native and Expo, make sure deep links in emails open correctly on iOS and Android.
- Verify auth flows do not break when users return from their inbox to the app after clicking a link.
7. Add basic abuse controls.
- Rate limit resend endpoints so users cannot hammer your mail quota or hurt reputation.
- Log request IDs without logging full tokens or sensitive user data.
My preferred path is boring on purpose: authenticate the domain properly, isolate environments, then retest with seed accounts before touching anything else. That gets you back to inboxes without risking downtime or breaking onboarding.
Regression Tests Before Redeploy
I would not ship this fix until these checks pass:
1. Authentication tests
- SPF passes
- DKIM passes
- DMARC passes
- From domain matches production sender policy
2. Delivery tests
- Send 10 test emails across Gmail, Outlook, Yahoo, and iCloud
- At least 8 of 10 land in primary inboxes for transactional templates
- No hard bounces
3. App flow tests
- Password reset works end to end on iPhone and Android simulators
- Magic link opens the correct screen after app switch
- Verification emails do not expire too fast for normal users
4. Security checks
- No secrets exposed in Expo public config
- Production-only API keys are used server side - Resend endpoints require auth where appropriate - Rate limits block abusive retries
5. Content checks - Plain-text version exists - Links use HTTPS - Images are compressed if included - No broken HTML tags in templates
6. Acceptance criteria - Bounce rate stays under 2 percent during validation - Complaint rate stays under 0.1 percent - Inbox placement improves from spam to primary or updates where expected - Support tickets about missing emails drop by at least 80 percent within 7 days
Prevention
I would put guardrails around this so it does not regress after the next AI-generated release.
- Add deliverability monitoring.
Track bounce rate, complaint rate, open rate trends, and provider warnings weekly.
- Review DNS changes like code changes.
Any update to SPF, DKIM, DMARC, MX-related records should be checked before deployment.
- Keep secrets out of client bundles.
In Expo apps especially, assume anything shipped to the device can be inspected by users.
- Add code review checks for mail templates.
I look for sender identity changes, broken unsubscribe behavior where relevant, bad links, and accidental staging domains.
- Use observability on critical auth emails.
Alert if verification emails fail more than 3 times in 10 minutes or if resend volume spikes unexpectedly.
- Maintain separate seeds for QA testing.
I keep dedicated Gmail/Outlook seed accounts so we can spot filtering issues before customers do.
- Protect against abuse loops.
A buggy resend button can become an expensive support problem fast if it floods your provider and hurts reputation.
From a UX angle, I also make sure the app tells users what happened clearly when an email is delayed: "Check spam," "Resend in 60 seconds," "Change email address," and "Contact support." That reduces frustration while we fix delivery behind the scenes.
When to Use Launch Ready
Launch Ready fits when you need this fixed fast without turning it into a multi-week cleanup project.
I would recommend Launch Ready if:
- Your AI-built React Native plus Expo SaaS already works but email trust is broken,
- You need production deployment cleaned up at the same time,
- You suspect secrets are leaking into builds,
- You want monitoring added before another launch push,
- You need one senior engineer to own the handover checklist instead of guessing across five tools.
What you should prepare before booking:
- Domain registrar access,
- Cloudflare access if already connected,
- Email provider access,
- Git repo access,
- Expo build settings,
- Current prod and staging environment variables,
- A list of affected email types,
- Any screenshots of spam placement or bounce errors.
If you want me to handle it quickly and safely: https://cyprianaarons.xyz https://cal.com/cyprian-aarons/discovery
Delivery Map
References
- https://roadmap.sh/api-security-best-practices
- https://roadmap.sh/cyber-security
- https://roadmap.sh/qa
- https://www.rfc-editor.org/rfc/rfc7208
- https://support.google.com/a/answer/2466580?hl=en
---
Take the next step
If this is a problem in your product right now, here is what to do next:
- [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
- [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.
*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*
Cyprian Tinashe Aarons — Senior Full Stack & AI Engineer
Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.