Email verification API in Python: sandbox and error handling
By the 1-email.com editorial team · Reviewed October 9, 2026 · Editorial policy
Use Python standard-library requests from a server, handle unknown results and test 402/429 responses.
Download and run locally
Python 3.10+. No package installation is needed. Download every file below into the same directory, then run:
python3 verify.py
Source files
verify.py Download
"""Python 3.10+: run on your server, never in a browser. No dependencies."""
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen
class VerificationError(Exception):
def __init__(self, status, message, retry_after=None):
super().__init__(message)
self.status = status
self.retry_after = retry_after
def verify_email(email, *, key=None, opener=urlopen):
key = key or os.environ.get("EEV_API_KEY", "eev_sandbox_key")
url = "https://api.easyemailverification.com/v1/verify?" + urlencode({"email": email})
request = Request(url, headers={"X-API-Key": key, "Accept": "application/json"})
try:
with opener(request, timeout=30) as response:
data = json.load(response)
except HTTPError as error:
messages = {402: "No credits: check your account before retrying.",
429: "Rate limited: wait before another request; respect Retry-After."}
raise VerificationError(error.code, messages.get(error.code, "Verification request failed."),
error.headers.get("Retry-After") if error.headers else None) from error
except (URLError, TimeoutError, ValueError) as error:
raise VerificationError(503, "No reliable result; review the request before retrying.") from error
if not isinstance(data, dict) or data.get("result") not in ("valid", "invalid", "unknown"):
raise VerificationError(502, "Unexpected API response; do not classify the address.")
return data
def classify(data):
if data["result"] == "invalid":
return "invalid"
if data["result"] == "unknown":
return "review"
if data.get("disposable") or data.get("accept_all") or data.get("safe_to_send") is not True:
return "review"
return "passed_checks"
if __name__ == "__main__":
email = sys.argv[1] if len(sys.argv) > 1 else "valid@sandbox.easyemailverification.com"
try:
data = verify_email(email)
print(json.dumps({"decision": classify(data), "result": data["result"],
"reason": data.get("reason"), "did_you_mean": data.get("did_you_mean")}, indent=2))
except VerificationError as error:
print(f"HTTP {error.status}: {error}", file=sys.stderr)
sys.exit(1)
Test success, uncertainty and failures
Replace the default test address using the command-line argument (Python/Node) or the form field (signup). Use valid, invalid, unknown, catchall, disposable, quota and ratelimit at sandbox.easyemailverification.com. The special typo@gmial.com fixture gives a correction suggestion.
Expect unknown and risk flags to produce review rather than rejection. Quota should stop the request with 402; a rate limit returns 429. Network or JSON failures should never create a valid or invalid mailbox classification.
Before production
Set EEV_API_KEY in the server environment. Keep the endpoint fixed, set a timeout, limit request size and add abuse controls. For a real signup flow add origin/CSRF protection, your own rate limit and consent handling. Do not retry an uncertain request automatically or silently replace a typo.
Primary source: Easy API reference. Download the example instructions.
Ready for real addresses?
We run Easy Email Verification. Create a free account for a live key after testing your integration.
Get a free live key