Sending transactional email from Django, done right
Django's built-in send_mail() goes through an SMTP backend by default, which works but gives you none of the delivery visibility an API-based provider offers: no webhook events, no structured bounce handling, no per-message status you can query later. Routing transactional sends through Envello's HTTP API instead is a small, contained change.
The plain HTTP version
This works in any Django view or task runner without adding a dependency, using the requests library most Django projects already have. The essentials:
- import requests
- response = requests.post('https://api.envello.dev/emails', headers={'Authorization': f'Bearer {settings.ENVELLO_API_KEY}'}, json={'from': 'Acme <[email protected]>', 'to': user.email, 'subject': 'Welcome!', 'html': rendered_html})
- response.raise_for_status() to surface a failed send instead of silently swallowing it
Rendering the email body
Django's own template engine (render_to_string with an .html template) works fine for the html field, no extra tooling needed. If you're already using Django templates for your web pages, reuse that same rendering path for transactional email content rather than introducing a second templating system.
If you want an SDK instead of raw requests
A Python SDK exists (packages/sdk-python in Envello's repo, pip install envello), but it's honest to say it isn't published to PyPI yet, install it from the local path or git source for now if you want the typed client and built-in request validation. For most Django integrations, the plain requests call above is simple enough that waiting for a published package isn't a blocker.
Where this fits in a Django project
Wrap the send call in a small function in a shared module (emails.py or similar), call it from signals, views, or a Celery task depending on whether the send needs to happen synchronously. For anything triggered by a web request (password reset, signup confirmation), a background task queue is worth it so a slow API response doesn't hold up the HTTP response to your user.