Why Run a Database for Disposable Email? Architecture of a Zero-State Mail Engine

Why Run a Database for Disposable Email? Architecture of a Zero-State Mail Engine

By Reggi, 18 Jul 2026

Most email testing environments are over-engineered sinkholes. Provisioning a full relational database, queuing subsystem, and heavyweight mail transfer agent just to inspect verification codes or capture ephemeral test payloads is an operational anti-pattern. If the lifecycle of a message is inherently short-lived, your persistence layer should reflect that reality directly.

OpenTrashmail strips out this database bloat. It provides a self-hosted, Python-powered mail engine designed around flat-file serialization, headless automation, and catch-all routing.

The Zero-Database Ingestion Architecture

The primary design principle behind OpenTrashmail is absolute decoupling from external databases. The system handles inbound SMTP traffic, writes incoming messages directly to disk as JSON files, and serves them via an integrated web interface or programmatic API.

                  [ Inbound SMTP Traffic (Port 25) ]
                                  │
                                  ▼
                     ┌─────────────────────────┐
                     │   OpenTrashmail Engine  │
                     │     (Python Daemon)     │
                     └────────────┬────────────┘
                                  │
                  ┌───────────────┴───────────────┐
                  ▼                               ▼
       [ Flat-File Storage ]             [ Real-Time Events ]
   (JSON Documents / Attachments)                 │
                  │                   ┌───────────┴───────────┐
                  ▼                   ▼                       ▼
           [ REST / JSON API ]   [ RSS Feeds ]     [ HMAC Webhooks ]

Because it operates as an open catch-all system, there is no requirement to seed accounts ahead of time. Any incoming payload addressed to a configured domain is accepted, parsed, and indexed on the filesystem instantly. This removes the state synchronization problem entirely when spinning up thousands of ephemeral test accounts during end-to-end integration runs.

Beyond standard catch-all duties, this architecture serves cleanly as an email honeypot or as an automated two-factor authentication (2FA) verification solver in CI/CD pipelines.

API Integration Surface

Headless systems require precise control over ingested messages. OpenTrashmail exposes endpoints to extract raw source data, isolate MIME attachments, or consume fully structured JSON objects.

EndpointMethod / TypeFunctionality
/rss/[email-address]XML FeedReal-time RSS updates for an isolated inbox.
/api/raw/[email-address]/[id]Raw SourceReturns the untouched RFC-compliant email body.
/api/attachment/[email-address]/[id]Binary / MIMEDelivers stored file attachments with correct MIME headers.
/api/delete/[email-address]/[id]MutationPurges an individual message and its linked attachments.
/api/deleteaccount/[email-address]MutationDrops an entire account along with all associated files.
/json/[email-address]JSON PayloadLists account emails with parsed text and attachment links. When authenticated as admin, returns the global mailbox.
/json/[email-address]/[id]JSON PayloadReturns complete message metadata, including HTML and raw formats.
/json/listaccountsJSON PayloadDumps all active addresses that have ingested mail (requires SHOW_ACCOUNT_LIST=true).
/api/webhook/get/[email-address]Config QueryInspects current webhook parameters for a targeted address.
/api/webhook/save/[email-address]Config MutationPersists endpoint, retry, and templating rules for an address.
/api/webhook/delete/[email-address]Config MutationUnregisters an active webhook integration.

Webhook Pipelines with HMAC Verification

Pulling APIs on intervals wastes cycles. OpenTrashmail includes an event-driven webhook pipeline that pushes incoming emails to external listeners the moment they hit the SMTP daemon.

Configurations can be applied globally or mapped to individual addresses. The engine supports variable interpolation to structure outbound JSON payloads before transmission.

                    ┌─────────────────────────┐
                    │ Incoming Email Parsed   │
                    └────────────┬────────────┘
                                 │
                   ┌─────────────┴─────────────┐
                   │ Format Template & Headers │
                   │  - {{to}}, {{subject}}    │
                   │  - X-Webhook-Signature    │
                   └─────────────┬─────────────┘
                                 │
                                 ▼
                    ┌─────────────────────────┐
                    │ Outbound POST Request   │
                    └────────────┬────────────┘
                                 │
                        [ Success? (200 OK) ]
                           ╱               ╲
                         YES                NO
                         ╱                   ╲
                   ┌────────┐       ┌──────────────────────┐
                   │ Finish │       │ Exponential Backoff  │
                   └────────┘       │   (Up to 10 Retries) │
                                    └──────────────────────┘

Available template variables include:

  • {{to}}
  • {{from}}
  • {{subject}}
  • {{body}}
  • {{attachments}}

Provisioning an Automated Ingestion Pipeline

To configure an endpoint with signing and retry policies, dispatch a payload to the webhook configuration route:

bash
curl -X POST http://localhost:8080/api/webhook/save/test@example.com \ -d "enabled=true" \ -d "webhook_url=https://myapi.com/webhook" \ -d 'payload_template={"email":"{{to}}","subject":"{{subject}}"}' \ -d "max_attempts=5" \ -d "secret_key=your-secret-key"

When a secret_key is supplied, OpenTrashmail calculates an HMAC-SHA256 digest across the request payload and injects it into the X-Webhook-Signature header. The downstream consumer must calculate the same digest over the incoming raw body using the shared secret to verify transport authenticity. If downstream delivery fails, the dispatcher executes an exponential backoff loop, supporting up to 10 retry attempts.

Configuration Parameters

All system behaviors are exposed through config.ini or environment variables:

  • DOMAINS: Comma-delimited list of domains accepted by the SMTP listener.
  • MAILPORT: Network port bound by the Python SMTP service (default: 25).
  • URL: Base public URL exposed by the web UI.
  • ADMIN: Designated address with administrative visibility across all stored mailboxes.
  • PASSWORD: Global credential gate protecting UI and API access.
  • ALLOWED_IPS: CIDR blocks allowed to communicate with UI and API routes.
  • ATTACHMENTS_MAX_SIZE: Threshold in bytes for inbound attachment writes.
  • TLS_CERTIFICATE / TLS_PRIVATE_KEY: Filesystem paths to TLS assets. The server supports Plaintext, STARTTLS, and TLS on Connect. Development certificates can be created directly via openssl.

Production Deployment with Docker

Deploying a containerized instance with persistent local storage, custom date formatting, automated purging, and explicit domain bindings requires a single runtime declaration:

bash
docker run -d --restart=unless-stopped --name opentrashmail \ -e "DOMAINS=mydomain.eu" \ -e "DATEFORMAT='D.M.YYYY HH:mm'" \ -e "DISCARD_UNKNOWN=false" \ -e "DELETE_OLDER_THAN_DAYS=90" \ -p 80:80 -p 25:25 \ -v /path/on/host/where/to/save/data:/var/www/opentrashmail/data \ hascheksolutions/opentrashmail:1

This deployment configuration maps port 25 for inbound SMTP and port 80 for HTTP operations. The DELETE_OLDER_THAN_DAYS=90 directive prevents storage exhaustion by pruning flat-file records older than three months automatically.

Once your domain MX record targets the host interface, the entire ingestion pipeline is operational without database migrations, index maintenance, or background worker dependencies.

Reference


Popular Reads