Deliverability13 min read

Sender Reputation Monitoring: How to Track and Recover from Deliverability Issues

Stop waiting for deliverability to break. Use Gmail Postmaster Tools, SNDS, bounce tracking, engagement monitoring, and automated alerts to catch reputation issues before they become crises.

R

React Emails Pro

March 2, 2026

Your sender reputation is invisible until it breaks. Then password resets land in spam, activation emails vanish, and support tickets flood in asking "where's my email?"

Most teams only check deliverability after it's already damaged. By then, you're fighting an uphill battle: Gmail has flagged your domain, Outlook is throttling your sends, and you're burning through engaged users trying to recover.

Sender reputation doesn't break overnight—it erodes. Catch it early with the right monitoring, and you can fix issues before they become incidents.

The three reputation signals that actually matter

Sender reputation isn't one number. It's a composite score based on three core signals that Gmail, Outlook, and Yahoo track independently:

  • Engagement rate — Opens, clicks, replies vs. deletes without reading
  • Complaint rate — Spam reports and unsubscribes
  • Technical hygiene — Bounce rate, authentication alignment, sending patterns

Each provider weighs these differently. Gmail prioritizes engagement. Outlook is stricter on complaints. Yahoo penalizes inconsistent sending patterns. You need to monitor all three.


Free monitoring tools you should set up today

You don't need expensive third-party tools to catch reputation issues early. These free provider tools give you 90% of what you need:

Gmail Postmaster Tools (critical)

Google's free dashboard shows your domain and IP reputation, spam rate, authentication status, and encryption compliance—directly from Gmail's internal scoring.

Terminal
# Setup steps:
1. Go to https://postmaster.google.com
2. Add your sending domain (e.g., notifications.yoursaas.com)
3. Add the verification TXT record to DNS
4. Wait 24-48h for data to populate

# What to monitor weekly:
- Domain reputation (keep it "High")
- IP reputation (should match domain)
- Spam rate (keep below 0.10%)
- Feedback loop complaints
Set up Gmail Postmaster before you have a problem. It only shows historical data, so if you wait until deliverability tanks, you'll have no baseline to compare against.

Microsoft SNDS (Outlook/Hotmail)

Microsoft's Smart Network Data Services tracks your IP reputation for Outlook.com and Hotmail. Shows message quality, trap hits, and complaint rates.

Terminal
# Setup:
1. Visit https://sendersupport.olc.protection.outlook.com/snds/
2. Register your sending IP addresses
3. Review color-coded reputation data

# Color codes:
- Green: Good standing (ship it)
- Yellow: Caution (investigate spike in complaints)
- Red: Poor reputation (immediate action required)
- No data: Not enough volume (increase sends or wait)

Feedback loops (FBLs)

Feedback loops let ESPs notify you when users mark your emails as spam. Most transactional providers (Resend, Postmark, SendGrid) automatically handle FBL registration and suppress complainers.

If you're sending via your own SMTP server, register manually:

  • AOL/Yahoo: https://senders.yahooinc.com/complaint-feedback-loop/
  • Outlook.com: Uses JMRP (Junk Mail Reporting Program) via SNDS
  • Gmail: No public FBL; use Postmaster Tools instead

The five metrics to track weekly

Raw dashboards don't help unless you know what to look for. Track these five metrics weekly (or daily during high-volume periods):

1. Bounce rate (hard + soft)

Target: Below 2% total, below 1% hard bounces

Hard bounces (permanent failures) directly hurt sender reputation. Soft bounces (temporary issues) are less harmful but can signal list hygiene problems if they're chronic.

lib/monitoring/bounce-tracker.ts
import { db } from "@/lib/db";

export async function trackBounceRate(period: "day" | "week" | "month") {
  const stats = await db.emailLog.aggregate({
    where: {
      sentAt: { gte: getPeriodStart(period) },
    },
    _count: {
      id: true,
      bounced: { where: { bounced: true } },
      hardBounce: { where: { bounceType: "hard" } },
    },
  });

  const total = stats._count.id;
  const bounced = stats._count.bounced;
  const hardBounced = stats._count.hardBounce;

  const bounceRate = (bounced / total) * 100;
  const hardBounceRate = (hardBounced / total) * 100;

  // Alert if thresholds exceeded
  if (bounceRate > 2.0) {
    await alertSlack({
      message: `⚠️ Bounce rate spike: ${bounceRate.toFixed(2)}%`,
      channel: "#deliverability-alerts",
    });
  }

  return { total, bounced, hardBounced, bounceRate, hardBounceRate };
}

function getPeriodStart(period: "day" | "week" | "month"): Date {
  const now = new Date();
  switch (period) {
    case "day":
      return new Date(now.setHours(0, 0, 0, 0));
    case "week":
      return new Date(now.setDate(now.getDate() - 7));
    case "month":
      return new Date(now.setMonth(now.getMonth() - 1));
  }
}

2. Complaint rate (spam reports)

Target: Below 0.1% (1 complaint per 1,000 sends)

Complaint rates above 0.1% trigger deliverability penalties. Above 0.3%, you're at risk of being blocklisted by major ESPs.

One spam complaint costs you more than 100 successful sends. Protect your complaint rate like it's your runway.

3. Engagement rate (opens + clicks)

Target: 20%+ for transactional, 15%+ for marketing

Low engagement tells Gmail and Outlook that your emails aren't valuable. Even with perfect authentication, chronically low engagement pushes you toward the spam folder.

lib/monitoring/engagement-tracker.ts
export async function trackEngagementRate(days = 7) {
  const stats = await db.emailLog.aggregate({
    where: {
      sentAt: { gte: new Date(Date.now() - days * 24 * 60 * 60 * 1000) },
      delivered: true,
    },
    _count: {
      id: true,
      opened: { where: { opened: true } },
      clicked: { where: { clicked: true } },
    },
  });

  const delivered = stats._count.id;
  const opened = stats._count.opened;
  const clicked = stats._count.clicked;

  const openRate = (opened / delivered) * 100;
  const clickRate = (clicked / delivered) * 100;
  const engagementRate = ((opened + clicked) / delivered) * 100;

  // Alert on low engagement
  if (engagementRate < 15 && delivered > 100) {
    await alertSlack({
      message: `📉 Low engagement: ${engagementRate.toFixed(1)}% (last ${days}d)`,
      channel: "#deliverability-alerts",
    });
  }

  return { delivered, opened, clicked, openRate, clickRate, engagementRate };
}

4. Authentication pass rate

Target: 100% SPF + DKIM pass, 100% DMARC alignment

Even occasional authentication failures erode trust. Use Gmail Postmaster Tools to verify alignment, and monitor DMARC reports for failures.

5. Inbox placement rate (seed testing)

Target: 95%+ inbox (not spam/promotions)

Seed testing sends your emails to monitored accounts across Gmail, Outlook, Yahoo, and Apple Mail, then checks where they land (inbox, spam, or promotions tab).

Free tools: GlockApps (limited free tier), Mail-Tester (single-send checks)

Paid tools: Litmus Email Analytics, 250ok (better for high-volume senders)


How to recover from reputation damage

Caught a reputation drop early? Here's the 4-step recovery playbook:

Step 1: Stop the bleeding

  • Pause non-critical sends (newsletters, marketing)
  • Keep only high-priority transactional emails (resets, verification)
  • Suppress recent complainers and hard bounces immediately
  • Review last 7 days of sends for pattern changes (new template? list import?)

Step 2: Audit list hygiene

scripts/audit-list-hygiene.ts
import { db } from "@/lib/db";

export async function auditListHygiene() {
  // Find high-risk recipients
  const highRisk = await db.recipient.findMany({
    where: {
      OR: [
        // Never opened in last 90 days
        { lastOpenedAt: { lt: new Date(Date.now() - 90 * 24 * 60 * 60 * 1000) } },
        // Hard bounced recently
        { hardBounced: true },
        // Complained
        { complained: true },
        // Multiple soft bounces
        { softBounceCount: { gte: 3 } },
      ],
    },
  });

  console.log(`Found ${highRisk.length} high-risk recipients`);

  // Suppress or delete
  await db.recipient.updateMany({
    where: { id: { in: highRisk.map((r) => r.id) } },
    data: { suppressed: true, suppressedReason: "hygiene_audit" },
  });

  return highRisk;
}

