Using the Django Package
The django-notifiedby package provides a Python interface for the NotifiedBy API, including
full support for email flows, recipients, and flags. This page covers how to set up the package
and use it to manage email flows from your Django application.
Installation
pip install django-notifiedby
pip install requests
Configuration
Add the following to your Django settings.py:
INSTALLED_APPS = [
# ... your other apps
'notifiedby',
]
EMAIL_BACKEND = "notifiedby.NotifiedByEmailBackend"
NOTIFIEDBY_API_KEY = "YOUR_API_KEY"
Note
Setting EMAIL_BACKEND makes NotifiedBy the default backend for all Django email sending,
including send_mail(). This is optional if you only want to use the flow and recipient
functions.
If you use custom encryption keys for email content, also add:
NOTIFIEDBY_ENCRYPTION_KEY = "your-encryption-key"
The API key and encryption key will be read automatically from your Django settings by all package functions.
Subscribing to a Flow
Use subscribe_to_flow() to add a recipient to an email flow. The recipient will be created
automatically if they don’t already exist.
from notifiedby import subscribe_to_flow
subscribe_to_flow(
flow_trigger='WELCOME_SIGNUP',
email='user@example.com',
first_name='John',
last_name='Doe',
flags=['new_user', 'free_plan']
)
Parameter |
Required |
Description |
|---|---|---|
flow_trigger |
Yes |
The trigger keyword of the flow. |
Yes |
The recipient’s email address. |
|
first_name |
No |
The recipient’s first name. |
last_name |
No |
The recipient’s last name. |
flags |
No |
A list of flag names to set on the recipient. |
client |
No |
A custom |
A common pattern is to subscribe users when they sign up, using a Django signal:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from notifiedby import subscribe_to_flow
@receiver(post_save, sender=User)
def on_user_created(sender, instance, created, **kwargs):
if created:
subscribe_to_flow(
flow_trigger='WELCOME_SIGNUP',
email=instance.email,
first_name=instance.first_name,
last_name=instance.last_name,
)
Unsubscribing from a Flow
Use unsubscribe_from_flow() to stop a recipient from receiving further emails in a flow.
from notifiedby import unsubscribe_from_flow
unsubscribe_from_flow(
flow_trigger='WELCOME_SIGNUP',
email='user@example.com'
)
Listing Flow Subscriptions
Use list_flow_subscriptions() to retrieve all flow subscriptions for your team. Results are
paginated.
from notifiedby import list_flow_subscriptions
result = list_flow_subscriptions(page=1)
print(f"Total subscriptions: {result['count']}")
for sub in result['results']:
print(f"{sub['recipient_email']} - {sub['flow_name']} ({sub['status']})")
Each subscription in the results contains:
Field |
Description |
|---|---|
id |
The subscription ID. |
flow_name |
The human-readable name of the flow. |
flow_trigger |
The trigger keyword of the flow. |
recipient_email |
The subscribed recipient’s email address. |
status |
One of |
current_step_order |
The current step number in the sequence. |
next_send_date |
When the next step will be processed. |
created_at |
When the subscription was created. |
updated_at |
When the subscription was last updated. |
Deleting All Subscriptions
Use delete_all_subscriptions() to remove all flow subscriptions for your team.
from notifiedby import delete_all_subscriptions
delete_all_subscriptions()
Warning
This deletes all subscriptions for your team and cannot be undone. Use with caution.
Managing Recipients
You can create and list recipients independently of flows.
Creating a Recipient
from notifiedby import create_recipient
recipient = create_recipient(
email='user@example.com',
first_name='John',
last_name='Doe',
flags=['premium', 'active']
)
If a recipient with that email already exists, their details will be updated.
Listing Recipients
from notifiedby import list_recipients
recipients = list_recipients()
for r in recipients:
print(f"{r['email']} - {r['first_name']} {r['last_name']}")
Managing Recipient Flags
Flags let you tag recipients for segmentation and flow branching. You can set and clear flags at any time.
Setting Flags
from notifiedby import set_recipient_flags
set_recipient_flags(
email='user@example.com',
flags=['premium', 'onboarded']
)
Clearing Flags
from notifiedby import clear_recipient_flags
clear_recipient_flags(
email='user@example.com',
flags=['trial']
)
Querying Sent Emails
The package also provides functions to query emails that have been sent.
from notifiedby import get_email_detail, list_emails, get_delivery_status
# Get details of a specific email by ID
email = get_email_detail(email_id='JDT')
# List sent emails (paginated)
emails = list_emails(page=1)
# Get delivery status of a specific email
status = get_delivery_status(email_id='JDT')
Error Handling
All functions raise exceptions from the notifiedby.exceptions module when something goes wrong.
from notifiedby import subscribe_to_flow
from notifiedby.exceptions import (
NotifiedByError,
NotifiedByConfigError,
NotifiedByAPIError,
NotifiedByValidationError,
NotifiedByAuthError,
NotifiedByNotFoundError,
)
try:
subscribe_to_flow(
flow_trigger='WELCOME_SIGNUP',
email='user@example.com',
)
except NotifiedByConfigError:
# Missing API key in Django settings
print("Check your NOTIFIEDBY_API_KEY setting")
except NotifiedByValidationError as e:
# Bad request (400) - e.g. flow not found, already subscribed
print(f"Validation error: {e}")
except NotifiedByAuthError:
# Authentication failed (401/403)
print("Invalid API key or feature not enabled")
except NotifiedByNotFoundError:
# Resource not found (404)
print("Not found")
except NotifiedByAPIError as e:
# Other API error
print(f"API error ({e.status_code}): {e}")
except NotifiedByError:
# Network or other error
print("Something went wrong")
The exception hierarchy:
NotifiedByError– Base exception for all errors.NotifiedByConfigError– Missing or invalid configuration (e.g. no API key).NotifiedByAPIError– An error response from the API.NotifiedByValidationError– HTTP 400 (bad request).NotifiedByAuthError– HTTP 401 or 403 (authentication/authorisation failure).NotifiedByNotFoundError– HTTP 404 (resource not found).
Using a Custom Client
By default, all functions create a NotifiedByClient that reads your API key from Django
settings. You can pass a custom client if you need to use a different API key or base URL
(useful for testing or multi-tenant setups).
from notifiedby import NotifiedByClient, subscribe_to_flow
client = NotifiedByClient(
api_key='your-other-api-key',
base_url='http://localhost:8000'
)
subscribe_to_flow(
flow_trigger='WELCOME_SIGNUP',
email='test@example.com',
client=client
)
All flow, recipient, and flag functions accept an optional client parameter.
Complete Example
Here is a complete example showing a typical integration – subscribing users on signup, managing flags when they upgrade, and unsubscribing when they cancel.
from notifiedby import (
subscribe_to_flow,
unsubscribe_from_flow,
set_recipient_flags,
clear_recipient_flags,
)
# When a user signs up
def on_user_signup(user):
subscribe_to_flow(
flow_trigger='WELCOME_SIGNUP',
email=user.email,
first_name=user.first_name,
last_name=user.last_name,
flags=['free_plan'],
)
# When a user upgrades to premium
def on_user_upgrade(user):
set_recipient_flags(email=user.email, flags=['premium'])
clear_recipient_flags(email=user.email, flags=['free_plan'])
subscribe_to_flow(
flow_trigger='PREMIUM_ONBOARDING',
email=user.email,
)
# When a user cancels
def on_user_cancel(user):
unsubscribe_from_flow(
flow_trigger='PREMIUM_ONBOARDING',
email=user.email,
)
subscribe_to_flow(
flow_trigger='REENGAGE_INACTIVE',
email=user.email,
)