Email Validation in Python

Validate any email address from Python with one API call using requests or httpx. Pass an address, get back a nested JSON object with syntax, deliverability, domain, and quality signals. Real-time, sub-1s median response.

100 validations a month. No credit card required.
100 free per monthWorks with requests and httpxSub-1s response
import requests response = requests.post( "https://api.trueguard.io/v2/email/validation", json={"email": "founder@yourcompany.com"}, headers={"X-API-KEY": YOUR_KEY}, ) result = response.json() print(result)

How do I validate an email in Python?

Three steps. Most teams have it running in under an afternoon.

1

Get a free API key

Sign up at trueguard.io. No card, no trial expiry. 100 validations a month included on the free tier.

2

POST to /email/validation with X-API-KEY

Send the address as JSON using requests.post or httpx.post. Set X-API-KEY in the headers dict. Read the key from os.environ, never hardcode it.

3

Read the nested JSON, branch on deliverability.status

safe: accept. risky: catch-all or uncertain, apply a softer policy. invalid: the mailbox does not exist, reject.

Python samples using the real endpoint. Paste, set your key, run.

import requests response = requests.post( "https://api.trueguard.io/v2/email/validation", json={"email": "founder@yourcompany.com"}, headers={"X-API-KEY": YOUR_KEY}, ) result = response.json() print(result)

Where should I run email validation in Python?

Python runs server-side. Keep your API key in an environment variable, call the API from your backend, and the key never leaves your infrastructure.

Keep the key out of source

Read the key with os.environ.get or os.getenv. Never hardcode it in your source file and never commit it to version control.

Do not include the key in a Jupyter notebook you share or in a client-distributed script. Treat it like a password.

Call it from your backend or a worker

Place the validation call inside a Django view, a Flask route handler, or a FastAPI endpoint. The key stays on the server and never reaches the client.

For batch validation, run it in a Celery or RQ background job. You get automatic retries and the web request stays fast.

What does the JSON response look like?

Four nested groups: syntax, deliverability, domain, and quality. Every field is included on every plan, including free.

saferealemail@gmail.com
Syntax valid
Deliverable
SMTP valid
MX valid
Catch-all
Disposable
Free provider
Role-based
{ "email": "realemail@gmail.com", "rawEmail": "realemail@gmail.com", "syntax": { "isValid": true }, "deliverability": { "status": "safe", "isSmtpValid": true, "isMxValid": true, "isCatchall": false, "isInboxFull": false, "isDeliverable": true, "isDisabled": false, "mxRecords": [ "alt2.gmail-smtp-in.l.google.com", "gmail-smtp-in.l.google.com", "alt4.gmail-smtp-in.l.google.com", "alt1.gmail-smtp-in.l.google.com", "alt3.gmail-smtp-in.l.google.com" ] }, "domain": { "name": "gmail.com", "age": 11263, "isLive": true, "isRisky": false }, "quality": { "isDisposable": false, "isFree": true, "isRole": false, "isSubaddress": false } }

How do I handle errors and rate limits in Python?

Call response.raise_for_status() after the requests.post call. A 429 on response.status_code means you have hit the rate limit and should back off before retrying. Wrap the block in a broader requests.exceptions.RequestException to catch network failures.

import requests try: response = requests.post( "https://api.trueguard.io/v2/email/validation", json={"email": email}, headers={"X-API-KEY": YOUR_KEY}, timeout=10, ) response.raise_for_status() except requests.exceptions.HTTPError as error: if response.status_code == 429: raise RuntimeError("Rate limit reached. Back off and retry.") from error raise RuntimeError(f"Validation failed: {response.status_code}") from error except requests.exceptions.RequestException as error: raise RuntimeError("Network error calling the validation API.") from error result = response.json()

Which Python frameworks does this work with?

Any Python environment that can make an HTTPS POST request. The snippets all call the same endpoint with the same header. You can also use the same API from JavaScript, PHP, Go, Ruby, C#, and Java.

Django

Call the API inside a Django view or form validator. Read the key from os.environ. Works with both function-based and class-based views.

Flask

Validate in a Flask route handler before committing any data. Store the key in app.config or an environment variable. Works with Flask-WTF forms.

