# Send email from Django

> Send all of Django's email through Vaartix with the vaartix email backend, and verify webhooks in a Django view.

Source: https://vaartix.com/docs/guides/django/

The [Python SDK](https://vaartix.com/docs/sdks/python/) includes a Django email backend, so `send_mail`, `EmailMessage` and Django’s built-in emails (such as password resets) all go through Vaartix. It works with Django 4.2 and later. The source is on GitHub at [vaartix-mail/vaartix-python](https://github.com/vaartix-mail/vaartix-python) and the package is on [PyPI](https://pypi.org/project/vaartix/).

1.  **Install the SDK with the Django extra**

    ```sh
    pip install "vaartix[django]"
    ```

2.  **Set the backend**

    settings.py

    ```python
    import os

    VAARTIX_API_KEY = os.environ["VAARTIX_API_KEY"]
    DEFAULT_FROM_EMAIL = "Acme <noreply@acme.in>"  # on a domain verified in Vaartix

    # Django 6.1 and newer
    MAILERS = {"default": {"BACKEND": "vaartix.django.EmailBackend"}}
    # Django 4.2 to 6.0
    EMAIL_BACKEND = "vaartix.django.EmailBackend"
    ```

    Use the setting that matches your Django version. With `MAILERS` you can pass the key as an option instead: `{"BACKEND": "vaartix.django.EmailBackend", "OPTIONS": {"api_key": "vx_live_..."}}`.

3.  **Send as usual**

    orders/emails.py

    ```python
    from django.core.mail import EmailMultiAlternatives

    message = EmailMultiAlternatives("Order confirmed", "Thanks!", to=["priya@example.com"])
    message.attach_alternative("<p>Thanks!</p>", "text/html")
    message.tags = [{"name": "type", "value": "order"}]  # optional, shown in the dashboard
    message.send()
    print(message.vaartix_id)  # em_...
    ```

    HTML alternatives, attachments, inline images (`Content-ID`), cc, bcc, reply-to and custom headers are supported. Errors raise `VaartixError` unless you pass `fail_silently=True`.

Until your domain is verified, send from `@test.vaartix.com` to `delivered@test.vaartix.com`: see [Test mode](https://vaartix.com/docs/sending/test-mode/).

## Receiving webhooks

Verify the signature against the raw request body:

orders/views.py

```python
import os

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from vaartix import WebhookVerificationError, verify_webhook

@csrf_exempt
@require_POST
def vaartix_webhook(request):
    try:
        event = verify_webhook(request.body, request.headers, os.environ["VAARTIX_WEBHOOK_SECRET"])
    except WebhookVerificationError:
        return HttpResponse(status=400)
    if event["type"] in ("email.bounced", "email.complained"):
        ...  # stop emailing event["data"]["recipient"]
    return HttpResponse(status=200)
```

Webhook requests come from Vaartix, not from a browser form, so the view must be exempt from CSRF protection. The signature check is what keeps it safe.
