Python SDK for ValidKit — email validation for signup flows
Project description
ValidKit Python SDK
Email validation for signup flows -- block junk without blocking test+staging@example.com. Sync and async clients, batch support up to 10K emails, automatic retries, and Pydantic models.
Installation
pip install validkit
Requires Python 3.8+.
Quick Start
from validkit import ValidKit
client = ValidKit("your_api_key")
result = client.verify("user@example.com")
print(result.v) # True or False
client.close()
Or with a context manager:
from validkit import ValidKit
with ValidKit("your_api_key") as client:
# Single email
result = client.verify("user@example.com")
print(result.v)
# Batch -- compact format by default
results = client.verify_batch([
"alice@company.com",
"bob@tempmail.com",
"not-an-email",
])
for email, r in results.items():
print(f"{email}: valid={r.v}, disposable={r.d}")
Async usage
For high-throughput applications, use AsyncValidKit directly:
import asyncio
from validkit import AsyncValidKit
async def main():
async with AsyncValidKit(api_key="your_api_key") as client:
result = await client.verify_email("user@example.com")
print(result.valid)
asyncio.run(main())
Features
- Sync and async --
ValidKitfor scripts,AsyncValidKitfor high-throughput - Batch verification -- up to 10,000 emails per call, chunked automatically
- Developer Pattern Intelligence -- understands
test@,+addressing, disposable domains - Compact format -- token-efficient responses (
v,d,rfields) enabled by default - Streaming --
async forresults as they complete - Webhook delivery -- fire-and-forget async batch jobs with callback
- Automatic retries -- exponential backoff, 3 retries default
- Type-safe -- Pydantic v2 models with full type hints
Advanced Usage
Custom configuration
from validkit import AsyncValidKit, ValidKitConfig
config = ValidKitConfig(
api_key="your_api_key",
timeout=30, # seconds
max_retries=3, # retry count
max_connections=100, # connection pool size
rate_limit=10000, # requests/min (None = unlimited)
compact_format=True, # smaller payloads
)
async with AsyncValidKit(config=config) as client:
result = await client.verify_email("user@example.com")
Batch with progress tracking
def on_progress(processed, total):
print(f"{processed}/{total} ({processed / total * 100:.1f}%)")
results = await client.verify_batch(
emails,
chunk_size=1000,
progress_callback=on_progress,
)
Async batch with webhook
job = await client.verify_batch_async(
emails=large_list,
webhook_url="https://your-app.com/webhooks/validkit",
webhook_headers={"Authorization": "Bearer token"},
)
# Poll until complete, or wait for webhook
job = await client.get_batch_status(job.id)
results = await client.get_batch_results(job.id)
# Cancel if needed
await client.cancel_batch(job.id)
Streaming
async for email, result in client.stream_verify(emails, batch_size=100):
print(f"{email}: valid={result.v}")
Trace IDs
Attach a trace ID for cross-service debugging:
result = await client.verify_email("user@example.com", trace_id="req_abc123")
Error Handling
from validkit.exceptions import (
ValidKitError, # base -- catches everything
ValidKitAPIError, # API errors (4xx, 5xx)
InvalidAPIKeyError, # 401
RateLimitError, # 429, includes retry_after
BatchSizeError, # batch exceeds 10K
TimeoutError, # request timeout (inherits ValidKitError, not API)
ConnectionError, # network failure (inherits ValidKitError, not API)
)
try:
result = await client.verify_email("user@example.com")
except RateLimitError as e:
print(e.retry_after) # seconds until retry
except InvalidAPIKeyError:
print("Check your API key")
except ValidKitAPIError as e:
print(e.message, e.status_code, e.code)
except ValidKitError as e:
# Catches TimeoutError, ConnectionError, and any other non-API errors
print(f"SDK error: {e}")
The SDK retries automatically on rate limits and transient errors (up to max_retries). Catch exceptions only if you need custom handling.
Compact Response Format
Default format. Smaller payloads, same information:
| Field | Type | Meaning |
|---|---|---|
v |
bool |
Email is valid |
d |
bool | None |
Domain is disposable (None if not checked) |
r |
str | None |
Reason (present only when invalid) |
# Compact (default)
r = await client.verify_email("bad@example.com")
print(r.v, r.d, r.r) # False, False, "invalid_format"
# Full format -- use when you need MX records, SMTP details
from validkit.models import ResponseFormat
full = await client.verify_email("user@example.com", format=ResponseFormat.FULL)
if full.mx:
print(full.mx.records) # ["mx1.example.com"]
Examples
See examples/:
basic_usage.py-- single verification, batch, streaming, configurationbatch_processing.py-- large batches, CSV processing, webhook jobs, domain analysis
Contributing
See CONTRIBUTING.md.
Support
Docs -- GitHub Issues -- developers@validkit.com
License
MIT -- see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file validkit-1.2.1.tar.gz.
File metadata
- Download URL: validkit-1.2.1.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8853d09988c18273f1a71b92a7fc46682d5879ad822e5041f22c6f492a725688
|
|
| MD5 |
c64eacb8b9656980e8fa5116525b7502
|
|
| BLAKE2b-256 |
dcca48dedbac9eff816288de4d1bc1356b5fd49c6cddbd6a692efd199a940199
|
File details
Details for the file validkit-1.2.1-py3-none-any.whl.
File metadata
- Download URL: validkit-1.2.1-py3-none-any.whl
- Upload date:
- Size: 22.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e57635e94654657ab4549b357ade9de4c710f2a83c53c72c8056f279975af2d4
|
|
| MD5 |
eb73ad009ced84e2d328298454fb1c6b
|
|
| BLAKE2b-256 |
6f934bf17fe7cd713d407884d6283c8c1c546f1e8a755d63a75b2a5a519c0fb7
|