Amazon SES is dominant at the low end of the cost curve. Ten cents per thousand emails is hard to argue with. Teams sending millions of emails a month routinely pick SES because the bill at SendGrid or Mailgun is an order of magnitude higher.
The trade-off is visibility. SES gives you delivery notifications, bounce events, complaint events, and a reputation dashboard that flags serious problems only when they are already serious. What SES does not give you is folder placement. There is no Gmail-level tab detection, no Microsoft junk verdict, no Yahoo engagement heuristic surfaced back to you. SES sent the mail, the receiver accepted it, the end.
That is fine for a transactional receipt where “delivered” is close enough. It is not fine for a newsletter to 500,000 addresses where Promotions versus Primary at Gmail is a 3x engagement difference.
The SES bulk send model
SES exposes a SendBulkEmail API (in v2) that takes a template and an array of destinations. Each destination is a recipient plus per-recipient merge data. SES renders the template per recipient and sends. This is the cheap, high-throughput path.
Because each destination is a full object with its own ToAddresses, CcAddresses, and BccAddresses fields, you have a clean insertion point for seed mailboxes. You add seeds as additional destinations in the same BulkEmailEntries array, or as BCCs on existing entries. Both work.
Option A: seeds as separate destinations
Add a handful of destinations where the ToAddresses is a seed mailbox. SES renders the template with whatever merge data you pass (use synthetic values that mirror real recipients). The seed gets an email that looks identical to what real recipients receive.
aws ses v2 send-bulk-email \
--from-email-address "news@example.com" \
--default-content '{
"Template": {
"TemplateName": "weekly-newsletter",
"TemplateData": "{\"first_name\":\"there\",\"link\":\"https://example.com/issue/42\"}"
}
}' \
--bulk-email-entries '[
{
"Destination": { "ToAddresses": ["user1@example.com"] },
"ReplacementEmailContent": {
"ReplacementTemplate": {
"ReplacementTemplateData": "{\"first_name\":\"Anna\"}"
}
}
},
{
"Destination": { "ToAddresses": ["seed-gmail@your-seed-domain.test"] },
"ReplacementEmailContent": {
"ReplacementTemplate": {
"ReplacementTemplateData": "{\"first_name\":\"Seed\"}"
}
}
},
{
"Destination": { "ToAddresses": ["seed-outlook@your-seed-domain.test"] },
"ReplacementEmailContent": {
"ReplacementTemplate": {
"ReplacementTemplateData": "{\"first_name\":\"Seed\"}"
}
}
}
]' \
--configuration-set-name "newsletter-cs"Option B: seeds as BCCs
You can also add seeds as BCC on one or more real destinations. This gives you a seed copy for every production send, which is useful for ongoing monitoring but doubles your mail volume to seed mailboxes over time. For large newsletters it is better to use Option A with a fixed seed batch per send.
Configuration Sets and event destinations
SES configuration sets are the right place to wire up visibility. A configuration set can route events — sends, deliveries, bounces, complaints, opens, clicks — to CloudWatch, Kinesis Firehose, SNS, or an EventBridge bus. You want at minimum:
- Bounces and complaints to SNS so you get an immediate alert on a spike.
- Deliveries and opens to a warehouse (Firehose to S3, then query with Athena) so you can join with seed placement data later.
- Reputation metrics to CloudWatch with alarms on complaint rate above 0.1 percent and bounce rate above 2 percent.
None of these replace seed placement testing. They tell you about the SMTP layer and the complaint layer, not about folder placement.
The free Inbox Check tool generates 20+ fresh seed addresses per test across Gmail, Outlook, Yahoo, Mail.ru, Yandex, ProtonMail and more. No signup, no credit card.
SES-specific placement gotchas
Bulk SES sends have a few patterns that seeds will surface fast:
- Shared IP pool surprises. Default SES IPs are shared. A neighbour with a bad run can move your placement. Seeds catch this even when your own content is unchanged.
- Dedicated IP warmup. If you are on dedicated IPs, warmup is long — weeks of graduated volume. Seed on every warmup day so you see placement rising across providers.
- Sandbox vs production. A newly moved-to-production SES account sometimes has placement issues at Microsoft for the first week. Seeds during the first real campaigns are critical.
- Template content drift. SES templates rendered with different merge data produce slightly different bodies. Occasionally a template change (a new link block, a longer preheader) shifts Gmail tab. Seeds catch this immediately.
Turning seed results into a feedback loop
The value of seeding is only realised if someone looks at the seeds. A tight loop for an SES newsletter team:
- Every bulk send includes 10 to 20 seed addresses across providers. Log the send IDs alongside the seed addresses used.
- Within 30 minutes of send, run a placement check (manually or via an inbox-check tool) against the seed mailboxes. Record Primary/Promotions/Junk per provider.
- If any provider flags Junk or Promotions, compare to the previous send. What changed in template, subject, from-name, or list segment?
- Roll the result into a weekly deliverability review. Trends matter more than single sends.