Prices increase in 00D : 00H : 00M Upgrade now Pay less later.

Blog / Email Marketing

Reduce Email Bounce Rate: The Developer's Guide to List Cleaning APIs

Reduce Email Bounce Rate: The Developer's Guide to List Cleaning APIs

Most email marketers obsess over open rates, click-through rates, and conversion metrics. They A/B test subject lines, optimize send times, and agonize over copy. Meanwhile, a single number quietly undermines every campaign they run — and they often don't notice until the damage is already done.

That number is 2%.

Gmail has drawn a hard line in the sand: sustain a bounce rate above 2%, and your sending reputation enters a spiral that can take months to recover from. This isn't a guideline or a best practice. It's a threshold enforced algorithmically, and crossing it triggers consequences that compound over time in ways that aren't immediately obvious when you're staring at your campaign dashboard.

This post breaks down exactly what happens when your bounce rate climbs past that threshold, how inbox providers track and penalize you over rolling time windows, and what you can do — right now — to diagnose your list health, verify your addresses before they cause damage, and build a monitoring system that catches problems before they spiral.


Why Gmail's 2% Threshold Is a Hard Limit, Not a Suggestion

In February 2024, Google formalized what had long been an informal industry standard: senders must keep their spam rate below 0.10% and their bounce rate — specifically hard bounces — below 2% to maintain reliable inbox placement. These requirements apply to anyone sending more than 5,000 messages per day to Gmail addresses, but the underlying reputation mechanics affect all senders regardless of volume.

The reason Gmail treats 2% as a hard threshold comes down to signal quality. Every bounce is a data point telling inbox providers something about how you acquired your list, how well you maintain it, and whether you're the kind of sender who cares about recipient experience. A handful of bounces is noise. Sustained bounces above 2% are a pattern — and inbox providers are exceptionally good at distinguishing patterns from noise.

What makes this particularly dangerous is the lag between cause and consequence. You don't send to 10,000 addresses, get 200 bounces, and immediately see your inbox placement collapse. Instead, reputation damage accumulates silently across rolling 30-day and 90-day windows. By the time your open rates start dropping noticeably, you may already be several weeks into a reputation hole that takes just as long to climb out of.

Industry deliverability benchmarks generally show a sharp gap in inbox placement between senders who stay under the 2% threshold and those who don't — often a difference of 20-30 percentage points or more.


The Math: What 200 Bounces Actually Cost You

Let's make this concrete. You have a list of 10,000 email addresses. You send a campaign, and 2% of those addresses bounce — that's 200 bounced messages. On the surface, 200 sounds manageable. You still reached 9,800 people. What's the big deal?

The big deal is what those 200 bounces signal to inbox providers, and how that signal compounds over time.

Month 1: Your bounce rate sits at 2.0%. Gmail's Postmaster Tools shows your domain reputation dropping from "High" to "Medium." Inbox placement dips noticeably. You attribute it to seasonal variation.

Month 2: You send again without cleaning your list. The same bad addresses bounce again, plus any new ones that have gone stale. Your rolling 30-day bounce rate stays above 2%. Domain reputation moves from "Medium" to "Low."

Month 3: Gmail begins routing a meaningful portion of your messages to spam folders. You're now in a feedback loop: lower inbox placement means fewer opens, which further signals to Gmail that recipients don't want your mail.

Month 4-6: Without intervention, you're in a full reputation crisis. Some receiving servers begin blocking your IP or domain outright.

This trajectory reflects a pattern deliverability practitioners see consistently: senders who clean their list and implement verification promptly after crossing the threshold recover meaningfully faster than those who don't act.

The math on the business impact is straightforward. If your list generates $50 per 1,000 emails sent (a conservative revenue-per-send figure for many e-commerce businesses), dropping from 95% to 60% inbox placement on a 10,000-address list costs you:

  • At 95% placement: 9,500 delivered × $0.05 = $475 per campaign
  • At 60% placement: 6,000 delivered × $0.05 = $300 per campaign
  • Loss per campaign: $175

And that calculation doesn't account for the compounding effect of damaged sender reputation on future campaigns, the cost of re-engagement, or the revenue lost from subscribers trained not to see your emails anymore.


