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
EMITD_API_KEY = os.environ.get('EMITD_API_KEY')
EMITD_FROM_EMAIL = 'hello@yourdomain.com'2. Create an email service
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
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
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.comNext steps
- Verify your domain before production sends.
- Test mode —
test_mode: trueplusdelivered@relay.devsimulates a send without SES. - Webhooks — verify signatures against the raw
body (Django gives you
request.body).