KAHIBARO
Discord Login Register

18.2. SMTP

What SMTP Is

SMTP stands for Simple Mail Transfer Protocol. It is the main protocol used to send emails across the internet.

When your backend application sends an email, it almost always talks to an SMTP server. Your code does not push a message directly into someone’s inbox. Instead, it gives the message to an SMTP server, and that server is responsible for delivering the message to the recipient’s mail server.

You can think of SMTP as the “postal service protocol” for email. It defines:

Modern email delivery also involves security, spam checks, and other protocols, but SMTP is the foundation for sending.

Key idea: SMTP is used for sending and relaying email messages between mail servers. It is not used by clients to read email. Reading usually uses POP3 or IMAP.

SMTP Roles: Client and Server

In SMTP, there are two main roles:

RoleAlso calledTypical example
SMTP clientMail User Agent / Mail TransferYour backend app, a library like smtplib, or a mail relay
SMTP serverMail Transfer Agent (MTA)Gmail’s SMTP server, Postfix, Sendmail, Mailgun, etc.

Your backend behaves as an SMTP client:

  1. Connects to an SMTP server (for example smtp.gmail.com on port 587).
  2. Authenticates with username and password or some other method.
  3. Sends details about the email and the message content.
  4. Disconnects.

The SMTP server then takes over:

SMTP Ports

SMTP uses specific TCP ports.

Common SMTP ports:

PortUse caseEncryption style
25Server to server SMTPOften blocked for clients
465“SMTPS” legacy encrypted SMTPImplicit TLS from the start
587Submission port for clientsStart unencrypted, then STARTTLS

For backend applications, you usually use:

Rule: For application email sending, use the submission ports (587 or 465), not port 25, and always use encryption (TLS) if available.

Example configuration you might see:

text
SMTP_HOST=smtp.mailprovider.com
SMTP_PORT=587
SMTP_USERNAME=my_app@example.com
SMTP_PASSWORD=super-secret
SMTP_USE_TLS=true

The Basic SMTP Conversation

SMTP is a text-based protocol. The client and server exchange lines of text.

A simplified example:

  1. Client connects to server on port 587.
  2. Server: 220 smtp.example.com ESMTP Ready
  3. Client: EHLO myapp.local
  4. Server: responds with capabilities (for example STARTTLS, AUTH LOGIN).
  5. Client: STARTTLS (if using TLS upgrade).
  6. TLS handshake happens, connection becomes encrypted.
  7. Client: EHLO myapp.local again (now inside TLS).
  8. Client: AUTH LOGIN or another auth method, sends credentials.
  9. Client: MAIL FROM:<no-reply@myapp.com>
  10. Client: RCPT TO:<user@example.org>
  11. Client: DATA
  12. Client sends headers and body, ends with a line containing only a single dot:
text
    Subject: Welcome
    Hello user!
    .
  1. Server: 250 Message accepted for delivery
  2. Client: QUIT
  3. Server: 221 Bye

Each step uses simple commands and responses.

Common SMTP Commands

CommandMeaning
HELO / EHLOSay hello, identify the client
STARTTLSUpgrade the connection to TLS
AUTHAuthenticate (LOGIN, PLAIN, etc.)
MAIL FROMSet the envelope sender
RCPT TOAdd a recipient
DATAStart sending the message content
QUITEnd the session

You rarely need to type these manually. Libraries handle them, but understanding them helps debugging.

SMTP vs Email Message Format

There are two related but different parts:

  1. SMTP envelope
    • MAIL FROM:<...> and RCPT TO:<...>
    • Used for delivery and bounce handling
    • Not always visible to the user
  2. Message itself (the content inside DATA)
    • Has its own headers (like From:, To:, Subject:)
    • Contains the body (text, HTML, attachments)

It is possible for the SMTP envelope sender to be different from the From: header that users see. For example, mailing lists often do this.

Important: The envelope addresses (MAIL FROM, RCPT TO) control delivery. The From: and To: headers control what the recipient sees. They are not guaranteed to match.

