Amazon SES
SMTP
Python
Email Sending
AWS

amazon ses smtp python usage

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Amazon SES can send email either through its API or through a standard SMTP interface. If you want to use Python's built-in mail libraries or an existing SMTP-based mail workflow, SES SMTP works well, but you must use the correct regional endpoint, SMTP credentials, and TLS settings.

SES SMTP Is Not The Same As The SES API

A common source of confusion is that SES offers two different access styles:

  • the SES API, typically used through boto3
  • the SES SMTP interface, used through smtplib or any SMTP-capable client

If you use SMTP, you connect to an SES SMTP hostname and authenticate with SMTP credentials. That is different from calling AWS APIs with boto3 and IAM request signing.

A Minimal Python Example

python
1import smtplib
2from email.mime.text import MIMEText
3
4SMTP_HOST = "email-smtp.us-east-1.amazonaws.com"
5SMTP_PORT = 587
6SMTP_USERNAME = "YOUR_SMTP_USERNAME"
7SMTP_PASSWORD = "YOUR_SMTP_PASSWORD"
8FROM_EMAIL = "[email protected]"
9TO_EMAIL = "[email protected]"
10
11msg = MIMEText("Hello from Amazon SES SMTP")
12msg["Subject"] = "SES test"
13msg["From"] = FROM_EMAIL
14msg["To"] = TO_EMAIL
15
16with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
17    server.starttls()
18    server.login(SMTP_USERNAME, SMTP_PASSWORD)
19    server.send_message(msg)
20
21print("sent")

This is the basic pattern:

  1. connect to the SES SMTP endpoint for your region
  2. start TLS
  3. authenticate with SES SMTP credentials
  4. send the message

Use The Right Credentials

Do not assume your normal AWS access key and secret key are valid as raw SMTP username and password. SES SMTP credentials are a separate concept and must be created or derived appropriately for the SMTP interface.

Also note that temporary AWS security credentials are not the usual answer for SES SMTP authentication.

If the login fails, the first things to verify are:

  • SMTP username and password
  • region-specific endpoint
  • whether the credentials were created for SES SMTP use

Region Matters

SES SMTP endpoints are regional. If your verified identity and sending setup live in one region but your code connects to another region's SMTP endpoint, you can get authentication or sending failures.

That means the hostname in the example is not arbitrary. It needs to match the SES region you intend to use.

Sandbox And Identity Verification

New SES accounts often start in a sandbox-like state where sending is restricted. In that mode, you may need verified sender and recipient identities before messages will be accepted.

Even outside restricted sending mode, verify:

  • sender identity or domain is configured correctly
  • DKIM and related email authentication are set up when needed
  • quotas and sending limits are not being exceeded

SMTP code can be correct and still fail because SES account configuration is incomplete.

Use TLS And A Reasonable Port

Port 587 with STARTTLS is the normal default. Port 465 is possible for implicit TLS in some SMTP clients, but 587 is the common starting point.

Avoid plain-text SMTP submission. Even when testing, use TLS.

Build Proper MIME Messages For Real Email

For production mail, you will usually need multipart bodies, HTML, attachments, or explicit character encoding. Python's email package handles that cleanly.

python
1from email.mime.multipart import MIMEMultipart
2from email.mime.text import MIMEText
3
4msg = MIMEMultipart("alternative")
5msg["Subject"] = "HTML example"
6msg["From"] = FROM_EMAIL
7msg["To"] = TO_EMAIL
8msg.attach(MIMEText("Plain text version", "plain"))
9msg.attach(MIMEText("<h1>Hello</h1><p>HTML version</p>", "html"))

That is usually better than trying to handcraft raw SMTP message strings.

Common Pitfalls

The most common mistake is mixing up SES API credentials and SES SMTP credentials.

Another mistake is connecting to the wrong regional SMTP endpoint.

Developers also often forget SES account restrictions such as sender verification or sandbox limitations and then debug the Python code unnecessarily.

Finally, do not skip TLS setup. SES SMTP is an authenticated mail submission service, not a local development mail relay.

Summary

  • Use Python's smtplib with the SES regional SMTP endpoint.
  • Authenticate with SES SMTP credentials, not arbitrary AWS credentials.
  • Use STARTTLS on port 587 unless you have a specific reason not to.
  • Make sure sender identity and account configuration are ready in SES.
  • If sending fails, check credentials, region, and SES account restrictions before changing the code.

Course illustration
Course illustration

All Rights Reserved.