📨
v1.0.0 Last updated: March 2026

Documentation

Everything you need to install, configure, and integrate EmailFilter into your existing mail infrastructure.

EmailFilter is a lightweight, self-hosted containerized API service that helps you verify and filter email addresses without compromising privacy. By performing all checks locally, your data never leaves your infrastructure.

Install

Requirements

  • Docker and Docker Compose
  • TCP_OUT port 43 open (for WHOIS checks)

Run the following command to get started:

git clone https://github.com/stefanpejcic/emailfilter emailfilter && \
            cd emailfilter && docker compose build --no-cache && docker compose up -d

The service is now available at http://localhost:8000.

API Usage

Check Email

curl -X POST "http://localhost:8000/filter-email" \
     -H "Content-Type: application/json" \
     -d '{"email": "[email protected]"}'
View JSON Response Example
{
    "email": "[email protected]",
    "domain": "example.com",
    "disposable": false,
    "blacklisted": false,
    "mx_exists": true,
    "gibberish": false,
    "smtp_valid": true,
    "new_domain": false,
    "domain_age_in_days": 3650,
    "spam_keywords": false,
    "reputation_penalty": 0,
    "score": 95,
    "verdict": "accepted"
}

Add domain to whitelist

curl -X POST "http://localhost:8000/whitelist?domain=example.com"

Remove domain from whitelist

curl -X DELETE "http://localhost:8000/whitelist?domain=example.com"

Add domain to blacklist

curl -X POST "http://localhost:8000/blacklist?domain=example.com"

Remove domain from blacklist

curl -X DELETE "http://localhost:8000/blacklist?domain=example.com"

View all lists

curl -X GET "http://localhost:8000/lists"

View a specific list

curl -X GET "http://localhost:8000/lists/"

Delete a specific list

curl -X DELETE "http://localhost:8000/lists/"

Report as spam

curl -X POST "http://localhost:8000/feedback/spam" \
     -H "Content-Type: application/json" \
     -d '{"email": "[email protected]"}'

List scores

curl -X GET "http://localhost:8000/scores"

Update scores

Customize the weights of each check to fit your security requirements.

curl -X POST http://localhost:8000/scores \
  -H "Content-Type: application/json" \
  -d '{
    "base": 40,
    "mx_exists": 25,
    "new_domain": -10,
    "smtp_valid": 15,
    "disposable": -25,
    "blacklisted": -50
    "whitelisted": 50,
    "spam_keywords": -40
  }'

Restore default scores

curl -X POST http://localhost:8000/scores/default

Update disposable domains list

wget -O lists/disposable_domains.txt https://stefanpejcic.github.io/disposable-email-domains/domains.txt

Display all available endpoints

curl http://localhost:8000/

Display help information for endpoints

curl http://localhost:8000/help/

Exim Outgoing Email Verification

Verify outgoing emails before delivery to reduce bounces and protect your IP reputation.

Requirements

  • Exim4 running as an SMTP server (receiving mail)
  • emailfilter service running locally and accessible on http://localhost:8000
  • Internet access from the machine (for DNS & MX lookups)
1

Edit Exim Configuration

Add this router before your remote delivery routers (usually dnslookup):

emailfilter_verify:
  debug_print = "R: emailfilter_verify for $local_part@$domain"
  driver = redirect
  condition = ${run{/usr/local/bin/emailfilter-check.sh $local_part@$domain}{$value}fail}
  data = :blackhole:
2

Setup Helper Script

Deploy the verification script and set executable permissions:

chmod +x /usr/local/bin/emailfilter-check.sh
3

Verification & Logs

Send a test mail and monitor /var/log/exim4/mainlog for the debug_print output:

sendmail [email protected]

Pro Tip:

Change data = :blackhole: to data = :fail: [Message] to notify the sender of rejection.


Exim Incoming Email Filtering

Reject bad senders at the RCPT stage to minimize resource usage.

Requirements

  • Exim running as an SMTP server (receiving mail)
  • emailfilter service running locally and accessible on http://localhost:8000
  • Exim compiled with support for ACLs
1

Configure ACL Block

Add these rules to your acl_check_rcpt block in your Exim configuration:

warn
  set acl_m0 = ${run{/usr/local/bin/emailfilter-check.sh $sender_address}{$value}fail}

deny
  condition = ${if eq{$acl_m0}{} {yes}{no}}
  message = Sender address <$sender_address> rejected by emailfilter.
2

Deploy Check Script

Ensure the helper script is present at the defined path:

/usr/local/bin/emailfilter-check.sh
3

SMTP Interaction Test

Verify the rejection works via manual SMTP (telnet/swaks). Expected response:

550 Sender address <[email protected]> rejected by emailfilter verification.

Proxmox Mail Gateway

Enterprise-grade integration via Postfix Milter for Proxmox clusters.

Requirements

  • Proxmox Mail Gateway 7.x or newer installed and configured
  • emailfilter service running locally and accessible on http://localhost:8000
  • Root or administrative access to your Proxmox Mail Gateway
1

Install PMG Milter Script

Copy scripts/pmg-emailfilter-milter.sh to your gateway:

chmod +x /usr/local/bin/pmg-emailfilter-milter.sh
2

Postfix Integration

Update /etc/postfix/main.cf to include the new milter:

smtpd_milters = unix:/path/to/milter
systemctl restart postfix
3

Monitor Delivery

Tail the mail log to ensure processing is active:

tail -f /var/log/mail.log

Troubleshooting

  • WHOIS Errors: If domain_age_in_days is missing, test connectivity: telnet whois.verisign-grs.com 43.
  • Connection Reset: Ensure port 8000 is open on your host firewall.
  • Empty Reply: Check logs via docker logs -f emailfilter.