Hard Bounces vs. Soft Bounces: Different Damage, Same Destination

Not all bounces are created equal, but both types inflict real damage on your deliverability — just through different mechanisms.

Hard Bounces

A hard bounce indicates a permanent delivery failure. The address doesn't exist, the domain doesn't accept mail, or the recipient has explicitly blocked your sender address. Hard bounces are the primary driver of reputation damage because they're the clearest signal that you're sending to addresses you shouldn't have.

Common causes of hard bounces: - Addresses that were never valid (typos, fake signups) - Addresses that have been abandoned and deactivated - Domains that no longer exist or have stopped hosting email - Role accounts that have been removed (e.g., info@company.com after a business closes)

The critical thing to understand about hard bounces is that they should never happen more than once per address. If you send to a hard-bounced address a second time, you're sending a clear signal to inbox providers that you don't maintain suppression lists.

Soft Bounces

Soft bounces indicate a temporary delivery failure — the mailbox is full, the receiving server is temporarily unavailable, or the message was too large. In isolation, a single soft bounce is benign. The damage comes from retry behavior.

Most email service providers automatically retry soft-bounced messages on a schedule. If you're retrying delivery to addresses that consistently soft-bounce, you're generating a sustained stream of failed delivery attempts that inbox providers interpret as poor list hygiene.

Best practice: After 3 consecutive soft bounces over a 30-day period, suppress the address and treat it as a hard bounce for list management purposes. Disposable addresses often follow this exact pattern — soft-bouncing repeatedly before finally hard-bouncing when the temporary domain expires.


How Gmail and Microsoft 365 Track Reputation Over Rolling Windows

Gmail's Reputation Model

Gmail evaluates sender reputation across multiple dimensions simultaneously: IP reputation, domain reputation, and brand reputation (the "From" name and address pattern). Each is evaluated over rolling time windows — commonly cited as roughly 30 days for most signals and up to 90 days for more significant reputation events.

Gmail's Postmaster Tools reputation tiers — High, Medium, Low, and Bad — correspond roughly to different inbox placement bands, with "Bad" carrying meaningful blocking risk.

Microsoft 365 / Outlook's Reputation Model

Microsoft uses a similar rolling-window approach. Microsoft's Smart Network Data Services (SNDS) evaluates IP reputation, while their broader filtering system also incorporates domain-level signals through their Junk Email Reporting Program (JMRP).

Key difference: Microsoft places significant weight on the ratio of bounces to successful deliveries on a per-IP basis. If you're sending from a shared IP (common with many ESPs), your bounce rate contributes to the IP's overall reputation — which affects all other senders on that IP. This is one of the strongest arguments for dedicated IPs at scale.


Step-by-Step: Diagnose, Verify, and Monitor Your List Health

Step 1: Diagnose Your Current Bounce Rate

Check these sources: - Your ESP's bounce report (broken down by hard and soft) - Gmail Postmaster Tools (free, shows domain reputation and spam rate) - Microsoft SNDS (free registration, shows IP-level reputation) - Your email authentication records (SPF, DKIM, DMARC) — authentication failures can masquerade as bounces

Warning signs your bounce rate is worse than your ESP reports: - Open rates declining without a change in content or send frequency - Gmail Postmaster Tools showing "Medium" or "Low" domain reputation - Increasing spam complaint rates - Replies from recipients saying they "never got" your emails

Step 2: Segment Your List by Risk

Segment by engagement recency, acquisition source, and age. Addresses that haven't engaged in 12+ months are significantly more likely to have gone stale — abandoned, deactivated, or converted to spam traps.

Step 3: Verify Your List with MailValid

MailValid's API checks each address against multiple validation layers — syntax, domain existence, MX records, and mailbox-level verification — to identify addresses that will bounce before you send to them.

  • Verify any list that hasn't been sent to in 90+ days
  • Verify all new subscribers within 24 hours of signup (real-time verification)
  • Re-verify your full list quarterly if you send at high volume
  • Always verify purchased or third-party lists before any send

