Projects Growth · Infrastructure
In-house B2B email infrastructure
My own commercial email system on AWS, to promote and sell my services and companies.
- Role
- Creator
- Year
- 2026
- Tools
- Python · Flask · SQLite · AWS SES · AWS SNS · DNS (SPF · DKIM · DMARC)
- Status
- Working · own use
How to use it
It simulates a campaign of 1,002 contacts: invalid addresses drop out at validation, the rest wait in the daily queue and go out through SES. Move the daily cap to see how many days it takes to complete. The brakes are the real system’s; the rejection and bounce rates are illustrative.
Mailchimp charges per contact and per month. Amazon charges $0.10 per 1,000 emails. I built my own sending system on top of Amazon, with everything needed for emails to land in the inbox.
- $0.10
- Cost of sending 1,000 emails with AWS SES
- 50,000
- Emails per day allowed by the account (14 per second)
- 4
- Domain authentication records configured and verified
- 17
- Automated tests before every change
What it is
I built it to promote and sell my own services and companies. It is a Flask web application that does what Mailchimp does for commercial campaigns (lists, templates and follow-up sequences) and sends through Amazon SES, AWS’s email service, with a production account that allows 50,000 emails a day.
| Piece | What it does |
|---|---|
validate.py |
Discards addresses before spending a send: syntax, the domain’s MX record and disposable domains |
ses.py |
Sends through SES with an HTML version and a plain-text version |
| Scheduler | Splits each campaign into daily batches and schedules the follow-ups |
| SNS | AWS reports every bounce and complaint; the address goes to a suppression list |
marcar_respondido.py |
Removes from the sequence anyone who replies, so as not to insist |
| 17 tests | Check greeting, plain text and templates before every change |
Safe sending by design
- Disarmed by default. Unless it is switched on deliberately, nothing goes out.
- A daily cap of 400, far below what is allowed, so that the domain builds its reputation gradually.
- One campaign at a time.
- Backlog expires after 6 hours. If the computer was off, the queue doesn’t empty all at once when it is switched back on.
Reaching the inbox
Sending is easy; getting the email into the primary inbox is the hard part. I worked on it on two fronts:
- Domain authentication. SPF authorising Amazon, DKIM signing, a DMARC policy and its own bounce domain aligned with the sender. All four verified through DNS and in the AWS console.
- Controlled content tests. Using Gmail accounts with no history, I compared versions of the same email changing just one thing at a time: the text, the links, the footer, the unsubscribe header, the layout. That is how I found the format that reaches the primary inbox: plain text, written like a person-to-person email, with the unsubscribe option explained in the body itself, which complies with Spanish e-commerce law (LSSICE).
What I take away
A commercial channel of my own, for pennies, and a method for improving delivery: change one variable at a time and measure.