Skip to main content

A risk-scoring engine for email signups.

Project description

Disposable Email Score

A robust, explainable risk-scoring engine for email signups. Detects disposable emails, typosquatting attacks, and suspicious domains.

Python 3.8+ License: MIT Twitter

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.com if tempmail.com is blocked
  • Plus Alias Detection — Detects user+tag@gmail.com patterns
  • 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

Architecture

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

disposable_email_score-0.1.1.tar.gz (653.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

disposable_email_score-0.1.1-py3-none-any.whl (654.8 kB view details)

Uploaded Python 3

File details

Details for the file disposable_email_score-0.1.1.tar.gz.

File metadata

  • Download URL: disposable_email_score-0.1.1.tar.gz
  • Upload date:
  • Size: 653.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for disposable_email_score-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9df4c2bc13dd6afd22922c5e71b6e556430634eff0748b3ecc4df13d69c96c10
MD5 aba4fa1de18c22c60bdf5676aab03f3f
BLAKE2b-256 839584a3d91e9e862a8587b58045963c9cf634ce1db92377648a3b296e927778

See more details on using hashes here.

File details

Details for the file disposable_email_score-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for disposable_email_score-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d433db838cbe5cd45b999ee7cef45fbadd4f71a0cf0fc5feb7e30ae4d63b9cdc
MD5 f9101774f214641c60b5f43d9f9b9690
BLAKE2b-256 f0229b9a2b1c4621ff7a33e7ee794b8dc6a28d8c7c95b352b14153a33c6b6807

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page