Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jtapieromalambo-ctrl/Signia/llms.txt

Use this file to discover all available pages before exploring further.

Signia uses Brevo (formerly Sendinblue) as its transactional email provider through a custom Django email backend located at usuarios/email_backend.py. Rather than routing email through SMTP, the backend sends messages directly to Brevo’s REST API, which is more reliable in serverless and containerised environments where SMTP ports may be blocked or rate-limited. All email-sending behaviour is centralised in this single backend class — no third-party Django packages are required beyond the requests library.

Emails Signia Sends

TriggerDescription
New user registrationA 6-digit OTP verification code (valid for 10 minutes)
Successful registrationA welcome message confirming the account is active
Password changeA confirmation notification after the user updates their password
Password recoveryA recovery link or code to reset a forgotten password

Setting Up Brevo

1

Create a Brevo account

Go to brevo.com and sign up for a free account. The free tier includes 300 emails per day, which is sufficient for development and small production deployments.
2

Generate an API key

In the Brevo dashboard, navigate to Settings → API Keys and click Create a new API key. Give the key a descriptive name (e.g. signia-production). Copy the generated key immediately — Brevo will not show it again.
3

Add the key to your .env

Open your .env file and set BREVO_API_KEY to the value you just copied:
BREVO_API_KEY=xkeysib-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4

Verify your sender email address

In the Brevo dashboard, go to Senders & IP → Senders and add the Gmail address you plan to use as the sender. Brevo requires the sender address to be verified before it will accept outgoing mail from it. Set the same address as EMAIL_HOST_USER in your .env:
EMAIL_HOST_USER=tu_correo@gmail.com

Required Environment Variables

BREVO_API_KEY=xkeysib-...           # REST API key from Brevo dashboard
EMAIL_HOST_USER=tu_correo@gmail.com  # Verified sender address
EMAIL_HOST=smtp-relay.brevo.com      # SMTP relay host (default, can be omitted)
EMAIL_HOST_PASSWORD can be left empty when using the Brevo backend. The custom BrevoEmailBackend authenticates using BREVO_API_KEY via the REST API — it does not establish an SMTP connection and therefore does not use the host password at all.

Email Settings in settings.py

The following email-related settings are defined directly in settings.py. They do not need to be set as environment variables:
EMAIL_BACKEND = 'usuarios.email_backend.BrevoEmailBackend'
EMAIL_PORT     = 465
EMAIL_USE_TLS  = True
EMAIL_USE_SSL  = False
DEFAULT_FROM_EMAIL = 'Signia <osorioescobardavidfelipe@gmail.com>'
EMAIL_HOST and EMAIL_HOST_USER are loaded from environment variables via python-decouple. EMAIL_PORT, EMAIL_USE_TLS, and EMAIL_USE_SSL are hardcoded to the correct values for Brevo’s SMTP relay and do not need to be overridden.

How the Custom Backend Works

The BrevoEmailBackend class in usuarios/email_backend.py extends Django’s BaseEmailBackend and overrides send_messages(). For each EmailMessage object Django passes to it, the backend:
  1. Extracts the plain-text body and, if present, the HTML alternative from msg.alternatives.
  2. Builds a JSON payload matching Brevo’s /v3/smtp/email API format.
  3. POSTs the payload to https://api.brevo.com/v3/smtp/email with the api-key header set to BREVO_API_KEY.
  4. Calls response.raise_for_status() to surface API errors; if fail_silently=True was passed to the backend, exceptions are swallowed.
# usuarios/email_backend.py (simplified)
class BrevoEmailBackend(BaseEmailBackend):
    def send_messages(self, email_messages):
        sent = 0
        for msg in email_messages:
            payload = {
                "sender": {"name": "Signia", "email": "osorioescobardavidfelipe@gmail.com"},
                "to": [{"email": to} for to in msg.to],
                "subject": msg.subject,
                "textContent": msg.body,
            }
            # Attach HTML alternative if present
            for content, mimetype in getattr(msg, 'alternatives', []):
                if mimetype == 'text/html':
                    payload["htmlContent"] = content
            response = requests.post(
                "https://api.brevo.com/v3/smtp/email",
                headers={"api-key": settings.BREVO_API_KEY, "Content-Type": "application/json"},
                json=payload,
                timeout=15,
            )
            response.raise_for_status()
            sent += 1
        return sent
The backend is registered in settings.py as:
EMAIL_BACKEND = 'usuarios.email_backend.BrevoEmailBackend'

OTP Verification Details

When a new user registers, Signia generates a CodigoOTP record with these properties:
PropertyValue
Code length6 digits
Expiry10 minutes from creation
Active codes per user1 (previous codes are invalidated on re-send)
Delivery methodEmail via BrevoEmailBackend
The user must enter the correct code within the 10-minute window to activate their account. Expired or already-used codes are rejected.

Testing Email in Development

During local development you may want to inspect outgoing emails without actually sending them. Switch to Django’s built-in console backend by temporarily setting EMAIL_BACKEND in your shell before starting the server:
# Print all outgoing emails to the terminal instead of sending them
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend python manage.py runserver
Alternatively, add this override directly in your local settings.py (do not commit it):
# Temporary local override — remove before deploying
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
All email content will be printed to the terminal running runserver. Switch back to 'usuarios.email_backend.BrevoEmailBackend' before deploying.
Brevo’s dashboard includes a Logs section under Transactional → Email where you can see delivery status, open rates, and error messages for every email sent through the API. This is the fastest way to diagnose delivery failures in production.

Build docs developers (and LLMs) love