---
title: "What is SMTP? How it works, from ports to reply codes"
description: "SMTP is the protocol that carries email from your app to your provider and between mail servers. How it works, which port to use and what each reply means."
url: "https://nextmail.sh/blog/what-is-smtp"
---

[Blog](https://nextmail.sh/blog.md)[Protocols](https://nextmail.sh/blog/tags/protocols.md)

# What is SMTP? How it works, from ports to reply codes

SMTP is the protocol that carries email from your app to your provider and between mail servers. How it works, which port to use and what each reply means.

Benjamin Nextmail team

October 31, 2026 10 min read

TL;DR

- SMTP, the Simple Mail Transfer Protocol, is the standard that mail apps and code use to hand a message to their provider, and that servers use to pass it on to the recipient's server.
- Mail apps and code send on port 465 with TLS from the start or on port 587 with STARTTLS, after signing in, while port 25 carries mail between servers and is blocked on many home and cloud networks.
- Every reply starts with a three-digit code, where 2xx means done, 4xx means try again later and 5xx means a permanent refusal.

SMTP, the Simple Mail Transfer Protocol, is the standard for sending email. A mail app or a script uses it to hand a message to its provider, which uses it to pass the message on to the recipient's server. It only sends: reading a mailbox is a separate job, done with [IMAP](https://nextmail.sh/blog/what-is-imap.md), POP3 or [JMAP](https://nextmail.sh/blog/what-is-jmap.md).

RFC 5321 defines the protocol, first published as RFC 821 in August 1982, and RFC 5322 the messages it carries. [Revisions of both](https://datatracker.ietf.org/wg/emailcore/documents/), approved as full Internet Standards, are waiting in the RFC Editor's queue. Apps may reach their own provider in other ways, but between providers, mail still travels over SMTP.

## How SMTP works: one message from app to inbox

Take Ada at `example.org` writing to Grace at `example.com`, with each program named as in [RFC 5598](https://www.rfc-editor.org/rfc/rfc5598.html):

1. **Ada's app writes the message.** It is the mail user agent (MUA): an [email client](https://nextmail.sh/blog/what-is-an-email-client.md), or the mail library in your code.
2. **Her provider's server accepts it.** The mail submission agent (MSA), on port 587 or 465, asks her to sign in and, as RFC 6409 allows, fixes details such as a missing Date header.
3. **A transfer agent finds Grace's server.** The mail transfer agent (MTA) looks up the MX records of `example.com` and tries the lowest-numbered one first. A domain with no MX record is its own mail server.
4. **The two servers talk SMTP on port 25.** Where both support it, they switch to TLS first. The receiving MTA checks who is sending, then accepts or refuses the message.
5. **The message reaches the mailbox.** A mail delivery agent (MDA) files it where Grace's app can read it.

Step 3 is an ordinary DNS query:

txt

```
$ dig +short MX example.com10 mx1.example.com.20 mx2.example.com.
```

Each server on the way adds a `Received:` line, so the headers trace a message's path. The [email address checker](https://nextmail.sh/tools/email-check.md) reads the MX records behind an address, so you can see whether its domain takes mail before you write to it.

## What is an SMTP server?

Any program that takes mail over SMTP, in one of two jobs. The outgoing server in a mail app's settings is a submission server: it takes mail only from its own users, once they sign in. The servers in a domain's MX records take mail for that domain from anyone, without a sign-in.

A server that passes mail on rather than delivering it is a relay, and an SMTP relay service is a sending service's submission server.

## SMTP commands: one conversation, line by line

This is Ada's app submitting her message on port 587. `C:` is the client and `S:` the server.

txt

```
S: 220 smtp.example.org ESMTP readyC: EHLO laptop.example.orgS: 250-smtp.example.orgS: 250-SIZE 26214400S: 250-STARTTLSS: 250 ENHANCEDSTATUSCODESC: STARTTLSS: 220 2.0.0 Ready to start TLS   (TLS handshake: everything below is encrypted)C: EHLO laptop.example.orgS: 250-smtp.example.orgS: 250-SIZE 26214400S: 250-AUTH PLAIN LOGINS: 250 ENHANCEDSTATUSCODESC: AUTH PLAIN AGFkYUBleGFtcGxlLm9yZwBhcHAtcGFzc3dvcmQ=S: 235 2.7.0 Authentication successfulC: MAIL FROM:<ada@example.org>S: 250 2.1.0 OKC: RCPT TO:<grace@example.com>S: 250 2.1.5 OKC: DATAS: 354 Start mail input; end with <CRLF>.<CRLF>C: From: Ada <ada@example.org>C: To: Grace <grace@example.com>C: Subject: Lunch on Friday?C: Date: Fri, 30 Oct 2026 09:12:00 +0000C: Message-ID: <lunch-1030@example.org>C:C: Are you free at one?C: .S: 250 2.0.0 OK queued as 4F2A91C: QUITS: 221 2.0.0 Bye
```

- **`EHLO`** asks what the server supports, one extension per `250-` line, until a line with a space after the code. It replaced `HELO`, and SMTP with extensions is often called ESMTP.
- **`STARTTLS`** switches to TLS. [RFC 3207](https://www.rfc-editor.org/rfc/rfc3207.html) then has both sides forget everything said before, so the client sends `EHLO` again, and this server offers `AUTH` only now.
- **`AUTH PLAIN`** signs in, once the connection is encrypted.
- **`MAIL FROM`** and **`RCPT TO`** are the envelope: the return address, then one command per recipient.
- **`DATA`** carries the message: header fields, a blank line, the body and a line holding only a dot. A leading dot in the message is doubled in transit, so the end cannot come early.
- **`250` after the dot** means the server now owns the message, and any later failure is its to report.

Between servers on port 25 the conversation is the same, minus `AUTH`. To try one yourself, use OpenSSL, which sends the first `EHLO` and `STARTTLS` for you:

txt

```
openssl s_client -connect smtp.example.org:587 -starttls smtp -crlf -quiet
```

## SMTP reply codes and enhanced status codes

The first digit of every reply says what to do next: 2 means done, 3 means go on, 4 means a temporary failure worth retrying, and 5 means a permanent one.

A server that announces `ENHANCEDSTATUSCODES`, as the one above does, adds a code from RFC 3463 such as `5.1.1`: the class again, the area (1 is the address, 2 the mailbox, 3 the mail system, 4 the network, 5 the protocol, 6 the content and 7 security or policy), then a detail. The replies people meet most:

| Reply | Meaning | Next step |
| --- | --- | --- |
| `250 2.0.0` | Accepted | None: the receiver is now responsible |
| `421 4.7.0` | Not now, closing the connection | Retry later |
| `452 4.2.2` | The mailbox is full | Retry, then give up if it stays full |
| `530 5.7.0` | Start TLS or sign in first | Turn on TLS and authentication |
| `535 5.7.8` | Wrong username or password | Fix the credentials |
| `550 5.1.1` | No such mailbox | Stop mailing the address |
| `550 5.7.1` | Refused by the receiver's policy | Read the reply text for the reason |
| `550 5.7.26` | More than one authentication check failed | Fix SPF, DKIM and DMARC |
| `552 5.3.4` | The message is too big | Send it smaller |

[IANA keeps the full list](https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml).

## The SMTP envelope and the message headers

The envelope is what `MAIL FROM` and `RCPT TO` say during the conversation. The headers are part of the content sent after `DATA`. RFC 5321 defines one, RFC 5322 the other, and nothing makes them match.

|  | Envelope | Headers |
| --- | --- | --- |
| Sender | `MAIL FROM`, the return address for bounces | `From:`, the author people see |
| Recipients | One `RCPT TO` per delivery | `To:` and `Cc:` |
| After delivery | Kept as a `Return-Path:` header | Kept as written |

That gap is how Bcc works, since a blind copy gets a `RCPT TO` but stays out of the headers others see. It is also how a sending service can use its own bounce address while yours stays in From.

SPF checks the envelope, the domain in `MAIL FROM`, not the From line people read. That is why DMARC counts an SPF pass only when that domain aligns with From. [What is SPF?](https://nextmail.sh/blog/what-is-spf.md) explains the check, and [What is DMARC?](https://nextmail.sh/blog/what-is-dmarc.md) explains alignment.

## Which SMTP port should you use: 25, 587 or 465?

SMTP uses port 25 between servers, and 587 or 465 when an app or your code sends through a provider.

| Port | Used for | Encryption |
| --- | --- | --- |
| 25 | Server to server, delivering to a domain's MX hosts | STARTTLS, where both sides support it |
| 587 | Submission: apps and code sending through their provider, after a sign-in | STARTTLS |
| 465 | Submission, as on 587 | TLS from the first byte, called implicit TLS |

RFC 8314 has recommended implicit TLS on 465 since 2018, while asking clients and servers to support both ports during a transition of several years. On 587, make the client require STARTTLS: an attacker who can alter traffic can delete the offer, and a client that does not insist carries on in plain text.

Older guides call 465 deprecated, but RFC 8314 gave it to submission after a brief, withdrawn registration for SMTP over TLS. Port 2525, which some guides suggest, has no standard behind it: [IANA's registry](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=2525) gives it to an unrelated service.

### Why is port 25 blocked?

Because computers taken over by malware send spam straight to receiving servers. M3AAWG, the industry's anti-abuse working group, has recommended since 2005 (updated in August 2023) that networks block port 25 except for mail servers they allow, and offer authenticated submission on 465 and 587.

[Google Cloud](https://docs.cloud.google.com/compute/docs/tutorials/sending-mail) blocks port 25 to destinations outside your network but not 587 or 465, and [Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-resource-limits.html) blocks it to public addresses until you ask for that to be lifted. So code at home or in the cloud sends through a provider, which handles port 25.

## Is SMTP secure?

Not by design. RFC 5321 calls SMTP mail "inherently insecure", because anyone can connect to a server and claim any sender. Two layers were added later: TLS for the connection, and [SPF, DKIM and DMARC](https://nextmail.sh/blog/spf-dkim-dmarc-explained.md) for the sender's identity.

Between servers, encryption is opportunistic: the receiver offers STARTTLS and the sender upgrades if it can. RFC 3207 forbids a public server from requiring it for local delivery, so mail from a server without TLS still arrives, and an attacker on the path can strip the offer unnoticed.

### MTA-STS and TLS reporting

MTA-STS (RFC 8461) lets a receiving domain publish a rule: use TLS with a valid certificate, and deliver only to these MX hosts. It takes a TXT record and a policy file served over HTTPS:

txt

```
_mta-sts.example.com.  TXT  "v=STSv1; id=20261031"
```

txt

```
https://mta-sts.example.com/.well-known/mta-sts.txt version: STSv1mode: enforcemx: mx1.example.commx: mx2.example.commax_age: 604800
```

In `enforce` mode, a sender will not deliver to a host that fails the check. `testing` mode delivers anyway and reports failures, the safe way to start. Reports go to the address in a TLS reporting record (RFC 8460), such as `v=TLSRPTv1; rua=mailto:tls@example.com` at `_smtp._tls.example.com`, once a day, in JSON.

### DANE

[DANE](https://www.rfc-editor.org/rfc/rfc7672.html) does the same through DNS: TLSA records for each MX host, at names such as `_25._tcp.mx1.example.com`, which count only in a zone signed with DNSSEC.

All of this protects one hop at a time. As RFC 3207 puts it, SMTP is not an end-to-end mechanism, so every server that relays a message can read it.

## SMTP authentication (SMTP AUTH)

A submission server relays only for people who sign in: RFC 6409 has it refuse `MAIL FROM` until the session is authenticated, and the `AUTH` command from RFC 4954 carries the credentials.

`PLAIN`, what mail apps call "Normal password", sends the username and password as base64 that anyone can decode, so RFC 4954 requires servers to have a setting that refuses plain-text passwords without encryption. `OAUTHBEARER`, from [RFC 7628](https://www.rfc-editor.org/rfc/rfc7628.html), sends an OAuth token instead.

## Bounces and deferrals: what happens when delivery fails

A `4xx` reply defers the message. The sender keeps it queued and tries again: RFC 5321 asks for at least 30 minutes between attempts and at least four to five days before giving up. Some receivers answer `4xx` on purpose to a sender they have not seen before, a practice called [greylisting](https://www.rfc-editor.org/rfc/rfc6647.html), because real servers retry and most spam software does not.

A `5xx` reply is final, and so is a deferral that runs out of time. The sending server then mails a bounce, a non-delivery report, to the envelope sender, with an empty envelope sender of its own (`MAIL FROM:<>`) so a bounce that fails has no address to come back to.

Many bounces can be avoided: the [email address checker](https://nextmail.sh/tools/email-check.md) catches bad syntax, domains that take no mail and throwaway addresses before the first send.

## SMTP or an email API?

Code can hand mail to a sending service over SMTP, or with an HTTPS request to its API.

|  | SMTP | Email API |
| --- | --- | --- |
| Works with | Any software that sends mail, unchanged | Code written for that service |
| Per message | Several commands and replies | One HTTPS request |
| Changing provider | New host and password | New code |
| Errors | Reply code, enhanced code and text | HTTP status and JSON |
| Tags or a send time | Custom headers, where supported | Fields in the request |

Neither success means delivered: both mean queued, and the outcome arrives later as bounces, events or webhooks. SMTP suits software you do not want to change, such as a CMS or a printer. An API suits code you write yourself, where one request carries everything.

## What Gmail, Yahoo and Microsoft require of senders

The largest mailbox providers add rules of their own:

- **Gmail** asks every sender for SPF or DKIM, a TLS connection, valid forward and reverse DNS and messages formatted by RFC 5322, and senders of more than 5,000 messages a day to Gmail accounts for SPF, DKIM and DMARC.
- **Yahoo** asks every sender for [valid forward and reverse DNS and compliance with RFCs 5321 and 5322](https://senders.yahooinc.com/best-practices/), and bulk senders for SPF, DKIM and DMARC.
- **Outlook.com** [refuses mail](https://support.microsoft.com/en-us/outlook/fix-ndr-error-550-5-7-515-in-outlook-com) from senders of 5,000 or more messages whose SPF, DKIM and DMARC fall short, with `550 5.7.515`.

Valid reverse DNS means a PTR record names a host that resolves back to the sending IP. Our posts on [SPF](https://nextmail.sh/blog/what-is-spf.md), [DKIM](https://nextmail.sh/blog/what-is-dkim.md) and [DMARC](https://nextmail.sh/blog/what-is-dmarc.md) cover the details, and the [deliverability checker](https://nextmail.sh/tools/deliverability.md) reads a domain's SPF, DKIM, DMARC, BIMI and MX records from live DNS.

## Where Nextmail fits

Nextmail runs the submission side for you. Any software that speaks SMTP, from a framework's mailer to a printer, can send through `smtp.nextmail.sh` on 465 with TLS from the first byte or 587 with STARTTLS, signed in as `nextmail` with an API key that has the `emails:send` scope. Nothing is accepted before the connection is encrypted.

Each message is the same send as `POST /emails` with that key, held to the key's scopes, the workspace's quota and its suppression list. The `250 2.0.0 OK queued as` reply carries the id that `GET /emails/{id}` reads, and the same `Message-ID` handed over again for the same recipients sends nothing new, so a mailer that retries cannot send twice. [Send over SMTP](https://nextmail.sh/docs/api/emails/smtp.md) has the settings and every reply.

Mail apps, which read as well as send, sign in to the same server with the whole address and an app password made for it. What they send passes the same checks and limits as the web app, picks up the address's signature and leaves a copy in Sent. [Mail apps](https://nextmail.sh/docs/knowledge/addresses/mail-apps.md) has the settings for each app.

## Free tools

Try what you just read on your own setup. They are free and need no account.

[Email deliverability checker SPF, DKIM, DMARC, BIMI and MX, read live.](https://nextmail.sh/tools/deliverability.md)[Email address checker See whether an address is worth sending to.](https://nextmail.sh/tools/email-check.md)

- [Protocols](https://nextmail.sh/blog/tags/protocols.md)
- [Deliverability](https://nextmail.sh/blog/tags/deliverability.md)
- [Developers](https://nextmail.sh/blog/tags/developers.md)

## References

1. 1 [RFC 5321: Simple Mail Transfer Protocol](https://www.rfc-editor.org/rfc/rfc5321.html) IETF
2. 2 [RFC 5322: Internet Message Format](https://www.rfc-editor.org/rfc/rfc5322.html) IETF
3. 3 [RFC 3463: Enhanced Mail System Status Codes](https://www.rfc-editor.org/rfc/rfc3463.html) IETF
4. 4 [RFC 4954: SMTP Service Extension for Authentication](https://www.rfc-editor.org/rfc/rfc4954.html) IETF
5. 5 [RFC 6409: Message Submission for Mail](https://www.rfc-editor.org/rfc/rfc6409.html) IETF
6. 6 [RFC 8314: Cleartext Considered Obsolete: Use of Transport Layer Security (TLS) for Email Submission and Access](https://www.rfc-editor.org/rfc/rfc8314.html) IETF
7. 7 [RFC 8461: SMTP MTA Strict Transport Security (MTA-STS)](https://www.rfc-editor.org/rfc/rfc8461.html) IETF
8. 8 [RFC 8460: SMTP TLS Reporting](https://www.rfc-editor.org/rfc/rfc8460.html) IETF
9. 9 [M3AAWG Best Common Practices for Managing Port 25 for IP Networks](https://www.m3aawg.org/Port25_IPNetworks) M3AAWG
10. 10 [Email sender guidelines](https://support.google.com/a/answer/81126) Google

Keep reading

## Related articles

Oct 31, 2026 10 min read

### What is IMAP? How IMAP works: ports, sync and security

IMAP is how mail apps read and organise mail that stays on the server, in sync on every device. How it works, which port to use and how it compares with POP3.

Arta Protocols

Oct 31, 2026 9 min read

### What is SPF? How SPF records work and where they break

SPF is the DNS record that lists the servers allowed to send mail for your domain. How receivers check it, what each part means and what quietly breaks it.

Arta Deliverability

Oct 31, 2026 9 min read

### What is an email client? How email clients work

An email client is the app you read and send mail in, apart from the service that holds your mailbox. How clients find servers, sync, send and guard privacy.

Benjamin Email clients

Try it yourself

## Your email, on your own domain.

Nextmail puts your domains, sending and inbox in one place, with the full API on every plan, the free one included.

[Open mail](https://nextmail.sh/mail/inbox) [Get Started](https://nextmail.sh/signup.md)[All articles](https://nextmail.sh/blog.md)
