Home / Guides / Send Email with Python

How to Send Email with Python

Two methods: REST API with requests or SMTP with smtplib. Plus Django and Flask integration examples.

Method 1: REST API with requests

The simplest approach. Install requests and make a single POST call.

import requests
import os

response = requests.post(
    "https://api.relaypost.dev/v1/emails/send",
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {os.environ['RELAYPOST_API_KEY']}",
    },
    json={
        "from": {"email": "[email protected]", "name": "Your App"},
        "to": [{"email": "[email protected]"}],
        "subject": "Your order has shipped",
        "html": "<h1>Order Shipped</h1><p>Your package is on the way.</p>",
    },
)

result = response.json()
print(result["data"]["message_id"])

Method 2: SMTP with smtplib

Python's built-in smtplib works with any SMTP relay. No external dependencies.

import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

msg = MIMEMultipart("alternative")
msg["Subject"] = "Your order has shipped"
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"

html = "<h1>Order Shipped</h1><p>Your package is on the way.</p>"
msg.attach(MIMEText(html, "html"))

with smtplib.SMTP("smtp.relaypost.dev", 587) as server:
    server.starttls()
    server.login(os.environ["SMTP_USERNAME"], os.environ["SMTP_PASSWORD"])
    server.sendmail(msg["From"], [msg["To"]], msg.as_string())

Django integration

Django has built-in email support via SMTP. Add these settings to your settings.py:

# settings.py
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.relaypost.dev"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ["SMTP_USERNAME"]
EMAIL_HOST_PASSWORD = os.environ["SMTP_PASSWORD"]
DEFAULT_FROM_EMAIL = "[email protected]"

Then send email from any view or management command:

from django.core.mail import send_mail

send_mail(
    subject="Welcome to YourApp",
    message="Thanks for signing up.",
    from_email="[email protected]",
    recipient_list=["[email protected]"],
    html_message="<h1>Welcome!</h1><p>Your account is ready.</p>",
)

Flask integration

Use the requests library directly in Flask routes — no Flask-Mail needed.

from flask import Flask, request, jsonify
import requests as http
import os

app = Flask(__name__)

@app.route("/register", methods=["POST"])
def register():
    data = request.get_json()
    # ... create user in database ...

    http.post(
        "https://api.relaypost.dev/v1/emails/send",
        headers={"Authorization": f"Bearer {os.environ['RELAYPOST_API_KEY']}"},
        json={
            "from": {"email": "[email protected]"},
            "to": [{"email": data["email"]}],
            "subject": "Welcome to YourApp",
            "html": "<h1>Welcome!</h1><p>Your account is ready.</p>",
        },
    )
    return jsonify(success=True)

Error handling

import requests
import os

try:
    response = requests.post(
        "https://api.relaypost.dev/v1/emails/send",
        headers={"Authorization": f"Bearer {os.environ['RELAYPOST_API_KEY']}"},
        json={
            "from": {"email": "[email protected]"},
            "to": [{"email": "[email protected]"}],
            "subject": "Hello",
            "html": "<p>Hello from RelayPost</p>",
        },
    )
    response.raise_for_status()
    print(response.json()["data"]["message_id"])
except requests.exceptions.HTTPError as e:
    error = e.response.json()
    print(f"Send failed: {error['error']['code']} - {error['error']['message']}")
except requests.exceptions.RequestException as e:
    print(f"Network error: {e}")

Best practices

  • Store API keys in environment variables, never in source code
  • Set up SPF and DKIM for your sending domain before production sends
  • Include both html and text content for maximum compatibility
  • Use a task queue (Celery, RQ) for non-critical emails to keep request latency low
  • Handle errors gracefully and retry transient failures
  • Use webhooks to track delivery status instead of polling the API

Frequently asked questions

What is the easiest way to send email with Python?

The easiest way is using the requests library with a REST email API. A single POST request with your API key and JSON payload sends the email. No SMTP configuration or email-specific libraries required.

Should I use SMTP or API for Python email?

Use the REST API with requests for new projects — it is simpler and gives you access to advanced features. Use smtplib if your existing codebase already uses SMTP or if you want to avoid external dependencies.

How do I send email with Django?

Django has built-in SMTP support. Set EMAIL_HOST to smtp.relaypost.dev, EMAIL_PORT to 587, and configure your SMTP credentials in settings.py. Then use Django's send_mail() function as usual.

How do I send email with Flask?

Use Flask-Mail with SMTP settings pointing to RelayPost, or use the requests library to call the REST API directly. The API approach is simpler and doesn't require Flask-Mail.

Start sending email from Python

Free tier includes 1,000 emails per month. Get your API key in 2 minutes.

Create free account