FastAPI

Use httpx.AsyncClient for async validation inside a FastAPI endpoint. Await the call so your handler stays non-blocking. The key stays server-side.

requests

The synchronous default. One pip install, minimal boilerplate. Best for scripts, Django, and Flask where async is not a requirement.

httpx (async)

Drop-in async equivalent of requests. Use it inside FastAPI or any asyncio-based application. The API shape and headers are identical.

Celery / background jobs

Validate in a Celery or RQ task for batch processing or deferred checks. Keeps your web request fast and lets you retry on transient failures.

What can I build with email validation in Python?

One API call unlocks several data-quality and fraud-prevention patterns. Here are the most common ones teams build with the Python integration.

Stop fake signups at the form

Validate on submit, before the account is created. Drop disposable addresses and hard-reject invalid ones. Risky catch-all addresses can be accepted with a confirmation step.

Stop fake signups

Clean outreach lists before sending

Run each address through the API before the campaign loads it. Flag role mailboxes and invalid addresses to protect your sender reputation.

Pair with VPN detection

Email list hygiene

Validate in batch before a send. Drop invalid, flag disposable, route catch-all to a re-permission flow. Cleaner list, lower bounce rate, better deliverability.

Email list cleaning guide

Frequently asked questions

How do I validate an email address in Python?

Send a POST request to https://api.trueguard.io/v2/email/validation using the requests library. Set the X-API-KEY header to your key and pass the address as JSON in the request body. Call response.json() to get the nested result object with syntax, deliverability, domain, and quality groups. Branch on deliverability.status: safe means the address passed, risky means catch-all or uncertain, invalid means the mailbox does not exist.

Should I use requests or httpx in Python?

Both work against the same endpoint. Use requests for synchronous code in Django, Flask, or scripts. Use httpx when you need async support, for example in a FastAPI route handler using await. The headers and body shape are identical. Install requests with pip install requests or httpx with pip install httpx.

Where should I run email validation in Python?

Always run the validation in a server-side process so your API key is never exposed. Store the key in an environment variable and read it with os.environ.get or os.getenv. Call the API from a Django view, a Flask route, a FastAPI endpoint, or a background worker such as Celery or RQ. Never embed the key in a client-distributed script or a notebook you share with others.

What does the JSON response look like?

The response is a nested object with four groups: syntax contains isValid; deliverability contains status, isSmtpValid, isMxValid, isCatchall, isInboxFull, isDeliverable, isDisabled, and mxRecords; domain contains name, age, isLive, and isRisky; quality contains isDisposable, isFree, isRole, and isSubaddress. Every field is present on every plan including free.

How do I check if an email is deliverable in Python?

Read deliverability.status from the parsed response dict. If it equals safe the address passed all checks. If it equals risky the domain is a catch-all or the SMTP probe could not confirm the mailbox, so the address may or may not be real. If it equals invalid the mailbox does not exist. Branch on these three values rather than any individual boolean for the most reliable decision.

Does the API detect catch-all domains in Python?

Yes. When the destination domain accepts mail for every address, the API sets deliverability.isCatchall to true and deliverability.status to risky. You cannot confirm a specific mailbox on a catch-all domain without actually sending mail, so risky is the honest verdict. You can use isCatchall to apply a softer policy instead of a hard reject.

How do I handle errors and rate limits in Python?

Call response.raise_for_status() after the requests.post call. This raises an HTTPError for any 4xx or 5xx response. Check the status_code on the exception: 429 means you have hit the rate limit and should back off before retrying. Wrap the block in a broader except requests.exceptions.RequestException to handle network failures such as timeouts. Log the status code to distinguish between a validation error and a temporary service issue.

Is there a free tier for testing the Python integration?

Yes. Sign up for a Trueguard account and you get 100 email validations per month at no cost, with no credit card required. The free tier runs the production endpoint with the same response shape and the same accuracy as a paid plan. It is enough to build and test a full integration before committing to a subscription.

Validate emails from Python in minutes.

100 validations a month, free, no card. One endpoint, working code samples, a real JSON response viewer. Start integrating now.

No credit card required.

trueguard-logo© 2026 Trueguardinfo@trueguard.io