SMTP Response Codes

SMTP servers respond with numeric codes similar to HTTP, but with 3 digits.

General meaning:

First digitMeaning
2xxSuccess
3xxMore information needed
4xxTemporary failure (try again later)
5xxPermanent failure (do not retry as-is)

Examples:

CodeMeaning
220Service ready
221Service closing transmission channel
235Authentication successful
250Requested action completed
354Start mail input (after DATA)
421Service not available, closing
450Mailbox unavailable, temporary
550Mailbox unavailable, permanent

In a backend app, your library will expose these as exceptions or error messages, but understanding 4xx vs 5xx helps decide whether you should retry.

SMTP Authentication

Most SMTP servers require authentication before you can send emails, especially when you connect from the internet as a client.

Typical methods:

If you try to send without authentication, you might see errors like:

SMTP AUTH is negotiated after EHLO. The client sends:

text
AUTH LOGIN

Then exchanges credentials (usually Base64 encoded) inside the TLS tunnel.

Rule: Never send SMTP credentials without TLS. If you see STARTTLS in the server features, use it. For ports like 465, TLS usually starts immediately.

SMTP Security: TLS and STARTTLS

SMTP by itself is plaintext. To secure it, we use TLS.

Two common patterns:

MethodPortHow encryption starts
Implicit TLS465TLS handshake happens immediately on connect
STARTTLS (explicit)587Start plaintext, then issue STARTTLS

Sequence with STARTTLS:

  1. Connect on port 587.
  2. EHLO.
  3. Server advertises STARTTLS.
  4. Client sends STARTTLS.
  5. TLS handshake happens.
  6. Client sends EHLO again in the encrypted channel.
  7. Client authenticates and sends email.

Backends usually only need to set a parameter like use_tls or use_ssl and the library handles the details.

SMTP in Backend Applications

In backend development, you usually do not interact with SMTP directly. Instead, you:

  1. Choose a mail provider:
    • Gmail (with app passwords or OAuth)
    • Services like SendGrid, Mailgun, Amazon SES
    • Your own SMTP server (Postfix, Exim, etc.)
  2. Configure your backend with:
    • SMTP host and port
    • Credentials
    • Whether to use TLS or SSL (implicit TLS)
    • From address and name
  3. Use a library (for example in Python) to:
    • Build the message (plain text or HTML)
    • Attach files if needed
    • Send via SMTP

Example high-level flow in pseudocode:

python
smtp = SMTP(
    host="smtp.mailprovider.com",
    port=587,
    tls=True,
    username="no-reply@myapp.com",
    password="secret",
)
msg = EmailMessage(
    from_="MyApp <no-reply@myapp.com>",
    to="user@example.org",
    subject="Welcome to MyApp",
    body="Thanks for signing up!"
)
smtp.send(msg)

Under the hood this does the full SMTP conversation you saw before.

Common SMTP Errors for Backends

When integrating SMTP, these are common issues:

ProblemTypical cause
Connection refused / timeoutWrong host or port, firewall, provider blocking
Authentication failedWrong username/password, account not allowed
535 5.7.8 Authentication ...Using wrong auth mechanism or invalid credentials
550 5.7.1 Relaying deniedNot authenticated, or trying to send from/to disallowed addresses
552 5.3.4 Message size exceedsEmail too large (attachments)
421 or 450 temporary errorsProvider rate limiting, remote server issues

Your backend should:

SMTP vs Email APIs

Many modern email providers give you two options:

Comparison:

AspectSMTPHTTP Email API
ProtocolSMTP over TCP (text commands)HTTP / HTTPS (JSON payloads)
LibrariesSMTP libraries, built into many languagesHTTP clients, often easier to debug
FeaturesBasic sending, standardOften richer (templates, tracking)
DebuggingSMTP logs, codesHTTP status & JSON responses

For backend beginners, SMTP is useful to understand conceptually, even if in production you often use a provider’s HTTP API for convenience.

Summary

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!