Choose the right email protocol

Trace and choose the complete email path

Map every stage of a real provider setup and choose protocols according to trust, synchronization, and interoperability needs.

We’ve covered every protocol on the path. Let’s put them back together on one message and see how to prove each step worked.

The outgoing path is: mail app → authenticated submission → sending MTA → DNS MX lookup → receiving MTA → delivery → mailbox → reading client.

Label every arrow. Submission is SMTP on 587 or 465 with TLS. Relay is SMTP on 25. Delivery is SMTP or LMTP. Access is IMAP on 993, POP3 on 995, or JMAP over HTTPS. The SMTP envelope stops mattering after the final 250 at delivery. From there on, only the RFC 5322 message exists.

Where provider APIs fit

Most apps I build don’t speak SMTP directly. They call Resend, Postmark, or Amazon SES over HTTPS and get webhooks back. I compared the options in Email for developers.

Those APIs are a contract with one provider, not a universal transport. Behind them, the provider still speaks SMTP to the recipient’s server.

Evidence at every stage

Write down what success and failure look like at each step:

StageProtocol or formatSuccess evidenceCommon failure evidence
SubmissionSMTP on 587 or 465final 250 and queue ID535, 552, TLS error
RelaySMTP on 25remote final 2504xx, 5xx, timeout
DeliverySMTP or LMTPmailbox delivery resultquota or policy reply
Storageprovider mailboxUID or object IDmissing or rebuilt state
AccessIMAP, POP3, JMAPtagged OK, +OK, method resultprotocol or sync error

The rule that ties this course together: success at one layer proves nothing about the next.

A webhook saying “accepted” often means “in our queue”. A “delivered” event means the recipient’s server said 250, not that Sara can see it on her phone yet. Name your status values after the evidence you have.

Redact before you share

Raw traces are full of sensitive data: bearer tokens, internal hostnames, addresses, message content, provider IDs. Strip them before pasting into a ticket. Keep timestamps with time zones, reply codes, and a correlation ID you control.

Do it once for real

Send a test message to an account you control and trace it. Collect the submission queue ID, the oldest and newest Received fields, the MIME tree, and the UID the mailbox assigned.

Somewhere you’ll hit a gap: a hop with no log, a webhook that never fired. Write it down instead of guessing. Knowing where you can’t see is as useful as knowing where you can.

Lesson completed