Send emails with Django

In this quickstart, you'll learn how to send transactional emails from your Django 4 or 5 app with Sidemail. You'll set up the SDK, send your first email, and see examples for common use cases like welcome emails, password resets, and scheduled reports.

Before you start

  1. Create a Sidemail account → get your API key
  2. Add a sending domain → set up your domain for sending

1. Install

pip install sidemail

2. Configure API key

Add your API key to settings.py.

# settings.py
import os

SIDEMAIL_API_KEY = os.getenv("SIDEMAIL_API_KEY")

3. Setup client

Create a shared instance of the Sidemail client. You can place this in a services.py file within your project or app.

# myapp/services.py
from django.conf import settings
from sidemail import Sidemail

sidemail = Sidemail(api_key=settings.SIDEMAIL_API_KEY)

4. Send a welcome email

Send an email when a user registers.

# myapp/views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .services import sidemail
import json

@csrf_exempt
def register(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        email = data.get('email')
        name = data.get('name')

        # ... create user in database ...

        sidemail.send_email(
            toAddress=email,
            fromAddress="[email protected]",
            fromName="Your App",
            templateName="Welcome",
            templateProps={"firstName": name},
        )

        return JsonResponse({"message": "User registered"})

5. Send a password reset email

# myapp/views.py
@csrf_exempt
def forgot_password(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        email = data.get('email')
        token = "secure-reset-token" # Generate this securely

        sidemail.send_email(
            toAddress=email,
            fromAddress="[email protected]",
            fromName="Your App",
            templateName="Password Reset",
            templateProps={
                "actionUrl": f"https://myapp.com/reset/{token}",
            },
        )

        return JsonResponse({"message": "Reset email sent"})

6. Send a weekly report (Management Command)

Django Management Commands are the standard way to create scripts for cron jobs.

# myapp/management/commands/send_weekly_report.py
from django.core.management.base import BaseCommand
from myapp.services import sidemail

class Command(BaseCommand):
    help = 'Sends weekly report email'

    def handle(self, *args, **options):
        # In a real app, fetch this from your database
        new_signups = 150
        chart_data = [100, 200, 300, 400, 200, 300, 200, 500]

        sidemail.send_email(
            toAddress="[email protected]",
            fromAddress="[email protected]",
            fromName="My App",
            templateName="Weekly Report",
            templateProps={
                "signups": new_signups,
                "chart": chart_data,
            },
        )

        self.stdout.write(self.style.SUCCESS('Weekly report sent'))

Run it via cron:

# Run every Monday at 8:00 AM
0 8 * * 1 python manage.py send_weekly_report

7. Send email via Signals

Decouple email sending from your views using Django Signals.

# myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .services import sidemail

@receiver(post_save, sender=User)
def send_welcome_email(sender, instance, created, **kwargs):
    if created:
        sidemail.send_email(
            toAddress=instance.email,
            fromAddress="[email protected]",
            fromName="My App",
            templateName="Welcome",
        )

# Don't forget to import signals in your apps.py ready() method!

8. Send HTML email (with Django Templates)

Use render_to_string to generate HTML from Django templates.

from django.template.loader import render_to_string

def send_invoice(request):
    # templates/emails/invoice.html
    html_content = render_to_string('emails/invoice.html', {'amount': 99})

    sidemail.send_email(
        toAddress="[email protected]",
        fromAddress="[email protected]",
        fromName="Your App",
        subject="Your Invoice",
        html=html_content,
    )

    return JsonResponse({"message": "Invoice sent"})

9. Send Markdown email

Store your markdown content in a file and load it (learn more).

import os
from django.conf import settings

def send_markdown(request):
    # Assuming templates are in your templates directory
    template_path = os.path.join(settings.BASE_DIR, 'templates/emails/welcome.md')

    with open(template_path, "r") as f:
        markdown_content = f.read()

    # Subject and sender are defined in the markdown frontmatter
    sidemail.send_email(
        toAddress="[email protected]",
        markdown=markdown_content,
        templateProps={
            "name": "John",
            "link": "https://example.com",
        },
    )

    return JsonResponse({"message": "Email sent"})

10. Send plain text email

sidemail.send_email(
    toAddress="[email protected]",
    fromAddress="[email protected]",
    fromName="Your App",
    subject="Hello",
    text="Hello! 👋",
)

11. Schedule email

Send email later. Set scheduledAt to an ISO date string.

import datetime

# Schedule for 1 hour from now
scheduled_at = (datetime.datetime.utcnow() + datetime.timedelta(hours=1)).isoformat() + "Z"

sidemail.send_email(
    toAddress="[email protected]",
    fromAddress="[email protected]",
    fromName="Your App",
    templateName="Welcome",
    templateProps={"firstName": "Alex"},
    scheduledAt=scheduled_at,
)

12. Send with attachment

Use the Sidemail.file_to_attachment helper to attach files.

from sidemail import Sidemail

with open("invoice.pdf", "rb") as f:
    pdf_data = f.read()

attachment = Sidemail.file_to_attachment("invoice.pdf", pdf_data)

sidemail.send_email(
    toAddress="[email protected]",
    fromAddress="[email protected]",
    fromName="Your App",
    subject="Your invoice",
    text="See attached.",
    attachments=[attachment],
)

13. Handle errors

from sidemail import SidemailError
import logging

logger = logging.getLogger(__name__)

try:
    sidemail.send_email(
        # ...
    )
except SidemailError as e:
    logger.error(f"Sidemail error: {e.message}")