Disposable Email Score
A robust, explainable risk-scoring engine for email signups. Detects disposable emails, typosquatting attacks, and suspicious domains.
Features
- Disposable Domain Detection — Checks against 113,000+ known disposable email domains
- Typosquatting Detection — Catches fake domains like
gmaiil.com,yahooo.com - MX Record Analysis — Flags domains with missing or suspicious mail servers
- Role Account Detection — Flags shared inboxes like
admin@,info@,sales@ - Subdomain Detection — Blocks
mail.tempmail.comiftempmail.comis blocked - Plus Alias Detection — Detects
user+tag@gmail.compatterns - Allowlist Support — Trusted domains bypass all checks
- Explainable Output — Returns score, decision, signals, and human-readable reasons
🚀 Hosted API (Coming Soon)
Don't want to self-host? We're building a hosted API with:
- Simple REST API — works with any language
- No setup required — get an API key and start
- Always updated blocklist
👉 Join the waitlist to get early access + lifetime discount.
Installation
pip install disposable-email-score
Quick Start
from disposable_email_score import evaluate_email
result = evaluate_email("user@tempmail.xyz")
print(result.model_dump_json(indent=2))
Output
{
"decision": "block",
"score": 0.7,
"thresholds": {
"allow": 0.3,
"block": 0.7
},
"signals": {
"domain_in_blocklist": 0.7
},
"reasons": [
"known_disposable_domain"
]
}
Using RiskLevel
from disposable_email_score import evaluate_email, RiskLevel
result = evaluate_email("test@example.com")
if result.decision == RiskLevel.BLOCK:
print("❌ Blocked!")
elif result.decision == RiskLevel.REVIEW:
print("🟡 Needs review")
else:
print("✅ Allowed")
How It Works
Risk Levels
| Score | Decision | Action |
|---|---|---|
| < 0.3 | allow |
Low risk — let them through |
| 0.3 - 0.69 | review |
Medium risk — require CAPTCHA or verification |
| ≥ 0.7 | block |
High risk — reject signup |
Signals & Weights
| Signal | Weight | Description |
|---|---|---|
domain_in_blocklist |
0.7 | Known disposable domain |
typosquatting |
0.6 | Looks like a typo of gmail.com, yahoo.com, etc. |
mx_risky_or_missing |
0.5 | No MX records or suspicious mail infrastructure |
plus_alias |
0.05 | Uses +tag in local part |
Framework Integration
FastAPI
from fastapi import FastAPI
from disposable_email_score import evaluate_email, RiskResult
app = FastAPI()
@app.get("/check-email", response_model=RiskResult)
def check_email(email: str):
return evaluate_email(email)
Django
from django.http import JsonResponse
from disposable_email_score import evaluate_email
def validate_signup(request):
email = request.GET.get('email')
result = evaluate_email(email)
if result.decision == "block":
return JsonResponse({'error': 'Email not allowed'}, status=400)
return JsonResponse(result.model_dump())
Configuration
All weights and thresholds are in config.py:
THRESHOLD_BLOCK = 0.7
THRESHOLD_REVIEW = 0.3
SCORES = {
"disposable_domain": 0.7,
"typosquatting": 0.6,
"no_mx_records": 0.5,
...
}
Auto-Updates
Domain lists are automatically updated weekly via GitHub Actions from disposable-email-domains.
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
ruff format src/ tests/
# Lint
ruff check src/ tests/
License
MIT
Metadata
Release files for disposable-email-score 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| disposable_email_score-0.1.1.tar.gz | 653.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| disposable_email_score-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / disposable_email_score-0.1.1.tar.gz
| Download URL | disposable_email_score-0.1.1.tar.gz |
|---|---|
| Size | 653.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9df4c2bc13dd6afd22922c5e71b6e556430634eff0748b3ecc4df13d69c96c10
|
|
BLAKE2b-256 checksum How to use checksums |
839584a3d91e9e862a8587b58045963c9cf634ce1db92377648a3b296e927778
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / disposable_email_score-0.1.1-py3-none-any.whl
| Download URL | disposable_email_score-0.1.1-py3-none-any.whl |
|---|---|
| Size | 654.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d433db838cbe5cd45b999ee7cef45fbadd4f71a0cf0fc5feb7e30ae4d63b9cdc
|
|
BLAKE2b-256 checksum How to use checksums |
f0229b9a2b1c4621ff7a33e7ee794b8dc6a28d8c7c95b352b14153a33c6b6807
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|