dj-brevo
Django integration for Brevo (formerly Sendinblue) - transactional emails and contact management.
Installation
pip install dj-brevo
Quick Start
- Add to your
INSTALLED_APPS:
INSTALLED_APPS = [
...
"dj_brevo",
]
- Configure your Brevo API key:
DJ_BREVO = {
"API_KEY": "your-brevo-api-key",
"DEFAULT_FROM_EMAIL": "noreply@yourdomain.com",
}
- Run migrations:
python manage.py migrate dj_brevo
- Set the email backend (optional):
EMAIL_BACKEND = "dj_brevo.backends.BrevoEmailBackend"
Sending Emails
Using Django's Email Functions
from django.core.mail import send_mail
send_mail(
subject="Welcome!",
message="Thanks for signing up.",
from_email="hello@yourdomain.com",
recipient_list=["user@example.com"],
)
Using Brevo Templates
Send emails using templates created in Brevo's dashboard:
from dj_brevo.services import BrevoClient
client = BrevoClient()
client.send_template_email(
to=[{"email": "user@example.com", "name": "David"}],
template_id=12,
params={"firstName": "David", "orderTotal": "$50"},
)
Contact Management
Models
dj-brevo provides Django models for managing Brevo contacts, lists, and attributes locally:
from dj_brevo.models import BrevoContact, BrevoList, BrevoAttribute
# Create a contact
contact = BrevoContact.objects.create(
email="user@example.com",
attributes={"FIRSTNAME": "David", "MRR": 99.99},
)
# Create a list (auto-syncs to Brevo when AUTO_SYNC=True)
newsletter = BrevoList.objects.create(
name="Newsletter",
folder_id=1, # Required for Brevo sync
)
# Add contact to list
contact.lists.add(newsletter)
# Create an attribute (auto-syncs to Brevo when AUTO_SYNC=True)
attr = BrevoAttribute.objects.create(
name="SUBSCRIPTION_STATUS",
attribute_type="text",
category="normal",
)
Auto-Sync
When AUTO_SYNC is enabled (default), BrevoList and BrevoAttribute models automatically sync to Brevo on save:
- BrevoList: Creates/updates the list in Brevo, stores the returned
brevo_id - BrevoAttribute: Creates the attribute in Brevo, marks
brevo_synced=True
Contacts do not auto-sync - use the API client directly for contact operations.
Direct API Access
For full control, use the BrevoClient directly:
from dj_brevo.services import BrevoClient
client = BrevoClient()
# Contacts
client.create_contact(email="user@example.com", attributes={"FIRSTNAME": "David"})
client.get_contact("user@example.com")
client.update_contact(identifier="user@example.com", attributes={"MRR": 150})
# Lists
client.get_lists()
client.create_list(name="Newsletter", folder_id=1)
client.add_contacts_to_list(list_id=5, emails=["user@example.com"])
client.remove_contacts_from_list(list_id=5, emails=["user@example.com"])
# Attributes
client.get_attributes()
client.create_attribute(
attribute_name="MRR",
attribute_type="float",
attribute_category="normal",
)
Configuration
All settings are optional except API_KEY:
DJ_BREVO = {
# Required
"API_KEY": "your-brevo-api-key",
# Optional
"DEFAULT_FROM_EMAIL": "noreply@yourdomain.com",
"TIMEOUT": 10, # Request timeout in seconds
"API_BASE_URL": "https://api.brevo.com/v3", # Override for testing
"SANDBOX": False, # Enable sandbox mode for testing
"AUTO_SYNC": True, # Auto-sync lists/attributes to Brevo on save
}
Disabling Auto-Sync
To manually control when data syncs to Brevo:
DJ_BREVO = {
"API_KEY": "your-brevo-api-key",
"AUTO_SYNC": False,
}
This is recommended for tests to prevent API calls.
Sandbox Mode
Use sandbox mode to test your integration without sending actual emails:
DJ_BREVO = {
"API_KEY": "your-brevo-api-key",
"SANDBOX": True, # Emails won't be sent
}
In sandbox mode:
- No emails are sent to recipients
- No email logs are created in your Brevo account
- You receive a success response with a
messageIdconfirming the API is working
This is useful for automated testing and CI/CD pipelines.
Requirements
- Python 3.12+
- Django 5.0+
License
MIT
Metadata
Release files for dj-brevo 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dj_brevo-0.3.2.tar.gz | 20.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dj_brevo-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.9 kB
Release files / dj_brevo-0.3.2.tar.gz
| Download URL | dj_brevo-0.3.2.tar.gz |
|---|---|
| Size | 20.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bfdcfd27a9ed0eea3d970115982c078624f361c2a5f8a9e2883d7b0f8fdca2dc
|
|
BLAKE2b-256 checksum How to use checksums |
f8f2a1424977e4501697d1f9c9c8e701f6700eabe6a431ce28a5fc0ae8456ce8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 17, 2026.
Transparency logRelease files / dj_brevo-0.3.2-py3-none-any.whl
| Download URL | dj_brevo-0.3.2-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1aaa74696a442d90cc40211097234a4e14c0bbad9f9669c08563a65d55e15a91
|
|
BLAKE2b-256 checksum How to use checksums |
df75789522e13bb3d6c58c7504418d605712bf947c077184fb62a0a207598127
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 17, 2026.
Transparency log