Send email from Django over SMTP

Django email configuration for SMTP: EMAIL_BACKEND, EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS vs EMAIL_USE_SSL, credentials from the environment, send_mail and EmailMultiAlternatives, plus the console backend for development.

Install

shell
# built in — django.core.mail

Complete example

Django — STARTTLS on 587, credentials from the environment
# settings.py
import os

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = os.environ.get("SMTP_HOST", "smtp.queensmtp.com")
EMAIL_PORT = int(os.environ.get("SMTP_PORT", "587"))
EMAIL_USE_TLS = EMAIL_PORT == 587        # STARTTLS
EMAIL_USE_SSL = EMAIL_PORT == 465        # implicit TLS — never set both True
EMAIL_HOST_USER = os.environ["SMTP_USER"]
EMAIL_HOST_PASSWORD = os.environ["SMTP_PASS"]
EMAIL_TIMEOUT = 20
DEFAULT_FROM_EMAIL = "Your App <hello@yourdomain.com>"
SERVER_EMAIL = "alerts@yourdomain.com"   # for error mails to ADMINS

# anywhere
from django.core.mail import send_mail, EmailMultiAlternatives

send_mail("Your receipt", "Thanks for your order #1042",
          None, ["customer@example.com"])         # None = DEFAULT_FROM_EMAIL

msg = EmailMultiAlternatives("Your receipt", "Thanks for your order #1042",
                             None, ["customer@example.com"])
msg.attach_alternative("<h1>Thanks for your order</h1><p>#1042 is confirmed.</p>", "text/html")
msg.send()

# development: print instead of sending
# EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

What to know

  • EMAIL_USE_TLS and EMAIL_USE_SSL are mutually exclusive; TLS = STARTTLS on 587, SSL = port 465.
  • python manage.py sendtestemail you@yourdomain.com is the fastest test.
  • Send from a background task (Celery/RQ) in production; SMTP round-trips add 0.5–2 s to a request.
  • For a Gmail account use smtp.gmail.com with an App Password; for SES use the region endpoint and SMTP credentials — the settings block is otherwise identical.

Same code, different provider

Only the host, port and credentials change. The rules per provider are on the SMTP settings hub.

ProviderHostPortUsernamePasswordNote
QueenSMTP smtp.queensmtp.com587 (STARTTLS) / 465 (SSL) / 2525SMTP username from the dashboardSMTP password$5/year + $0.10 per 1,000; 100 free/day
Gmail smtp.gmail.com587 / 465you@gmail.comApp Password500/day, From must be the account
Amazon SES email-smtp.<region>.amazonaws.com587 / 465 / 2587SES SMTP usernameSES SMTP passwordsandbox 200/day until approved
Office 365 smtp.office365.com587user@yourdomain.commailbox passwordSMTP AUTH must be enabled; 30/min
SendGrid smtp.sendgrid.net587 / 465 / 2525apikeyAPI keyno free plan since 2025

Credentials for the example above

Create a free account, verify your sending domain (SPF + DKIM shown in the dashboard), add an SMTP credential, and paste it into the code. 100 emails a day free; $5/year plus $0.10 per 1,000 after that. Prefer HTTPS? The same account has a REST email API.

Get SMTP credentials Test your settings first

Other languages and frameworks

Examples tested 2026-08-30. If a library changed its API, tell us.

Django SMTP — questions

Run python manage.py sendtestemail your@address; check EMAIL_HOST/PORT/TLS match the provider; on a cloud VM confirm the port is not blocked (25 usually is). Set EMAIL_BACKEND to the console backend to verify your code path first.