How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox)

Want to verify whether an email is real (deliverable) or just a throwaway disposable address (e.g. TempMailbox)? In this post I’ll show the purpose, how to write a small Python script that uses the Mail7 public Email Checker API, and how to use it in s…


This content originally appeared on DEV Community and was authored by Den

Want to verify whether an email is real (deliverable) or just a throwaway disposable address (e.g. TempMailbox)? In this post I’ll show the purpose, how to write a small Python script that uses the Mail7 public Email Checker API, and how to use it in simple workflows (single-check, bulk-check, rate-limit handling). Code examples are ready-to-run and easy to adapt for production use.

Why this is useful

  • Prevent fake or disposable emails polluting your database (improves deliverability & analytics).
  • Reduce fraud, reduce bounce rates and protect downstream workflows (password resets, marketing).
  • Lightweight: Mail7’s API is public and simple — you don’t need API keys to get started. 

(Example disposable service referenced in this post: TempMailbox — a typical disposable/temp-mail provider.)

Quick notes from Mail7 docs (what matters)

  • Base URL: https://mail7.net. No authentication required — it’s a public API. 
  • Rate limit: 5 requests / minute / IP. Exceeding it returns HTTP 429 with a Retry-After header. Your script should respect this. 
  • Key endpoints used here:
  1. POST /api/validate-single — single email check (JSON body {"email": "..."} ). Response contains valid, formatValid, mxValid, smtpValid, status, details and importantly is_disposable. 
  2. POST /api/validate-bulk — upload file or text list for bulk checks. Useful for offline cleanup. 
  3. GET /api/spf-check/{domain} - optional: check domain SPF if you want to add additional heuristics.

The Python script (complete, annotated)

Save as mail7_check.py. It does:

  • single-check via /api/validate-single
  • handles rate-limit (429 + Retry-After)
  • simple backoff on server errors
  • can be used interactively or imported as a module
#!/usr/bin/env python3
"""
mail7_check.py
Simple utilities to check an email address using Mail7 Email Checker API.
"""

import time
import requests
from typing import Dict, Optional

BASE = "https://mail7.net"
SINGLE_ENDPOINT = f"{BASE}/api/validate-single"
BULK_ENDPOINT = f"{BASE}/api/validate-bulk"
SPF_ENDPOINT = f"{BASE}/api/spf-check/{{}}"

# Simple wrapper for single validation
def validate_single(email: str, timeout: float = 10.0) -> Dict:
    """Validate a single email. Returns the parsed JSON response."""
    payload = {"email": email}
    headers = {"Content-Type": "application/json"}
    while True:
        resp = requests.post(SINGLE_ENDPOINT, json=payload, headers=headers, timeout=timeout)
        if resp.status_code == 200:
            return resp.json()
        if resp.status_code == 429:
            # Respect Retry-After header if present
            retry = resp.headers.get("Retry-After")
            wait = int(retry) if retry and retry.isdigit() else 60
            print(f"[rate-limit] 429 received. Waiting {wait} seconds...")
            time.sleep(wait)
            continue
        if 500 <= resp.status_code < 600:
            # transient server error, back off a bit
            print(f"[server-error] {resp.status_code}. Backing off 5s...")
            time.sleep(5)
            continue
        # For other errors, raise
        resp.raise_for_status()

def is_good_email(result: Dict) -> bool:
    """
    Heuristic to decide whether to accept this email:
      - result['valid'] should be True
      - smtpValid and mxValid are helpful
      - is_disposable should be False
      - status normally contains 'Valid' for good addresses
    Adapt this logic to your business needs.
    """
    if not result:
        return False
    if result.get("is_disposable"):
        return False
    # require overall valid + smtp existence
    if result.get("valid") and result.get("smtpValid"):
        return True
    # fallback: format + mx
    if result.get("formatValid") and result.get("mxValid"):
        return True
    return False

def pretty_print(result: Dict):
    print("email:", result.get("email"))
    print("status:", result.get("status"))
    print("valid:", result.get("valid"))
    print("formatValid:", result.get("formatValid"))
    print("mxValid:", result.get("mxValid"))
    print("smtpValid:", result.get("smtpValid"))
    print("is_disposable:", result.get("is_disposable"))
    print("details:", result.get("details"))

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Check email validity using mail7.net API")
    parser.add_argument("email", help="Email to check, or path to file with emails (one per line) if --bulk")
    parser.add_argument("--bulk", action="store_true", help="Treat argument as a file and run bulk check (calls validate-bulk)")
    args = parser.parse_args()

    if args.bulk:
        # Bulk mode: upload file to /api/validate-bulk (form data: 'emails')
        with open(args.email, "rb") as f:
            files = {"emails": (args.email, f)}
            r = requests.post(BULK_ENDPOINT, files=files)
            r.raise_for_status()
            data = r.json()
            print("Total:", data.get("total"))
            for item in data.get("results", []):
                print("----")
                pretty_print(item)
    else:
        res = validate_single(args.email)
        pretty_print(res)
        print("DECISION:", "ACCEPT" if is_good_email(res) else "REJECT")

Requirements

pip install requests
python3 mail7_check.py [email to check]
# or bulk:
python3 mail7_check.py emails.txt --bulk

How the script decides disposable vs real

Mail7’s response contains an is_disposable boolean. Use that directly to detect throwaway providers (like TempMailbox). Combine that with smtpValid and mxValid to be confident — smtpValid=true strongly indicates the address exists and accepts mail. 

Example logic in the script (is_good_email) returns False when is_disposable is true, or when the address fails SMTP checks.

Real-world usage examples

  • Signup form — call validate-single on email submission. If is_disposable is true or smtpValid is false, show a friendly error or ask the user for a non-disposable email.
  • CRM cleanup — every week, run a bulk pass with validate-bulk and remove invalid/disposable addresses from mailing lists.
  • Fraud screening — combine is_disposable with geo/IP/device signals for higher-risk signups.

Caveats & tips

  • False negatives/positives: No validation is perfect. Some providers block SMTP probes, some disposable providers forward to real addresses — combine signals (mx, smtp, is_disposable, and business rules).
  • Respect privacy & terms: Don’t leak results or perform abusive queries. If you need bulk/enterprise usage, contact Mail7 for a supported arrangement (the docs describe basic public API behavior).
  • Disposable services evolve. Lists of disposable domains change — relying solely on a static list is brittle. Using Mail7’s is_disposable is easier because they update their detection on the provider side.

Final notes & links

  • Mail7 API docs (use them as the definitive reference for endpoints, payloads and rate limits): https://mail7.net/api-docs.html. 
  • Example disposable provider for reference: https://tempmailbox.net (TempMailbox) — great example of a disposable mailbox you may want to block on registration. 


This content originally appeared on DEV Community and was authored by Den


Print Share Comment Cite Upload Translate Updates
APA

Den | Sciencx (2025-10-28T09:14:18+00:00) How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox). Retrieved from https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/

MLA
" » How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox)." Den | Sciencx - Tuesday October 28, 2025, https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/
HARVARD
Den | Sciencx Tuesday October 28, 2025 » How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox)., viewed ,<https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/>
VANCOUVER
Den | Sciencx - » How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox). [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/
CHICAGO
" » How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox)." Den | Sciencx - Accessed . https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/
IEEE
" » How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox)." Den | Sciencx [Online]. Available: https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/. [Accessed: ]
rf:citation
» How to build a Python email-checker using the Mail7 API (and spot disposable addresses like TempMailbox) | Den | Sciencx | https://www.scien.cx/2025/10/28/how-to-build-a-python-email-checker-using-the-mail7-api-and-spot-disposable-addresses-like-tempmailbox/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.