Step 3: Re-warm gradually

Don't blast your full list the moment metrics recover. Use a gradual warm-up schedule:

  • Week 1: High-engagement recipients only (opened in last 30 days)
  • Week 2: Add medium-engagement (opened in last 60 days)
  • Week 3: Slowly reintroduce dormant users (60-90 days)
  • Week 4+: Resume normal sending if reputation stable

Step 4: Monitor obsessively

During recovery, check metrics daily:

  • Gmail Postmaster domain reputation (must stay "High")
  • Bounce rate (should drop below 1% within 3-5 days)
  • Complaint rate (watch for new reports; investigate each one)
  • Engagement rate (should increase as you target engaged users)
Set up automated alerts for threshold breaches. By the time you manually check and see a problem, hours of damage may have already occurred.

Set up automated monitoring (10 min)

Manual checks don't scale. Automate reputation monitoring with a simple cron job and Slack alerts:

app/api/cron/deliverability-check/route.ts
import { NextResponse } from "next/server";
import { trackBounceRate } from "@/lib/monitoring/bounce-tracker";
import { trackEngagementRate } from "@/lib/monitoring/engagement-tracker";
import { alertSlack } from "@/lib/alerts";

export async function GET(req: Request) {
  // Verify cron secret
  const authHeader = req.headers.get("authorization");
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response("Unauthorized", { status: 401 });
  }

  const bounceStats = await trackBounceRate("day");
  const engagementStats = await trackEngagementRate(7);

  // Build daily report
  const report = {
    date: new Date().toISOString().split("T")[0],
    bounceRate: bounceStats.bounceRate.toFixed(2),
    hardBounceRate: bounceStats.hardBounceRate.toFixed(2),
    engagementRate: engagementStats.engagementRate.toFixed(1),
    openRate: engagementStats.openRate.toFixed(1),
    clickRate: engagementStats.clickRate.toFixed(1),
  };

  // Alert if thresholds breached
  const alerts = [];
  if (bounceStats.bounceRate > 2.0) {
    alerts.push(`⚠️ Bounce rate: ${report.bounceRate}%`);
  }
  if (engagementStats.engagementRate < 15 && engagementStats.delivered > 100) {
    alerts.push(`📉 Engagement rate: ${report.engagementRate}%`);
  }

  if (alerts.length > 0) {
    await alertSlack({
      message: `Deliverability Alert\n${alerts.join("\n")}`,
      channel: "#deliverability-alerts",
    });
  }

  return NextResponse.json({ report, alerts });
}

// Deploy to Vercel Cron:
// Add to vercel.json:
// {
//   "crons": [{
//     "path": "/api/cron/deliverability-check",
//     "schedule": "0 9 * * *"
//   }]
// }

Prevention checklist (bookmark this)

Most reputation damage is preventable. Run this checklist monthly:

  • Authentication: Verify SPF, DKIM, DMARC passing at 100%
  • Bounce handling: Auto-suppress hard bounces immediately
  • Engagement pruning: Suppress users inactive 90+ days
  • Complaint monitoring: Review every spam report; identify patterns
  • Sending consistency: Avoid sudden volume spikes (>50% increase)
  • List-Unsubscribe header: Present on all bulk/marketing emails
  • Content quality: Avoid spam trigger words, broken links, HTML errors
  • Seed testing: Monthly inbox placement checks across providers
Good sender reputation isn't built in a day—it's maintained daily. Set up monitoring, automate hygiene, and catch issues before they cascade into deliverability crises.

Want production-ready templates that follow deliverability best practices out of the box? Check out our transactional email templates for Next.js — built with proper authentication, engagement-optimized copy, and tested across all major email clients.

Production-ready templates

Pick from 9 template packs built with React Email. One-time purchase, lifetime updates, tested across every major email client.

Browse all templates