Frameworks

Django

Send transactional emails from Django with one requests.post — no SDK.

Send transactional emails from your Django app. No SDK required — one requests.post is the whole integration.

1. Add to settings.py

settings.py
EMITD_API_KEY = os.environ.get('EMITD_API_KEY')
EMITD_FROM_EMAIL = 'hello@yourdomain.com'

2. Create an email service

services/email.py
import os
import requests

EMITD_API = 'https://api.emitd.com/v1/email'


def _send(payload, headers=None):
    return requests.post(
        EMITD_API,
        headers={'Authorization': f"Bearer {os.environ['EMITD_API_KEY']}", **(headers or {})},
        json=payload,
        timeout=10,
    )


def send_welcome_email(user, idempotency_key=None):
    headers = {'Idempotency-Key': idempotency_key} if idempotency_key else None
    return _send({
        'from': os.environ.get('EMITD_FROM_EMAIL', 'hello@yourdomain.com'),
        'to': [user.email],
        'subject': f'Welcome, {user.first_name}!',
        'html_body': f'''
            <h1>Welcome, {user.first_name}!</h1>
            <p>Thanks for signing up.</p>
        ''',
        'tags': {
            'campaign': 'welcome',
            'user_id': str(user.id),
        },
    }, headers=headers)


def send_password_reset(user, reset_token):
    return _send({
        'from': os.environ.get('EMITD_FROM_EMAIL', 'hello@yourdomain.com'),
        'to': [user.email],
        'subject': 'Reset your password',
        'html_body': f'''
            <h1>Password Reset</h1>
            <p>Click the link below to reset your password:</p>
            <a href="https://yourapp.com/reset?token={reset_token}">
                Reset Password
            </a>
            <p>This link expires in 1 hour.</p>
        ''',
        'tags': {'campaign': 'password_reset'},
    })

Timeouts and retries

A requests timeout raises before you see the response — if you retry, send a stable Idempotency-Key (e.g. f"password-reset:{user.pk}") so the retry replays instead of re-sending.

3. Use it in a view

views.py
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from services.email import send_welcome_email
from .models import User


@require_POST
def register(request):
    user = User.objects.create_user(
        email=request.POST['email'],
        password=request.POST['password'],
    )
    send_welcome_email(user, idempotency_key=f"welcome:{user.pk}")
    return JsonResponse({'status': 'ok'})

4. Use Celery for async sending

tasks.py
from celery import shared_task
from services.email import send_welcome_email, send_password_reset


@shared_task
def send_welcome_email_task(user_id):
    from .models import User
    user = User.objects.get(id=user_id)
    send_welcome_email(user, idempotency_key=f"welcome:{user.id}")


@shared_task
def send_password_reset_task(user_id, token):
    from .models import User
    user = User.objects.get(id=user_id)
    send_password_reset(user, token)

5. Environment variables

export EMITD_API_KEY=esk_live_...
export EMITD_FROM_EMAIL=hello@yourdomain.com

Next steps

  • Verify your domain before production sends.
  • Test mode — test_mode: true plus delivered@relay.dev simulates a send without SES.
  • Webhooks — verify signatures against the raw body (Django gives you request.body).

On this page