15 — SES: Transactional Email, and the Reputation That Decides If It Lands
"An email-sending API" was how I summarized SES, and the summary was dangerous: it made deliverability sound like a code problem. The corrective that landed: the SES API is the easy 20% — the real work is identity verification, email authentication (DKIM), reputation management, and climbing out of the sandbox so the messages actually reach the inbox [1]. A pipeline that can send a million messages is worthless if those messages land in spam, and SES makes that an operational concern, not just a code one.
What SES is for
Amazon Simple Email Service is a scalable, pay-as-you-go service for sending and receiving email [1]. The typical use is transactional email — the password-reset link, the order confirmation, the weekly digest — where the application triggers a send in response to an event. It also handles marketing mail, but the configuration and reputation bar for bulk is stricter still.
The thing SES is not: a mailbox provider. It does not host you@yourdomain.com for receiving and reading mail the way Gmail does. It's a sender (and optionally a receiver, via SMTP or API), focused on the delivery pipeline.
The sandbox: every account starts locked
Every new SES account begins in the sandbox [2]. In sandbox mode:
- I can only send to verified email addresses and domains.
- The maximum send rate is 1 email per second.
- The daily cap is 200 messages per 24 hours.
The sandbox exists to stop new accounts from being used as spam firehoses. To leave it, I submit a production access request through AWS Support, describing my use case, how I acquired the recipient addresses, and how I'll handle bounces and complaints. Approval is the gate between "I can test" and "I can serve real users." Plan for it — it's not instant.
Identity verification: proving I own the address
Before I can send from an address, SES requires me to prove I own it [3]. Two scopes:
- Email address verification — SES sends a confirmation link to the address; clicking it verifies that single sender.
- Domain verification — I add DNS records (a TXT and, for DKIM, three CNAME records) to the domain. Verifying the domain lets me send from any address on it (noreply@, billing@, alerts@), which is what production systems actually need.
Domain verification is the production path. Verifying individual email addresses is a sandbox-era convenience.
DKIM: the cryptographic signature
DKIM — DomainKeys Identified Mail — is the authentication standard that lets a receiving mailbox provider verify a message genuinely came from my domain [4]. SES supports it by giving me three CNAME records to publish in my DNS; once they propagate, SES signs outgoing messages with a private key, and receivers validate the signature against the public key in my DNS.
The reason DKIM matters: it is one of the three pillars (SPF, DKIM, DMARC) that mailbox providers use to decide inbox versus spam. Without it, a message "from" my domain could be trivially spoofed, and my real mail suffers. With it, plus SPF, a receiver has cryptographic proof of origin. DKIM is not optional for production sending.
Configuration sets: per-message routing and tracking
A configuration set is a bundle of rules attached to a send [5]. It lets me, per message:
- Choose a dedicated IP pool (more on those below).
- Enable event publishing — sends, deliveries, opens, clicks, bounces, complaints — to CloudWatch, Kinesis Firehose, or SNS.
- Apply message tags for grouping and analysis.
Configuration sets are how I make email observable. Without one, I know I asked SES to send; with one, I know whether it was delivered, opened, or bounced, per campaign or per message type. The discipline: every production send carries a configuration set, and the events flow somewhere I can alert on.
Feedback: bounces and complaints
Bounces are delivery failures (the address doesn't exist, the mailbox is full). Complaints happen when a recipient marks the message as spam. SES surfaces both as feedback notifications [6], deliverable by email, to an SNS topic, or to CloudWatch via a configuration set.
The reason feedback is operationally load-bearing: my sender reputation depends on keeping bounce and complaint rates low [7]. High rates tell mailbox providers I'm sending to people who didn't want the mail, and they start routing me to spam. The correct response to a bounce is to stop sending to that address — ideally automatically, by adding it to a suppression list. Ignoring feedback is the fastest way to wreck deliverability for every recipient, not just the bouncing one.
Reputation and dedicated IPs
Sender reputation is the score mailbox providers (Gmail, Outlook, etc.) maintain about my sending domain and IP, based on bounce rate, complaint rate, volume, consistency, and content quality [7]. Good reputation = inbox. Bad reputation = spam folder, regardless of whether the technical send succeeded.
Two capacity tiers interact with reputation:
- Shared pool (default) — my mail shares an IP with other SES customers. Cheapest, fine for low-to-medium volume, but I'm partially exposed to the pool's aggregate reputation.
- Dedicated IP — an IP reserved for me alone, where I fully own the reputation [8]. The right choice for high-volume senders or those with strict deliverability requirements. Dedicated IPs need "warming up" — ramping volume gradually to build reputation — before they carry full load.
How I use this
SES is my pick for transactional email the moment I outgrow a hosted service's free tier, but I treat the technical API as the easy part. The work I plan for: verify the sending domain (not just addresses) and turn on DKIM before sending anything real; submit the production-access request early, because the sandbox is unusable for real users; wire every send through a configuration set that publishes events to CloudWatch, so bounces and complaints are visible and alertable; and maintain a suppression list that auto-addrs hard-bouncing addresses, because the single biggest deliverability lever is "don't keep mailing addresses that rejected you." For high-volume senders I'd move to a dedicated IP and warm it gradually. The way of thinking I keep: sending the mail is a solved problem; landing the mail is an ongoing operational discipline measured in bounces and complaints, and SES gives me the signals to manage it but won't manage it for me.
References
[1] Amazon Web Services, "What is Amazon SES?," 2024. [Online]. Available: https://aws.amazon.com/ses/
[2] Amazon Web Services, "Managing sending quotas in Amazon SES," SES Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/ses/latest/dg/manage-sending-quotas.html
[3] Amazon Web Services, "Verifying identities in Amazon SES," SES Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/ses/latest/dg/Welcome.html
[4] Cloudflare, "DMARC, DKIM, and SPF explained," 2024. [Online]. Available: https://www.cloudflare.com/learning/email-security/dmarc-dkim-spf/
[5] Amazon Web Services, "Using configuration sets with Amazon SES," SES Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/ses/latest/dg/using-configuration-sets.html
[6] Amazon Web Services, "Amazon SES feedback notifications," SES FAQ, 2024. [Online]. Available: https://aws.amazon.com/ses/faqs
[7] Amazon Web Services, "The four pillars of email reputation," AWS Messaging Blog, 2023. [Online]. Available: https://aws.amazon.com/blogs/messaging-and-targeting/the-four-pillars-of-email-reputation/
[8] Amazon Web Services, "Dedicated IPs in Amazon SES," SES Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/ses/latest/dg/dedicated-ip.html
Knowledge check · Question 1 of 5
Every new SES account starts in the sandbox, which means…
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!