Mailfloss Python SDK
The official Python SDK for the Mailfloss email verification API. Zero runtime dependencies — standard library only.
- Full coverage of the Mailfloss v1 public API
- Automatic retries (429/5xx,
Retry-Afteraware, exponential backoff + jitter) - Automatic
Idempotency-Keyon every POST - Fully typed (
TypedDictmodels, shipspy.typed) - Python 3.9+
Installation
pip install mailfloss
Authentication
Get your API key from the Mailfloss dashboard, then either pass it directly:
from mailfloss import Mailfloss
client = Mailfloss(api_key="mf_rk_your_key_here")
or set it in the environment and construct the client with no arguments:
export MAILFLOSS_API_KEY="mf_rk_your_key_here"
from mailfloss import Mailfloss
client = Mailfloss()
Every request is sent with Authorization: Bearer <key>. If no key is
available, the constructor raises MailflossConfigError.
Quickstart
Verify a single email — GET /v1/verify
from mailfloss import Mailfloss
client = Mailfloss()
result = client.verify("jane@example.com")
print(result["status"]) # "passed" | "undeliverable" | "risky" | "unknown"
print(result["passed"]) # True if safe to send
print(result["reason"]) # e.g. "available", "nonexistent", ...
if result.get("suggestion"):
print("Did you mean:", result["suggestion"])
Verify a batch — POST /v1/batch-verify
job = client.batch_verify.create(
emails=["jane@example.com", "joe@exmaple.com"],
webhook_url="https://example.com/hooks/mailfloss", # optional callback
)
job_id = job["id"]
# Poll progress...
status = client.batch_verify.status(job_id)
print(status["status"], status.get("progress"))
# ...then page through results
page = client.batch_verify.results(job_id, per_page=500)
for row in page.get("results", []):
print(row)
Error handling
Non-2xx responses raise MailflossError with structured fields:
from mailfloss import Mailfloss, MailflossError
client = Mailfloss()
try:
client.jobs.get("does-not-exist")
except MailflossError as err:
print(err.status) # 404
print(err.code) # stable machine-readable code
print(err.message) # human-readable message
print(err.type) # e.g. "not_found_error"
print(err.request_id) # for support correlation
Requests failing with 429 or 5xx (and connection errors) are retried
automatically up to max_retries (default 3), honoring the server's
Retry-After header when present.
API surface
| Resource | Methods |
|---|---|
| Single verify | client.verify(email, timeout=None) |
| Batch verify | client.batch_verify.create(emails, webhook_url=None) / .status(id) / .results(id, per_page=None, next=None) / .cancel(id) |
| Jobs | client.jobs.list(per_page=None, cursor=None, source=None, status=None) / .get(id) |
| Users | client.users.list(per_page=None, cursor=None) / .get(user_id) |
| Reports | client.reports.usage(period=None, connection_id=None) |
| Key check | client.check_key() |
| Account | client.account.get() / .update({...}) |
| Organization | client.organization.get() |
| Integrations | client.integrations.list() / .get(type) |
| Connections | client.integrations.connections.create(type, credentials, name=None) / .get(type, id) / .update(type, id, {...}) / .delete(type, id) / .sync(type, id) / .test(type, id) |
| Keyword rules | client.integrations.keywords.list(type, connection_id, list) / .add(type, connection_id, list, rules) / .delete(type, connection_id, list, rule_id) |
| Erasures | client.erasures.create(emails, webhook_url=None) |
List endpoints return {"data": [...], "pagination": {"next_cursor", "has_more"}}.
Configuration
client = Mailfloss(
api_key="mf_rk_...", # or MAILFLOSS_API_KEY
base_url="https://api.mailfloss.com/v1", # default
max_retries=3, # retries on 429/5xx/conn errors
timeout=30.0, # socket timeout, seconds
transport=None, # injectable low-level transport
)
Idempotency
Every POST automatically carries an Idempotency-Key header (UUIDv4),
generated once per call so retries replay the same key. Supply your own when
you want cross-process dedup:
client.batch_verify.create(
emails=["jane@example.com"],
idempotency_key="order-12345-verify", # gitleaks:allow — docs example, not a secret
)
Development
cd sdks/python
PYTHONPATH=src python3 -m unittest discover -s tests -v
License
MIT — see LICENSE.
Metadata
Release files for mailfloss 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mailfloss-0.1.0.tar.gz | 19.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mailfloss-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.7 kB
Release files / mailfloss-0.1.0.tar.gz
| Download URL | mailfloss-0.1.0.tar.gz |
|---|---|
| Size | 19.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
510d8a8f2e7b34f00245ab32142c2405df5cad0882b8877881887b86b4d35f89
|
|
BLAKE2b-256 checksum How to use checksums |
27b63b6d6225eb955512d0cfb7d1136c6ea962b14d4eea5e0c3e31a8960eac9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / mailfloss-0.1.0-py3-none-any.whl
| Download URL | mailfloss-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de92ae7d54435ad86cf3bee37d4d35592461f8351dd776dc49dd2a40ee91dadd
|
|
BLAKE2b-256 checksum How to use checksums |
78ffd736fe87fd2d5b18b06211305ebce9f2d6898eec93897fb02cb5b416585d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Security for mailfloss 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.