NAMETS uses n8n for automated email notifications triggered by platform events. Rather than running background tasks inside Django, the platform exposes a lightweight REST API that an n8n workflow polls on a schedule. When new announcements are published or upcoming events are detected, n8n fetches the data, retrieves the list of active subscribers, and dispatches personalized emails — all without any code changes on the Django side. This architecture keeps the web server stateless and lets the notification logic be edited visually inside n8n.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Muhammadbugaje/NAMETS_Website/llms.txt
Use this file to discover all available pages before exploring further.
Authentication: N8NAuthentication
All API endpoints consumed by n8n are protected by a custom DRF authentication class defined in utils/auth.py. The class reads a token from the X-N8N-Token HTTP header and compares it against the N8N_API_TOKEN setting. If the header is absent or the value does not match, the request is rejected immediately.
return (None, None) signals to DRF that the request is authenticated but has no associated Django user object. This is intentional — n8n is a machine client, not a human user.Environment Variables
A long-lived API token generated inside your n8n instance (Settings → n8n API → Create API Key). The NAMETS platform reads this from
settings.N8N_API_TOKEN and validates every inbound API request against it. Must be identical on both the n8n side (stored as a credential) and the NAMETS side (stored as an environment variable).The full URL of the n8n webhook endpoint that NAMETS posts outbound events to. Declared in
render.yaml with a default pointing to the Render-hosted n8n service. Override this if you run n8n on a different host.A shared secret included in outbound webhook payloads from NAMETS to n8n. The n8n workflow should verify this value before processing the payload to prevent spoofed requests.
REST API Endpoints
n8n workflows call the following read-only endpoints. All endpoints require theX-N8N-Token header.
| Method | Path | Description |
|---|---|---|
GET | /api/subscribers/ | Returns all active subscribers. Filter by ?announcements=1, ?events=1, or ?prayer=1 to get only those who opted into a specific notification type. |
GET | /api/announcements/new/ | Returns announcements published after a given timestamp. Pass ?since=<ISO8601> to narrow results. Defaults to the last 24 hours if since is omitted. |
GET | /api/events/upcoming/ | Returns events starting within the next N days. Pass ?days=<int> (default: 7). |
GET | /api/prayer/today/ | Returns the prayer schedule for the current day. |
Calling the API from n8n
Use an HTTP Request node in your n8n workflow. Set the method toGET, add the X-N8N-Token header under Headers, and optionally append query parameters.
Typical n8n Announcement Notification Workflow
Schedule trigger
Add a Schedule trigger node set to run every 15–60 minutes (or on a cron expression that matches your posting frequency).
Fetch new announcements
Add an HTTP Request node that calls
GET /api/announcements/new/ with a dynamic since timestamp. Use an expression like {{ $now.minus(1, 'hour').toISO() }} for the since parameter.Check if announcements exist
Add an IF node. If the response array is empty, stop the workflow. If it contains items, proceed to the next step.
Fetch active subscribers
Add a second HTTP Request node that calls
GET /api/subscribers/?announcements=1 to retrieve all subscribers who opted into announcement notifications.notify_announcements Management Command
The platform also ships a Django management command as a Django-native alternative to the n8n polling approach. It can be run via python manage.py notify_announcements or scheduled with a cron job.
How notify_announcements works
How notify_announcements works
The command queries for all active, currently-live announcements (those where The n8n workflow approach is preferred for production because it avoids the need for a persistent cron daemon and provides a visual audit trail of every notification run.
publish_at ≤ now and expire_at ≥ now), limited to 5 for the initial implementation. It then fetches all active subscribers who have notify_announcements=True and calls send_notification_email() for each one, rendering the emails/new_announcements.html template with the announcement list and an unsubscribe URL.