Pranor Notify

docker run -p 8091:8091 ghcr.io/vyuvaraj/pranor-notify:latest

Pranor Notify is the transactional email and deliverability management service for the Pranor ecosystem. It handles sending, receiving, bounce management, unsubscribe compliance, DMARC enforcement, and provides a rich templating DSL and delivery analytics.


Table of Contents


Key Features

📤 Sending

  • Transactional email API: Simple REST API to send emails with HTML/plain text body, attachments, CC/BCC
  • SMTP relay integration: Route outgoing mail through your own SMTP relay (Postfix, SendGrid, AWS SES, Mailgun)
  • Template rendering: Render emails from reusable templates with the Pranor Notify DSL

📥 Inbound Routing

  • Inbound email webhook router: Route inbound emails to HTTP endpoints based on configurable rules (match by From, Subject, header patterns, or recipient address)
  • Rule-based routing: Priority-ordered rules with regex matching; fallback default handler

📝 Template Engine DSL

  • Variable interpolation: {{ user.name }}, {{ order.total }}
  • Conditionals: {% if user.verified %} ... {% endif %}
  • Loops: {% for item in order.items %} ... {% endfor %}
  • Partials / includes: {% include "components/footer.html" %}
  • Layouts: Extend base layouts for consistent header/footer across templates

📊 Bounce & Complaint Management

  • Automatic suppression list: Bounced and complained addresses are automatically added to a suppression list; future sends are blocked
  • Bounce classification: Distinguishes hard bounces (invalid address) from soft bounces (mailbox full) — hard bounces are immediately suppressed, soft bounces retry with backoff
  • Webhook callbacks: Configure webhooks for bounce, complaint, and delivery events
  • Retry policies: Configurable retry count and backoff strategy for soft bounces

🔒 DMARC & Deliverability

  • DMARC policy enforcement: Check incoming mail against sender's DMARC DNS record; reject, quarantine, or report non-compliant messages
  • SPF/DKIM alignment checking: Validate SPF and DKIM headers are aligned with the From: domain
  • DMARC aggregation reports (RUA): Generate and send periodic DMARC aggregate reports to the domain owner's rua address
  • Deliverability scoring: Pre-send score estimation based on SPF/DKIM/DMARC alignment, suppression list checks, and content scoring

✅ Compliance

  • One-click unsubscribe (RFC 8058): List-Unsubscribe-Post header injected on all bulk emails; honor unsubscribe POSTs from email clients (Gmail, Apple Mail)
  • List management API: Subscribe, unsubscribe, and manage mailing list membership; segmentation support
  • Automatic unsubscribe link injection: Pranor Notify injects a unique unsubscribe link in every outgoing email footer

📈 Analytics

  • Delivery analytics telemetry: Per-campaign delivery rates, open rates, click rates, bounce rates, complaint rates
  • Per-recipient event tracking: Track individual recipient events (delivered, opened, clicked, bounced, unsubscribed)
  • Pranor Console dashboard integration: Live analytics charts for mail campaigns

Architecture

Outbound Flow:
API Request → Template Render → Deliverability Check → SMTP Relay → Recipient

Inbound Flow:
Inbound SMTP → DMARC/SPF/DKIM Check → Webhook Router → Your HTTP Endpoint

Event Callbacks:
Bounce/Complaint Events → Suppression List + Webhook → Pranor Console Analytics

API Endpoints

MethodPathDescription
POST/api/v1/sendSend a transactional email
POST/api/v1/send/templateSend using a named template
POST/api/v1/templatesCreate/update an email template
GET/api/v1/templatesList all templates
GET/api/v1/templates/{name}Get a template
DELETE/api/v1/templates/{name}Delete a template
GET/api/v1/suppressionList suppressed addresses
POST/api/v1/suppressionManually suppress an address
DELETE/api/v1/suppression/{email}Remove from suppression list
POST/api/v1/inbound/rulesCreate an inbound routing rule
GET/api/v1/inbound/rulesList inbound routing rules
POST/api/v1/listsCreate a mailing list
POST/api/v1/lists/{id}/subscribeSubscribe to a list
POST/api/v1/lists/{id}/unsubscribeUnsubscribe from a list
GET/api/v1/analytics/campaigns/{id}Analytics for a campaign
GET/api/v1/dmarc/reportGenerate DMARC aggregate report
/healthzGETLiveness probe

Template DSL

Create a template:

curl -X POST http://pranor-notify:8091/api/v1/templates \
  -d '{
    "name": "welcome-email",
    "subject": "Welcome, {{ user.name }}!",
    "html": "<h1>Welcome, {{ user.name }}!</h1>\n{% if user.verified %}<p>Your account is verified.</p>{% endif %}\n{% include \"components/footer.html\" %}"
  }'

Send using the template:

curl -X POST http://pranor-notify:8091/api/v1/send/template \
  -d '{
    "template": "welcome-email",
    "to": "alice@example.com",
    "variables": { "user": { "name": "Alice", "verified": true } }
  }'

DMARC & Deliverability

# Check DMARC policy for a domain
curl http://pranor-notify:8091/api/v1/dmarc/check?domain=example.com

# Generate DMARC aggregate report
curl -X POST http://pranor-notify:8091/api/v1/dmarc/report \
  -d '{"reporting_period": "2026-07", "report_to": "dmarc-reports@example.com"}'

Compliance

Pranor Notify automatically injects unsubscribe headers on bulk sends:

List-Unsubscribe: <https://pranor-notify.yourapp.com/unsubscribe?token=xxx>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

When a mail client (Gmail, Apple Mail) sends the one-click unsubscribe POST, Pranor Notify handles it and suppresses the recipient automatically.


Getting Started

docker run -p 8091:8091 \
  -e PRANOR_NOTIFY_SMTP_HOST=smtp.sendgrid.net \
  -e PRANOR_NOTIFY_SMTP_PORT=587 \
  -e PRANOR_NOTIFY_SMTP_USER=apikey \
  -e PRANOR_NOTIFY_SMTP_PASS=SG.xxxxx \
  -e PRANOR_NOTIFY_FROM_DOMAIN=yourapp.com \
  -e PRANOR_NOTIFY_OTEL_ENDPOINT=http://pranor-trace:4318 \
  ghcr.io/vyuvaraj/pranor-notify:latest

Environment Variables

VariableDefaultDescription
PRANOR_NOTIFY_PORT8091HTTP listener port
PRANOR_NOTIFY_SMTP_HOSTOutbound SMTP relay host
PRANOR_NOTIFY_SMTP_PORT587Outbound SMTP relay port
PRANOR_NOTIFY_SMTP_USERSMTP authentication username
PRANOR_NOTIFY_SMTP_PASSSMTP authentication password
PRANOR_NOTIFY_FROM_DOMAINDefault sending domain
PRANOR_NOTIFY_INBOUND_PORTSMTP port for inbound mail reception
PRANOR_NOTIFY_DMARC_ENABLEDtrueEnable DMARC enforcement
PRANOR_NOTIFY_OTEL_ENDPOINTOpenTelemetry collector URL