# Domain Reputation on SES

Source: https://wraps.dev/docs/guides/reputation

A complaint rate is a recipient-quality problem before it is a technical one. Authentication and bounce handling keep you out of obvious trouble; who you mail and how often is what actually moves the number.

The AWS thresholds, the CloudWatch alarms Wraps deploys per preset, and how to read a bounce are covered in [Bounce & complaint handling](https://wraps.dev/docs/guides/bounce-handling). This page is the other half: keeping the rate low in the first place, and what to do when it starts climbing anyway.

## What actually moves the number

In rough order of effect. The first two are worth more than everything below them combined.

1.  Mail people who asked. Confirmed opt-in costs you list size and buys you a complaint rate that stays flat under volume. A purchased or scraped list will cross 0.1% on its first real send, and no amount of authentication prevents that.
2.  Stop mailing people who stopped reading. Engagement is an input to placement at Gmail and Outlook. Someone who has not opened anything in six months is more likely to report spam than to convert. Suppress them on a schedule rather than waiting for them to complain.
3.  Make unsubscribing easier than complaining. Every spam button press is a complaint against your domain. A visible unsubscribe link plus `List-Unsubscribe` and `List-Unsubscribe-Post` headers give an annoyed recipient a cheaper exit. Google and Yahoo require one-click unsubscribe for bulk senders, and it is the single easiest complaint-rate win.
4.  Ramp new domains slowly. A cold domain sending 100,000 messages on day one looks exactly like a compromised one. Start in the hundreds, double every day or two while the rates stay clean, and send to your most engaged recipients first.
5.  One message per recipient. Thirty addresses in a single BCC means SES cannot tell you who complained. One send each keeps the attribution exact, which is what lets you suppress the right person.
6.  Authenticate everything. SPF, DKIM, and a DMARC record that is actually enforcing. This is table stakes rather than an advantage — it stops you being filtered for the wrong reason, and it does nothing for a bad list.

## Separate the streams so you can see which one is failing

Reputation is scored on the account. That means one bad campaign can take your password resets down with it, and the account average will not tell you which stream caused it.

streams

```
# Reputation is scored on the account, but SES can publish CloudWatch metrics# per configuration set. Adding a domain gives you the configuration set for# free — Wraps creates one per domain and names it after the domain.  wraps email domains add news.yourdomain.com  transactional   →  mail.yourdomain.com   →  wraps-email-tracking  marketing       →  news.yourdomain.com   →  wraps-email-news-yourdomain-com# The metrics are the part you have to turn on. Wraps enables reputation# metrics on the default configuration set for the Production and Enterprise# presets only, and never on the per-domain sets it creates. Until you enable# them, SES publishes no per-set Reputation.* metrics at all:  aws sesv2 put-configuration-set-reputation-options \    --configuration-set-name wraps-email-news-yourdomain-com \    --reputation-metrics-enabled# The account rate is still the one AWS acts on. Splitting the streams does# not protect you from a suspension; it tells you which stream caused it,# early enough to stop that one.
```

Wraps does not split the streams for you. It gives you the pieces: a configuration set per domain, and reputation metrics on the default set for the Production and Enterprise presets. Turning the metrics on for the second set is a one-line AWS call, and until you make it the split is real but invisible.

## Watching it

The dashboard shows bounce and complaint trends with bot opens filtered out. When you want the raw numbers, or want them in your own alerting, they are CloudWatch metrics in your account:

terminal

```
# Complaint and bounce rate for one configuration set, hourly, last 24h.aws cloudwatch get-metric-statistics \  --namespace AWS/SES \  --metric-name Reputation.ComplaintRate \  --dimensions Name=ses:configuration-set,Value=wraps-email-tracking \  --start-time "$(date -u -v-24H '+%Y-%m-%dT%H:%M:%SZ')" \  --end-time "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \  --period 3600 \  --statistics Maximum# Account-wide, which is the number AWS actually enforces on.aws sesv2 get-account --query 'SendQuota'
```

The rate AWS enforces on is a trailing account-wide average, so it moves slowly in both directions. That is why it has to be watched rather than checked: by the time it is visibly bad, pulling it back down takes as much clean volume as it took to spoil.

## When it starts climbing

A runbook, in order. The first step is the one people skip.

1.  Stop the bulk sending. Not the transactional stream. Pause campaigns and automated re-engagement before you start investigating, because every hour of continued sending adds to the average you are trying to pull down.
2.  Find the segment. Group recent complaints by campaign, by signup source, and by signup date. A complaint spike is almost always one list, one import, or one re-engagement send to people who forgot who you are.
3.  Suppress that segment entirely. Not just the individuals who complained. If one import is producing complaints, the rest of that import will too.
4.  Verify the suppression list is being enforced. Confirm bounces and complaints are actually landing on the SES account-level list rather than only in your own database.
5.  Resume at lower volume, most engaged first. Clean volume is the only thing that brings a trailing average back. Recipients who open reliably are the safest volume to send.
6.  If AWS has already written to you, answer with specifics. What the cause was, which segment you suppressed, and what you changed so it cannot recur. A reply that names a mechanism gets better outcomes than one that promises to be careful.

## Quarterly check

-   DMARC is enforcing, not `p=none`, and someone reads the reports.
-   One-click unsubscribe works, end to end, on a real send.
-   Recipients with no engagement in six months are suppressed or in a separate low-frequency stream.
-   Marketing and transactional are on different subdomains and different configuration sets.
-   Reputation alarms exist and point at a channel a human reads. The Starter preset ships with alerting off.

## Next steps

Thresholds and alarms live in the bounce guide. Suppression mechanics live in the suppression guide.

[Bounce & complaint handling](https://wraps.dev/docs/guides/bounce-handling)[Suppression lists](https://wraps.dev/docs/guides/suppression-lists)
