Python email verification
Verify emails in Python with Verifly
Add a live email verification step to any Python app in a few lines. Verifly is an API-first, pay-as-you-go service — call it with the requests library you already use, read a clean JSON verdict, and drop bad addresses before they ever reach your mailer.
import requests
resp = requests.get(
"https://verifly.email/api/v1/verify",
params={"email": "user@example.com"},
headers={"Authorization": "Bearer vf_YOUR_KEY"},
)
data = resp.json()
print(data["result"], data["is_valid"])Real-time SMTP mailbox checks
Single, batch, and async bulk verification
Disposable, role account, and catch-all detection
Pay-as-you-go credits with no subscription lock-in
Search fit
Built for Python email verification
Use Verifly when you need a simple API, predictable pricing, and clean JSON results before emails hit your product, CRM, or campaign tool.
Email verification in the Python ecosystem
Python is the language most teams reach for when they need to clean data, and email lists are one of the messiest datasets around. Whether the addresses arrive from a web form handled by Flask or Django, a scraped source loaded into pandas, or a partner CSV that lands in an S3 bucket, they all share the same problem: syntax alone tells you almost nothing about whether a mailbox actually exists. A regex or the venerable email-validator package will happily pass user@dead-domain.com, and your SMTP server will only find out it bounces after you have already burned sender reputation.
Verifly closes that gap with a single HTTP call. Because it is a plain REST API, you do not need a heavy SDK or a native extension — the standard requests library (or httpx if you prefer async) is all it takes. You send an address, Verifly performs a live SMTP mailbox probe, and you get back a JSON object with a result field of deliverable, undeliverable, or risky plus boolean flags for disposable, role, catch-all, and smtp. That maps cleanly onto Python control flow: branch on data["result"], or filter a list comprehension on it.
The pay-as-you-go model fits scripts and cron jobs especially well. There is no monthly seat to justify — you grab a key, spend credits from $2 per 1,000 checks down to $0.60 per 1,000 at volume, and the same key works from a laptop notebook, a Lambda function, or a long-running worker. Start with 100 free credits by self-registering, no card and no captcha, at the autonomous register endpoint.
Batch-verify a list of emails in Python
When you have more than a handful of addresses, do not loop the single endpoint — send them together to POST /verify/batch. It accepts a JSON body with an emails array and returns a results array in the same order, so you can zip it back against your source rows. This is the natural fit for a pandas column or a de-duplicated set of leads.
import requests
emails = [
"ada@example.com",
"info@some-domain.com",
"noreply@disposable.tld",
]
resp = requests.post(
"https://verifly.email/api/v1/verify/batch",
json={"emails": emails},
headers={
"Authorization": "Bearer vf_YOUR_KEY",
"Content-Type": "application/json",
},
)
results = resp.json()["results"]
deliverable = [r["email"] for r in results if r["result"] == "deliverable"]
print(f"Keeping {len(deliverable)} of {len(results)} addresses")
for r in results:
if r.get("disposable") or r.get("role"):
print("drop:", r["email"], r["result"])Wire it into a Django or Flask signup
The highest-value place to verify in Python is the moment a user registers. A quick call inside your view — or better, a short-timeout call wrapped in a try/except so a network hiccup never blocks signup — lets you reject disposable addresses and warn on undeliverable ones before the account is created. Because the check is one synchronous request against a fast endpoint, it slots into existing form validation without a background queue.
import requests
def is_email_ok(email: str) -> bool:
try:
r = requests.get(
"https://verifly.email/api/v1/verify",
params={"email": email},
headers={"Authorization": "Bearer vf_YOUR_KEY"},
timeout=8,
)
data = r.json()
except requests.RequestException:
return True # fail open: never block signup on a network error
if data.get("disposable"):
return False
return data["result"] != "undeliverable"FAQ
Frequently asked questions
Which Python HTTP library should I use with Verifly?
Any of them. The examples use the requests library because it is the most common, but Verifly is a plain REST API, so httpx (great for async), aiohttp, or the standard-library urllib all work identically. Send a GET to /api/v1/verify with a Bearer key and read JSON.
How do I verify a whole pandas column?
Collect the column into a list, send it to POST /api/v1/verify/batch in chunks, and merge the results array back onto your DataFrame by the email field. Batching is far faster and cheaper than calling the single endpoint per row.
Should I verify emails synchronously inside a Django view?
Yes for a single signup check — it is one fast request. Wrap it in a try/except with a timeout and fail open so a transient network error never blocks a legitimate registration. For bulk cleaning, move it to a Celery task instead.
What fields does the JSON response contain?
Each result includes result (deliverable, undeliverable, or risky), is_valid, and boolean flags disposable, role, catch_all, and smtp. Branch on result for the headline decision and use the flags to strip throwaway or generic role addresses.
Is there a Python SDK, or just the REST API?
The REST API is the interface, and with requests it is already only a few lines, so no wrapper is required. If you run an AI agent, Verifly also exposes an MCP server at verifly.email/mcp that the agent can call directly.
What does Python email verification cost?
Pricing is pay-as-you-go from $2 per 1,000 checks down to $0.60 per 1,000 at volume, with 100 free credits when you self-register. There is no subscription, so an occasional cleaning script costs only the credits it spends.