Step 4: Implement Suppression and Monitoring

  • Add every hard bounce to your suppression list immediately and automatically
  • After 3 consecutive soft bounces in 30 days, add to suppression
  • Never remove addresses from your suppression list without re-verification
  • Check Gmail Postmaster Tools weekly
  • Track your rolling 30-day bounce rate, not just per-campaign bounce rate

Step 5: Implement Real-Time Verification at the Point of Capture

The most cost-effective place to stop bad addresses is before they ever enter your list. Integrating MailValid's API at your signup forms catches typos, fake addresses, and disposable domains at the moment of capture — before they have any chance to damage your reputation.


Verify Your List with MailValid's API

The following example shows the actual documented request and response for a single verification, plus a bulk-cleaning script using the real fields.

import requests
import csv
import time

MAILVALID_API_KEY = "your_api_key_here"

def verify_single_email(email: str, api_key: str, timeout: int = 10) -> dict:
    """
    Verify a single email using MailValid's documented API.
    Returns the full 'result' object from the response.
    """
    headers = {"X-API-Key": api_key, "Content-Type": "application/json"}
    try:
        response = requests.post(
            "https://mailvalid.io/api/v1/verify/single",
            headers=headers,
            json={"email": email},
            timeout=timeout
        )
        response.raise_for_status()
        return response.json()["result"]
    except requests.exceptions.RequestException as e:
        return {"email": email, "error": str(e), "is_valid": False}


def verify_list_from_csv(input_file: str, output_file: str, api_key: str = MAILVALID_API_KEY,
                          rate_limit_delay: float = 0.1) -> dict:
    """
    Verify a CSV list of addresses. For lists over a few thousand rows,
    prefer the bulk endpoint (POST /api/v1/verify/bulk, up to 10,000
    emails per request, async) instead of looping single calls like this.
    """
    summary = {"total": 0, "valid": 0, "invalid": 0, "catch_all": 0, "disposable": 0}

    with open(input_file, "r") as infile, open(output_file, "w", newline="") as outfile:
        reader = csv.DictReader(infile)
        fieldnames = reader.fieldnames + ["status", "status_reason", "confidence_score"]
        writer = csv.DictWriter(outfile, fieldnames=fieldnames)
        writer.writeheader()

        for row in reader:
            summary["total"] += 1
            result = verify_single_email(row["email"], api_key)

            row["status"] = result.get("status", "error")
            row["status_reason"] = result.get("status_reason", "")
            row["confidence_score"] = result.get("confidence_score", "")

            if result.get("is_valid"):
                summary["valid"] += 1
            elif result.get("status") == "catch_all":
                summary["catch_all"] += 1
            else:
                summary["invalid"] += 1
            if result.get("is_disposable"):
                summary["disposable"] += 1

            writer.writerow(row)
            time.sleep(rate_limit_delay)

    projected_bounce_rate = round((summary["invalid"] / summary["total"]) * 100, 2) if summary["total"] else 0
    print(f"Total: {summary['total']} | Valid: {summary['valid']} | Invalid: {summary['invalid']} | Catch-all: {summary['catch_all']} | Disposable: {summary['disposable']}")
    print(f"Projected bounce rate if sent unverified: {projected_bounce_rate}%")
    return summary


if __name__ == "__main__":
    verify_list_from_csv("raw_list.csv", "verified_list.csv")

Start Verifying Emails with MailValid

Everything in this guide is built into MailValid's email verification API:

  • 95%+ accuracy with syntax, MX, and SMTP validation
  • Under 500ms average response time for real-time checks
  • From $0.0006 to $0.0015 per email depending on plan tier
  • Credits never expire — pay once, use whenever
  • 100 free credits to start — no credit card required
import requests

response = requests.post(
    "https://mailvalid.io/api/v1/verify/single",
    headers={"X-API-Key": "mv_live_your_key", "Content-Type": "application/json"},
    json={"email": "user@example.com"}
)
print(response.json())

→ Start free with 100 credits at mailvalid.io

Last Updated - 21 September 2026

M

MailValid Team

Email verification experts

Share:

Join teams that verify before they send

Stop letting bad emails hurt your deliverability

100 free credits. From $0.0008/email after. Credits never expire. No credit card required.

More from MailValid

Verify 100 emails free Start Free