Skip to content

ubachan/Email-Verifier-API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Email Verifier API Logo

🛡️ Email Verifier API

A self-hosted, multi-layer email verification engine built with Flask.

Python Flask n8n License: Personal Use

Built to replace expensive paid services like ZeroBounce or NeverBounce for personal, freelance, and automation workflows.


⚡ What It Does

This API checks every email through 4 distinct layers before it ever reaches your sending queue, protecting your SMTP server and domain reputation. It returns valid, risky, or invalid with a specific reason for each email.

Layer Verification Check Example Catch Action
1 Syntax Validation user@ ❌ Invalid
2 Disposable Domain mailinator.com ❌ Invalid
3 Role-Based Prefix info@, admin@ ⚠️ Risky
4 Live MX + SMTP Check Non-existent mailbox ❌ Invalid

📂 File Structure

├── verify-app.py     # Flask API — core verification logic
├── index.html        # Browser UI — drag-and-drop CSV uploader
├── requirements.txt  # Python dependencies
├── Procfile          # Railway deployment config
└── README.md         # Documentation

🚀 Local Setup

1. Clone the repository

git clone https://github.com/ubachan/Email-Verifier-API.git
cd Email-Verifier-API

2. Create a virtual environment

python3 -m venv venv
source venv/bin/activate        # Mac/Linux
venv\Scripts\activate           # Windows

3. Install dependencies

pip install -r requirements.txt

4. Run the API Engine

python verify-app.py
# → API Running on http://localhost:5050

5. Open the UI (in a separate terminal)

python3 -m http.server 3000
# → Open http://localhost:3000/index.html in your browser

📡 API Reference

1. Upload Leads for Verification

POST /verify

Upload a CSV file for bulk verification. The CSV must have an email column. Other columns are preserved in the final output.

Request:

curl -X POST http://localhost:5050/verify \
  -F "file=@leads.csv"

Response:

{
  "job_id": "abc-123-def"
}

2. Check Job Progress

GET /progress?job_id=<id>

{
  "percent": 72,
  "row": 72,
  "total": 100
}

3. Download Results

GET /download?job_id=<id>&type=<filter>

Download the verified results as a CSV file.

type Parameter Returns
all Every row with status + reason
valid Valid emails only
risky Risky emails only
risky_invalid Risky + Invalid combined

Request:

curl "http://localhost:5050/download?job_id=abc-123&type=valid" -o valid-leads.csv

4. Cancel a Job

POST /cancel?job_id=<id>

Stops a currently running verification process.


☁️ Deploy to Railway (Production)

Deploy this API to the cloud in 3 minutes to use it as a webhook endpoint.

  1. Push this repository to your GitHub.
  2. Go to Railway.appNew ProjectDeploy from GitHub repo.
  3. Select this repository. Railway auto-detects the Procfile.
  4. You get a permanent public URL (e.g., https://your-app.up.railway.app).

⚠️ Critical — Update before deploying:

Change the last line of verify-app.py so it binds to Railway's dynamic port:

# REMOVE THIS:
# app.run(debug=True, port=5050)

# REPLACE WITH THIS:
if __name__ == '__main__':
import os
app.run(debug=False, host='0.0.0.0', port=int(os.environ.get('PORT', 5050)))

🤖 n8n Integration

After deploying to Railway, seamlessly plug this API into your backend automation workflows using the HTTP Request node.

💡 Looking for a ready-made n8n template?
I have built a complete, enterprise-grade automation workflow that uses this exact API alongside OpenAI, Supabase, and Slack. 👉 Get the Advance AI-Powered Lead Management System here

Manual Node Configuration

If you are building your workflow from scratch, set up your n8n HTTP Request node like this:

  • Method: POST
  • URL: https://your-app.up.railway.app/check (Use /verify for CSV files, /check for single JSON emails)
  • Body Type: JSON (or Form-Data for files)

Recommended High-Performance Flow:

[ Code Node: Syntax + Disposable + Role Checks ]
                          ↓
[ HTTP Request: Google DNS API (Fast MX Check) ]
                          ↓
[ HTTP Request: THIS API (Deep SMTP Check) ]
                          ↓
[ Switch/If Node: Route to Valid / Invalid ]

📊 Status Codes & Meanings

Primary Statuses

Status Meaning Recommended Action
🟢 valid Passed all 4 layers of checks Safe to send
🟡 risky Role-based or SMTP timeout Send with caution
🔴 invalid Bad syntax, fake domain, or rejected Do not send

Deep Reason Codes

Reason What happened under the hood
bad_syntax Not a valid email format
disposable_domain Temporary/Trash email service detected
role_based Generic prefix used (e.g., info@, admin@, support@)
no_mx The domain has no active email server
smtp_ok The receiving server confirmed the mailbox exists
smtp_reject The receiving server explicitly rejected the email (550)
smtp_timeout The receiving server took too long to respond
domain_accepts_all Catch-all domain — cannot verify individual mailbox

🛠️ Tech Stack

  • API Server: Python 3 + Flask
  • Resolution: dnspython (MX record routing)
  • Verification: smtplib (SMTP-level mailbox pinging)
  • Frontend: Vanilla JS (Browser UI with drag-and-drop & live progress)

📄 License

Personal Use License — Free to use, modify, distribute, and deploy for personal and educational projects only. Commercial use is strictly prohibited.


📬 Connect with Me


About

A self-hosted email verification API built with Flask. Features multi-layer checks (Syntax, Disposable, MX, SMTP) to eliminate bounce rates in n8n workflows.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors