Notes from the Vault

MailZap - Case Study

MailZap started because a tool I relied on quietly disappeared. When Litmus retired PutsMail, I lost my go‑to way to sanity‑check HTML emails: paste the code, send a quick test, and see how it really looks in my inbox. The alternatives I found were heavy, paid platforms that didn’t fit simple day‑to‑day testing.

Here's the link: MailZap

So I built MailZap as a small, focused replacement. The first version runs on my laptop using Flask and a single HTML page. You paste your HTML, enter up to three email addresses, click “Send test email” and it sends real messages using your own account. The backend just validates the input, loops through the addresses, and returns clear success or error messages so you always know what happened.

When I tried to put MailZap online with Render so other people could use it, things broke in a non-obvious way. The UI loaded fine, but emails never arrived. After a lot of debugging and log‑watching, I found the core issue: Render’s free tier blocks outbound SMTP ports, and Gmail in particular doesn’t like traffic from cloud IPs. My original SMTP approach worked locally but timed out or failed in production.

The next iteration was to keep the local version on Gmail (simple and fully under my control) and switch the Render version to an HTTP email API instead of SMTP. I integrated Mailgun’s API on Render: the Flask route now makes a single HTTPS call to Mailgun, passing the recipients and HTML. This works within Render’s network rules and still fits within Mailgun’s free daily limit for a small testing tool.

Today MailZap has two honest stories:

  1. On my machine, it’s a lightweight HTML email tester powered by my own email account.

  2. Online, it’s the same experience, but delivered through a Mailgun API to get around SMTP blocks on free hosting.