September 24, 2026 · 6 min read
We got SES production access. Here is exactly what AWS asked.
Amazon granted PigeonAtlas production access on the first request: 50,000 a day, 14 a second. The full text of the request, what the reviewers actually check, and a checklist you can copy.
On September 19 Amazon granted PigeonAtlas production access to SES in eu-central-1: 50,000 messages a day, 14 a second, on the first request, four days after we sent it. Until then the account was a sandbox, which means mail reaches only addresses you have verified yourself: fine for testing, useless for a product.
"SES production access denied" is one of the most searched phrases in this corner of the internet, and almost nobody publishes what they sent. This post does, because the request is the whole trick: there is no form to game, only a reviewer reading whether you understand what you are asking for.
Key takeaways
- The request is a Support case, not an email. It is opened from the SES console; every follow-up goes into the same case.
- Reviewers care about four things, in this order: where recipients come from, what happens on bounces and complaints, how people opt out, and how you stop abuse if you send for others.
- They read your website. The policy pages you link are checked; the follow-up questions quote them.
- Ask for a modest quota. We asked for 50,000 a day and got exactly that; a larger number invites more questions, and increases are routine later.
Where is the request actually sent?
Nowhere you can type an address. In the SES console, in the region you send from, the account dashboard shows a yellow box saying the account is in the sandbox and a button, Request production access. That opens a form with five fields (mail type, website URL, use-case description, additional contacts, language) and submitting it creates a case in Support Center. AWS answers there, and there is where you reply if they ask for more.
The same request exists as an API call, PutAccountDetails, which is what the console does underneath. The console is simpler.
What did the request say?
The use-case description was written as a letter, because a person reads it. This is the structure, with the substance of each section:
What we send. Developers integrate PigeonAtlas through an HTTP API or SMTP submission to send transactional email from their own applications: password resets, sign-in codes, order confirmations, receipts. Each message is a response to something the recipient just did. Bulk mail exists only as an explicit broadcast feature to a list the customer uploaded, and is handled separately.
Volume. Under 20,000 a month across all customers in the first three months, growing with onboarding. Requesting 50,000 a day and 14 a second to start.
Where recipients come from. Our customers' own users. We do not build, buy, rent or share lists, and our acceptable use policy prohibits purchased or scraped lists on pain of suspension.
Domain verification. An account cannot send until it has proven control of a domain through DNS: a 2048-bit DKIM key per domain, an SPF record and a custom MAIL FROM subdomain with its MX record. We verify all three ourselves before allowing any send, and register the identity with SES at the same time, so every message is DKIM- and SPF-aligned with the customer's own domain. There is no shared sending domain.
Bounces and complaints. All sending goes through a configuration set with an SNS event destination. We verify the SNS signature, record every delivery, bounce and complaint against the originating message, and add permanently bounced or complaining addresses to the account's suppression list immediately and automatically. A suppressed address is refused at the API before it enters the queue. Customers see bounce and complaint rates per domain against the thresholds AWS applies.
Opt-out. Every broadcast carries List-Unsubscribe and List-Unsubscribe-Post headers and an unsubscribe link; unsubscribing suppresses the address at once. Bulk and transactional traffic run on separate queues.
Abuse prevention as a platform. Open registration is limited to a free plan that cannot send without a verified domain; sending is rate limited per account and per recipient domain; sign-in and password reset are rate limited; staff can suspend an account instantly; message bodies are retained for 30 days for investigation. Links to the anti-abuse and acceptable use pages, and the abuse mailbox.
Infrastructure. Application and database at DigitalOcean Amsterdam, archived bodies in Frankfurt, mail only through SES in eu-central-1.
Every paragraph described something the code already did. That is the part worth repeating: the request is not a persuasion exercise. If your bounce handling is "we look at the dashboard sometimes", write a bounce handler first and then ask.
What do the reviewers actually check?
Three things we can say with confidence, from the follow-up and from the timing:
- They open the website. The reply referenced our refund and anti-abuse pages by name. If the request links to a policy, the policy is read.
- They look for the feedback loop. "How do you handle bounces and complaints" is the question that decides most reviews. The answer has to name a mechanism (SNS notifications, a suppression list, a threshold), not an intention.
- They want to know who the recipients are. For a platform that sends on behalf of others, this becomes "how do you vet your customers", and the answer has to describe a gate a script cannot pass. Ours is the verified domain: a throwaway account has nothing to send from.
What if you are refused?
The standard wording is that your use case "could negatively impact the deliverability of the service". It is usually a generic reply to a request without enough detail, not a verdict on your product. Reply in the same case (do not open a new one) with the four sections above, one paragraph each, and ask for reconsideration. If it happens twice, send a few hundred messages to verified recipients inside the sandbox first, so the account has a bounce-free history, then ask again.
A checklist you can copy
Before submitting:
- The policy pages you will link exist, are reachable without an account, and describe what the code does.
abuse@,support@andsecurity@mailboxes exist and are read.- You can name the mechanism for bounces, for complaints and for unsubscribe, in one sentence each.
- You know your expected volume for three months and are asking for a quota near it.
- Your sending domain is verified in your own product before you claim it is.
After approval:
- Raise your own dispatcher's rate limit to the granted rate and not above it: ours was still pacing at the sandbox's one message a second for a day after approval, which is a slow way to send a broadcast.
- Set the operations alternate contact on the AWS account to a mailbox someone reads; reputation notices go there.
- Quota increases go through Support Center as a service limit increase, with the last 30 days of bounce and complaint rates from the reputation dashboard.
PigeonAtlas does the domain verification, the suppression and the headers for you, which is most of what the request is about. If you would rather not write your own SNS handler before you can send a password reset, start with the free plan: a thousand messages a month from a domain you own, no card.