Documentation

Everything you need to deploy, configure, and use ZenoMail.

Getting Started

ZenoMail can be deployed using Docker Compose in minutes. Here's what you need:

Prerequisites

  • Docker and Docker Compose
  • SMTP credentials or Microsoft 365 tenant
  • PostgreSQL (included in Docker Compose)

Quick Start

# Download and extract wget https://zenomail.io/releases/latest/zenomail.tar.gz tar -xzf zenomail.tar.gz && cd zenomail cp .env.example .env docker-compose up -d # Access the dashboard open http://localhost:3000

Configuration

ZenoMail is configured via environment variables. Key settings:

# Database DATABASE_URL=postgres://user:pass@localhost:5432/zenomail # SMTP Provider SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=your-user SMTP_PASS=your-password # Microsoft Graph (alternative to SMTP) GRAPH_TENANT_ID=your-tenant-id GRAPH_CLIENT_ID=your-client-id GRAPH_CLIENT_SECRET=your-secret # Security JWT_SECRET=your-secure-random-string ENCRYPTION_KEY=32-byte-hex-string

API Reference

ZenoMail provides a RESTful API with OpenAPI documentation available at /api/docs.

Send Email

POST /api/v1/send Authorization: Bearer {api_key} Content-Type: application/json { "to": ["user@example.com"], "cc": ["manager@example.com"], "bcc": ["archive@example.com"], "template_key": "welcome-email", "data": { "name": "John", "company": "Acme Inc" }, "reply_to": "support@example.com", "list_unsubscribe": "https://example.com/unsubscribe", "scheduled_at": "2025-01-15T10:00:00Z" }

Batch Send

POST /api/v1/send/batch Authorization: Bearer {api_key} Content-Type: application/json { "template_key": "newsletter", "recipients": [ {"to": "user1@example.com", "data": {"name": "Alice"}}, {"to": "user2@example.com", "data": {"name": "Bob"}}, // ... up to 1000 recipients ] }

Templates

ZenoMail supports Handlebars and Liquid templates with Git-like versioning.

Handlebars Example

<h1>Welcome, {{name}}!</h1> {{#if premium}} <p>Thanks for being a premium member.</p> {{else}} <p>Upgrade to premium for more features.</p> {{/if}} {{#each items}} <li>{{this.name}} - ${{this.price}}</li> {{/each}}

Template Versioning

  • Draft branch: Edit and preview without affecting production
  • Publish: Promote draft to production with one click
  • History: View all versions with commit messages
  • Rollback: Instantly revert to any previous version

Webhooks

Get notified about email delivery events in real-time.

Events

  • email.delivered: Email successfully delivered
  • email.failed: Delivery failed (with error details)
  • email.bounced: Hard bounce detected (550 errors)

Payload Example

{ "event": "email.delivered", "timestamp": "2025-01-06T12:00:00Z", "data": { "message_id": "msg_abc123", "recipient": "user@example.com", "template_key": "welcome-email" }, "signature": "sha256=..." }

SMTP Server

ZenoMail includes a built-in SMTP server for applications that prefer SMTP protocol over HTTP APIs.

Configuration

# SMTP Server Environment Variables SMTP_LISTEN_ADDR=:587 # STARTTLS port SMTP_TLS_LISTEN_ADDR=:465 # Implicit TLS port SMTP_DOMAIN=mail.yourdomain.com SMTP_AUTO_TLS=true # Auto-generate dev certs SMTP_TLS_CERT=/path/to/cert # Or provide your own SMTP_TLS_KEY=/path/to/key

Authentication

Authenticate using SASL PLAIN with your tenant API key:

  • Username: Tenant slug (or omit)
  • Password: API key (zeno_live_...)

Sending via SMTP

# Basic email swaks --to user@example.com \ --from sender@yourdomain.com \ --server localhost:587 \ --auth PLAIN \ --auth-user tenant-slug \ --auth-password zeno_live_xxx \ --tls \ --body "Hello from ZenoMail!" # Using templates via headers swaks --to user@example.com \ --server localhost:587 \ --auth PLAIN --auth-password zeno_live_xxx \ --tls \ --header "X-Zenomail-Template: welcome-email" \ --header 'X-Zenomail-Data: {"name": "John"}'

Custom Headers

  • X-Zenomail-Template: Template key to use
  • X-Zenomail-Data: JSON object with template variables
  • X-Zenomail-Schedule: RFC3339 timestamp for scheduled delivery
  • X-Zenomail-Reply-To: Reply-To address
  • X-Zenomail-List-Unsubscribe: Unsubscribe URL

Multi-Tenant

ZenoMail supports complete tenant isolation for SaaS and agency use cases.

Tenant Features

  • Separate API keys per tenant
  • Per-tenant email providers
  • Isolated templates and logs
  • Per-tenant encryption keys (crypto-shredding)
  • Centralized admin dashboard