Why are my emails going to spam even though your application successfully sent them? Because acceptance by an SMTP relay or email API is only the first step: Gmail, Yahoo, Outlook, Apple Mail, and corporate gateways still decide whether the recipient should see the message in the inbox, spam folder, another tab, or not at all.
Spam placement is not usually caused by one magic word or one failed setting. It is the result of many signals working together: domain authentication, IP and domain reputation, recipient engagement, complaint rates, bounce behavior, message structure, link safety, and consistency over time. The practical fix is to diagnose those signals in the right order instead of repeatedly rewriting subject lines and hoping for a different result.
First, distinguish sent, delivered, and inboxed
Developers often use “sent” to describe several different events. They are not the same.
A transactional email service can accept a message through a REST API or SMTP relay, queue it, and attempt delivery successfully. The receiving mail server can then accept it with an SMTP 250 response. Even after that, the recipient’s mailbox provider may classify the message as spam.
That creates four distinct stages:
- Submission: Your application hands a message to an API or SMTP server.
- Relay acceptance: Your email provider accepts it for processing.
- Mailbox delivery: The recipient server accepts the message, commonly with an SMTP
250 2.0.0-class success response. - Mailbox placement: The receiving provider puts it in the inbox, spam, a category tab, quarantine, or another filtered location.
An API success response proves submission, not inbox placement. Similarly, an SMTP response such as 250 2.0.0 Ok: queued means the next server accepted responsibility for the message; it does not mean a human will find it in the primary inbox.
When investigating, collect evidence for every stage. Save the message ID returned by your provider, the recipient domain, the exact sending domain, timestamps, SMTP or webhook events, bounce text, and a copy of the final received message headers. Without headers, you are largely guessing.
How spam filters make their decision
Modern spam filtering is a reputation and risk system, not a static word blacklist. A mailbox provider asks questions such as:
- Is this domain authorized to send mail using this identity?
- Does the message authenticate and align with the visible
From:domain? - Has this domain or IP recently sent mail that people mark as spam?
- Do recipients read, reply to, move, delete, or ignore these messages?
- Is the volume and cadence consistent with the sender’s history?
- Does the content resemble phishing, bulk promotion, impersonation, or malware delivery?
- Are URLs, attachments, and redirect domains trustworthy?
- Does the recipient have a history with this sender?
No single provider publishes its full scoring model, and the result can vary by recipient. A password-reset message may reach the inbox for a long-time customer while the same message lands in spam for a brand-new recipient who has never interacted with your domain.
This is why a small test using only employee inboxes can be misleading. Your team may have previously opened, replied to, and moved messages from your domain, creating positive recipient-level signals that a new customer does not have.
Transactional mail is not automatically exempt
Order receipts, login links, verification codes, invoices, alerts, and password resets are usually expected mail. That helps, but it does not make them immune to filtering.
A transactional message can still go to spam if it comes from an unauthenticated domain, contains a suspicious URL, is sent to stale or mistyped addresses, uses a misleading display name, has broken HTML, or originates from a domain with a poor reputation. A legitimate receipt sent from updates@example.com does not receive special treatment merely because your application labels it “transactional.”
Start with the message headers, not the template
The fastest way to understand a spam placement issue is to open a delivered message and inspect its full headers. Gmail exposes this through “Show original”; other mailbox providers offer similar options such as “View message source” or “View headers.”
Look for these fields and results:
Authentication-Results:— the receiving provider’s evaluation of SPF, DKIM, DMARC, and sometimes ARC.Return-Path:— the envelope sender used for SMTP bounces and SPF evaluation.From:— the visible author address the recipient sees.DKIM-Signature:— the domain and selector used to cryptographically sign the message.Received:— the path and timestamps of the message through mail servers.Message-ID:— a message identifier, useful when correlating application logs and provider events.List-Unsubscribe:andList-Unsubscribe-Post:— expected for bulk or promotional mail and useful for mailbox-provider handling.
A healthy simplified result may look like this:
Authentication-Results: mx.google.com;
spf=pass smtp.mailfrom=bounces.example.com;
dkim=pass header.d=example.com header.s=s1;
dmarc=pass header.from=example.com
A problematic message may instead show:
Authentication-Results: mx.google.com;
spf=fail smtp.mailfrom=mailer.other-domain.net;
dkim=none;
dmarc=fail header.from=example.com
The second example does not prove that spam placement is inevitable, but it is an urgent configuration failure. Fix authentication before tuning content, cadence, or HTML.
Headers also reveal hidden identity mismatches. For example, your visible address may be support@example.com, while the envelope sender is bounce@vendor-mail.net and the DKIM signer is vendor-mail.net. That arrangement can work if DKIM or SPF is properly aligned for DMARC, but it should be deliberate and verified rather than assumed.
Fix SPF, DKIM, and DMARC before anything else
Authentication is table stakes. It tells receiving systems that the infrastructure sending a message is authorized to use your domain and that the message has not been altered in transit.
For high-volume senders, major mailbox providers require stronger authentication practices. Even below a formal bulk-sender threshold, properly configured SPF, DKIM, and DMARC materially improve trust, make spoofing harder, and make troubleshooting possible.
SPF: authorize the envelope sender
SPF, or Sender Policy Framework, is published as a DNS TXT record. It authorizes servers to send mail for the envelope sender domain, which is normally visible through Return-Path: rather than the human-facing From: address.
A basic SPF record for a domain that sends only through one approved provider might look like this:
example.com. IN TXT "v=spf1 include:spf.email-provider.example -all"
The exact include: value must come from your email provider’s documentation. Do not copy a provider-specific include mechanism from a blog post unless it belongs to the service actually sending your mail.
If your domain also sends mail from a separate system, such as Google Workspace or Microsoft 365, you must combine all authorized sources into one SPF record:
example.com. IN TXT "v=spf1 include:_spf.google.com include:spf.email-provider.example -all"
Publishing two SPF TXT records starting with v=spf1 is invalid. Receivers can return an SPF permanent error rather than combining them.
Also keep an eye on SPF’s DNS lookup limit. Mechanisms such as include, a, mx, exists, redirect, and ptr can trigger lookups, and SPF evaluation is limited to 10 DNS-triggering lookups. Nested includes can make a short-looking SPF record exceed the limit. The result is commonly spf=permerror, which can undermine DMARC if SPF is your only aligned authentication path.
Use -all only when you are confident every legitimate sender is included. During a migration, ~all may be a temporary diagnostic choice, but it is not a substitute for identifying and authorizing your actual senders.
DKIM: sign the message with your domain
DKIM, or DomainKeys Identified Mail, adds a cryptographic signature to each message. The receiving provider retrieves a public key from DNS and verifies that signed portions of the message have not changed.
A DKIM DNS record is typically a TXT record under a selector, such as:
s1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
In practice, your sending platform generates the selector and public key. Your job is to publish the provided record exactly, wait for DNS propagation, and confirm that actual messages contain a matching DKIM-Signature with a passing result.
The important identity field is d= in the message signature. For example:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s1; ...
A DKIM pass for d=example.com is often more useful for DMARC than a pass for an unrelated provider domain because it can align with the address in your visible From: header.
DKIM can fail after a message leaves your provider. Mailing lists, gateways, footer injection, security tools, and some forwarding systems may alter signed headers or body content. If you run a system that modifies outbound messages after signing, test the final message rather than only the message your application generated.
DMARC: require alignment and get visibility
DMARC connects the visible From: domain to SPF and DKIM. It passes when either SPF passes and aligns with the From: domain, or DKIM passes and aligns with the From: domain.
A practical monitoring record is:
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; adkim=r; aspf=r; pct=100"
The important pieces are:
v=DMARC1identifies the record.p=noneasks receivers to monitor rather than quarantine or reject failing mail.rua=specifies an address for aggregate reports.adkim=randaspf=ruse relaxed alignment.pct=100applies the stated policy to all applicable mail.
After reviewing reports and confirming every legitimate sender authenticates correctly, a stricter policy may be appropriate:
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; adkim=r; aspf=r; pct=100"
Or, once your inventory is complete:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; adkim=r; aspf=r; pct=100"
Do not jump to p=reject before you know every service that sends as your domain. That inventory can include your application’s transactional relay, support desk, CRM, billing platform, recruiting software, product analytics service, and employees’ mailbox provider.
Alignment is the common missing detail
Consider this message:
From: Acme Support <support@example.com>
Return-Path: <bounce@provider-mail.example>
DKIM-Signature: d=provider-mail.example; s=default;
SPF might pass for provider-mail.example, and DKIM might pass for provider-mail.example, but DMARC can still fail because neither authenticated domain aligns with example.com in the visible From: address.
The usual solution is to configure custom sending domains so the provider signs as your domain or an aligned subdomain, and uses an aligned envelope sender such as bounces.example.com. This is one reason a dedicated sending domain is safer than using a provider’s shared default identity.
Reputation: the reason correct DNS may still not be enough
A fully authenticated email can still go to spam. Authentication establishes identity; reputation helps decide whether that identity is trustworthy.
Mailbox providers develop reputation at several levels:
- Domain reputation: the history of mail using your domain and subdomains.
- IP reputation: the history of the sending IP address.
- Recipient-level reputation: whether an individual recipient has engaged with your messages.
- URL and linked-domain reputation: whether destinations in the message are associated with risk or abuse.
- Campaign or stream reputation: the behavior of a particular class of mail, such as receipts versus promotions.
A new domain has little or no history. A domain that was recently used for cold outreach, a compromised account, purchased contacts, or repeated bounces may have negative history. In both cases, sending a sudden large volume can look risky.
Separate transactional and promotional mail
If possible, separate mail streams at the domain or subdomain level. For example:
notify.example.comfor product alerts and account notificationsreceipts.example.comfor billing and order receiptsnews.example.comfor newsletters and product announcements
The visible From: address can use those subdomains or an aligned parent-domain strategy, depending on your brand and authentication design. The goal is not to hide promotional mail. It is to prevent weak engagement on a newsletter stream from contaminating critical password resets and receipts.
Separation also gives you clearer operational data. If only promotional messages are seeing complaints, you can change segmentation and frequency without changing the infrastructure for all product mail.
Warm up by behaving predictably
“Warm-up” is often misunderstood as a trick for manufacturing reputation. It is better understood as controlled growth that lets mailbox providers observe a stable, wanted sending pattern.
For a new sending domain or IP:
- Start with people who recently signed up, purchased, requested a message, or otherwise expect it.
- Increase volume gradually as positive engagement and low complaint rates continue.
- Avoid sudden spikes caused by importing an old list or retrying a backlog all at once.
- Keep the sender identity, sending domain, and content type consistent.
- Stop and investigate if bounces, complaints, deferrals, or spam placement rise.
For transactional applications, volume can be unpredictable. You may not be able to warm a password-reset stream in a traditional way. In that case, focus on clean authentication, consistent production behavior, verified users, and strict protection against abuse in signup, invite, and contact forms.
Bad addresses, complaints, and low engagement damage deliverability
Your recipient list is part of your sending reputation. Sending technically valid mail to people who do not want it is still spam behavior from a mailbox provider’s perspective.
Hard bounces are a particularly strong signal. Examples include addresses that do not exist, domains with no mailbox, or recipients that have been disabled. Repeatedly sending to them tells providers that your list is stale or poorly collected.
Treat these SMTP responses seriously:
550 5.1.1commonly indicates an unknown or nonexistent mailbox.550 5.1.10or similar enhanced codes can indicate a recipient rejection, though the exact wording varies by provider.554 5.7.1commonly signals a policy, reputation, authentication, or content-related rejection.421 4.7.0commonly indicates a temporary deferral due to policy, rate, reputation, or suspicious traffic.451 4.7.1is another temporary policy-related deferral often worth retrying with backoff.
The leading digit matters: 4xx responses are temporary failures and may be retried carefully; 5xx responses are permanent failures for that attempt and should generally not be retried blindly. Always store the full SMTP diagnostic text because the human-readable portion often identifies the actual issue.
Build suppression into your application
At a minimum, maintain a suppression list for:
- Permanent hard bounces
- Spam complaints reported through your provider’s feedback mechanisms
- Unsubscribes and opt-outs
- Addresses that repeatedly soft bounce over a defined period
- Recipients your support team has identified as incorrect or unwanted
Do not simply delete a user record when an address bounces if that would break account recovery or auditing. Instead, mark the address as undeliverable and block nonessential sends until the user updates it.
Before sending invitations, newsletters, onboarding drips, or imported contacts, consider validating addresses. A free address verification tool can help catch obvious formatting and deliverability risks before a bad list becomes a reputation problem. Verification is not permission, however: a deliverable address may still belong to someone who never asked for your message.
Complaints carry more weight than opens
Open tracking is increasingly unreliable because privacy features and image proxying can generate or obscure opens. Complaints, unsubscribes, bounce rates, replies, purchases, login activity, and direct user feedback are more actionable signals.
If users mark your messages as spam, do not interpret that only as a content issue. It may mean your signup flow did not set expectations, a double opt-in was missing, messages are too frequent, the message is not recognizable, or a transactional event is actually being used to deliver marketing content.
Content and HTML can trigger filtering, but “spam words” are not the main issue
Content matters, but simplistic keyword lists are a poor diagnosis. A spam filter does not automatically reject a message because it includes “free,” “urgent,” or an exclamation mark. It evaluates combinations of content, structure, sender history, URLs, recipient behavior, and impersonation risk.
Content problems that genuinely matter include:
- A misleading display name or
From:address - Subject lines that promise something the body does not deliver
- An image-only email with little meaningful text
- Broken HTML, malformed MIME boundaries, or invalid character encoding
- A large mismatch between plain-text and HTML parts
- Excessive tracking redirects or links to unrelated domains
- URL shorteners or newly created redirect domains
- Attachments that recipients do not expect
- Login links that point to a different domain without explanation
- Brand names and visual styling that resemble another organization
Send multipart messages
Provide both a plain-text and an HTML version. The plain-text part is useful for accessibility, text-only clients, security tools, and filtering systems that want to compare a message’s visible claims with its HTML rendering.
A basic MIME structure should include appropriate Content-Type headers and a clean multipart alternative. Your email library or provider normally creates this for you, but test the actual received source after template changes.
Do not hide large blocks of text with CSS, use tiny invisible text, stuff keywords into comments, or include fake reply chains. These are old evasion tactics and are more likely to create distrust than improve placement.
Make links predictable and branded
A password-reset email is inherently sensitive because it asks a user to click a link. Reduce risk by making the destination obvious.
Prefer a URL such as:
https://app.example.com/reset-password?token=...
over a vague short link or a redirect through an unrelated domain. If your provider uses a tracking domain, configure a branded custom tracking domain when appropriate and confirm it is correctly authenticated and maintained.
Avoid putting credentials, personal data, or long-lived secrets in query strings. Use single-purpose, short-lived tokens and explain why the recipient received the message. That is good application security and improves the message’s legitimacy to users.
Sending behavior matters as much as message quality
Mailbox providers learn from patterns. A sudden volume jump, repeated sends to the same recipient, inconsistent sender identities, or a burst of nearly identical mail can trigger throttling or spam placement even when the content is valid.
Avoid accidental email storms
Common application bugs include:
- A queue retrying a message after the provider already accepted it
- A webhook loop that sends a notification for its own notification
- A cron job processing the same database rows repeatedly
- A failed idempotency implementation during deployment retries
- A bulk operation using production addresses during testing
- A sign-up endpoint abused to send invitations or verification mail to arbitrary recipients
Use idempotency keys or durable event identifiers around critical sends. Store a delivery intent before submission, record the provider message ID after submission, and make workers safe to retry without producing duplicates.
For example, an order confirmation should be keyed to an immutable order event. If the job runs twice, the second run should discover that the confirmation has already been submitted rather than send another copy.
Respect rate limits and deferrals
A 421 or 451 response is not an instruction to retry immediately in a tight loop. Repeated rapid retries amplify the behavior that caused the deferral.
Use exponential backoff with jitter. Separate temporary failures from hard bounces, cap retry duration, and monitor the recipient domain producing the deferrals. If a major provider begins deferring a significant share of your traffic, reduce volume and inspect authentication, recipient quality, and complaint signals before resuming normal throughput.
Test deliverability with controlled diagnostics
A good test plan uses multiple mailbox providers and real headers. Do not rely on one inbox or one test service.
Start with a small seed list containing accounts at Gmail, Yahoo, Outlook.com, iCloud, and a business mailbox if your customers use Microsoft 365 or Google Workspace. Send representative messages: a password reset, receipt, verification email, alert, and any promotional template you operate.
Then inspect authentication and placement at each destination. Differences are useful evidence. If Gmail accepts the message into the inbox while Outlook places it in junk, that suggests provider-specific reputation or policy behavior rather than a universal template failure.
Useful diagnostic tools include:
- mail-tester.com for a quick content, authentication, and structural review using a generated test address.
- MXToolbox for DNS lookups, SPF, DKIM, DMARC, MX, and blacklist-oriented checks.
- Google Postmaster Tools for eligible Gmail senders who need domain reputation, spam-rate, and authentication visibility.
- DMARC aggregate reports for discovering all services that send mail using your domain.
- Command-line DNS tools such as
digandnslookupfor checking what the public internet actually sees.
For example:
dig TXT example.com +short
dig TXT _dmarc.example.com +short
dig TXT s1._domainkey.example.com +short
A DNS control panel may show a record as saved while resolvers still return an old value because of TTLs, a wrong hostname, an accidental duplicate record, or an edit in the wrong DNS zone. Querying public DNS is more reliable than trusting a dashboard confirmation.
If you send through a REST API or SMTP relay, use your provider’s logs and event webhooks to connect an application event to the final outcome. Review the email API setup guides and reference for the exact sending, event, and authentication behavior of the platform you use rather than assuming every provider exposes the same fields or event names.
A practical troubleshooting order
When mail starts landing in spam, do not change ten things at once. That makes it impossible to identify the cause. Work through a controlled sequence.
- Confirm scope. Is the issue one recipient, one mailbox provider, one template, one sending domain, or all mail?
- Capture headers. Compare a spammed message with an inboxed message from the same stream.
- Verify authentication. Check SPF, DKIM, DMARC, and alignment from the recipient’s
Authentication-Resultsheader. - Check DNS externally. Query your public TXT records and confirm there is one valid SPF record and one DMARC record at the correct hostname.
- Review sender identity. Compare
From:,Return-Path:, DKIMd=, tracking domain, and visible links. - Inspect bounces and deferrals. Group SMTP errors by recipient provider and full diagnostic text.
- Audit recipient quality. Remove hard bounces, honor suppressions, pause questionable imports, and investigate complaint sources.
- Review volume changes. Look for deployment-related spikes, retry loops, new campaigns, or newly enabled automations.
- Test the exact production message. Send the same headers, URLs, and template—not a simplified local test—to multiple seed inboxes.
- Change one variable and measure. Authentication changes, identity changes, and list-cleaning actions may take time to affect placement; avoid declaring success from a single test.
This order works because it starts with objective technical faults before moving into reputation and behavior, which are more probabilistic and slower to recover.
When the root cause is outside your application
Some spam placement is not directly caused by your code. Shared sending infrastructure can have an IP-level reputation event. A recipient’s corporate gateway may quarantine mail because of its own policies. A user may have created a filter, blocked the sender, or repeatedly marked previous messages as spam.
That does not mean there is nothing to do. Verify whether the issue is isolated or systemic. If only one recipient company is affected, ask for the full rejection or quarantine reason from its mail administrator. If multiple providers show the same failure, focus on your authentication, domain reputation, recipient acquisition, and message stream.
If you use shared IP infrastructure, your provider should manage baseline IP reputation, abuse prevention, reverse DNS, and delivery routing. You are still responsible for your domain’s authentication, the quality of addresses you send to, the legitimacy of your application traffic, and the sending behavior your software creates.
For high-volume or highly regulated mail, build deliverability into operations rather than treating it as a one-time DNS task. Assign ownership, review metrics regularly, keep an inventory of every vendor allowed to send as your domain, and test changes before large sends.
Conclusion: inbox placement is earned continuously
The answer to “why are my emails going to spam” is rarely a single word in the subject line. Most problems trace back to one of four areas: missing or misaligned authentication, weak or damaged reputation, poor recipient quality, or unexpected sending behavior.
Start with headers and DNS. Make sure SPF, DKIM, and DMARC pass with alignment for the visible From: domain. Then protect reputation by separating streams, suppressing bad addresses, sending only expected mail, avoiding duplicate bursts, and monitoring bounces, complaints, deferrals, and engagement trends.
A reliable email system treats delivery as an observable pipeline. Your application should know what it attempted to send, your provider should report what happened during delivery, and your team should be able to explain why a message was accepted, deferred, bounced, inboxed, or classified as spam.
FAQ
Why do my emails go to spam even when SPF and DKIM pass?
SPF and DKIM passing prove authorization and message integrity, but they do not guarantee a positive reputation. Spam placement can still result from DMARC misalignment, poor recipient engagement, complaint history, a sudden volume spike, suspicious links, low-quality addresses, or weak domain reputation.
Does a 250 SMTP response mean the email reached the inbox?
No. A 250 response generally means the receiving SMTP server accepted the message. The mailbox provider can still place it in spam, another category, quarantine, or apply recipient-specific filtering after acceptance.
How long does it take to recover from spam placement?
There is no fixed timeline. DNS fixes can become visible after propagation, but reputation recovery depends on sustained good sending behavior: authenticated mail, low complaints, low bounces, predictable volume, and positive recipient interaction. Recovery often requires days or weeks of consistent evidence rather than one corrected campaign.
Should transactional and marketing emails use different domains?
Separating them by subdomain or sending stream is often a good practice because their engagement and complaint patterns differ. It helps protect critical mail such as receipts and password resets from reputation problems caused by lower-engagement promotional traffic.
Can email verification guarantee inbox placement?
No. Verification can reduce obvious address errors and hard-bounce risk, but it cannot prove consent, recipient interest, reputation, or inbox placement. Use it as one part of list hygiene alongside clear opt-in, suppression handling, and careful sending practices.