Official BillionVerify Python SDK for email verification.
Documentation: https://billionverify.com/docs
pip install billionverifyfrom billionverify import BillionVerify
client = BillionVerify(api_key="your-api-key")
# Verify a single email
result = client.verify("user@example.com")
print(result.status) # 'valid', 'invalid', 'unknown', 'risky', 'disposable', 'catchall', 'role'
print(result.is_deliverable) # True or Falseclient = BillionVerify(
api_key="your-api-key", # Required
base_url="https://api.billionverify.com/v1", # Optional
timeout=30.0, # Optional: Request timeout in seconds (default: 30)
retries=3, # Optional: Number of retries (default: 3)
)Uses the /verify/single endpoint:
result = client.verify(
email="user@example.com",
check_smtp=True, # Optional: Perform SMTP verification (default: True)
)
# Flat response structure
print(result.email) # 'user@example.com'
print(result.status) # 'valid', 'invalid', 'unknown', 'risky', 'disposable', 'catchall', 'role'
print(result.score) # 0.95
print(result.is_deliverable) # True
print(result.is_disposable) # False
print(result.is_catchall) # False
print(result.is_role) # False
print(result.is_free) # True
print(result.domain) # 'example.com'
print(result.reason) # 'Valid email address'
print(result.smtp_check) # True (whether SMTP was performed)
print(result.credits_used) # 1Verify up to 50 emails synchronously using verify_bulk():
# Synchronous bulk verification (max 50 emails)
response = client.verify_bulk(
emails=["user1@example.com", "user2@example.com", "user3@example.com"],
check_smtp=True, # Optional
)
# Returns BulkVerifyResponse directly
print(f"Total: {response.total}")
print(f"Credits used: {response.credits_used}")
for result in response.results:
print(f"{result.email}: {result.status}")
print(f" Deliverable: {result.is_deliverable}")
print(f" Disposable: {result.is_disposable}")
print(f" Catchall: {result.is_catchall}")
print(f" Role: {result.is_role}")For large lists, use upload_file() for asynchronous file verification:
# Upload a file for async verification
job = client.upload_file(
file_path="emails.csv",
check_smtp=True,
email_column="email", # Column name for CSV files
preserve_original=True, # Keep original columns in results
)
print(f"Job ID: {job.job_id}")
print(f"Status: {job.status}")
# Get job status (with optional long-polling)
status = client.get_file_job_status(
job_id=job.job_id,
timeout=60, # Long-poll for up to 60 seconds (0-300)
)
print(f"Progress: {status.progress_percent}%")
# Wait for completion (polling)
completed = client.wait_for_file_job(
job_id=job.job_id,
poll_interval=5.0, # seconds
max_wait=600.0, # seconds
)
# Get results with filter options
results = client.get_file_job_results(
job_id=job.job_id,
limit=100,
offset=0,
valid=True, # Include valid emails
invalid=True, # Include invalid emails
unknown=True, # Include unknown emails
risky=True, # Include risky emails
disposable=True, # Include disposable emails
catchall=True, # Include catch-all emails
role=True, # Include role-based emails
)
for item in results.results:
print(f"{item.email}: {item.status}")import asyncio
from billionverify import AsyncBillionVerify
async def main():
async with AsyncBillionVerify(api_key="your-api-key") as client:
# Single verification
result = await client.verify("user@example.com")
print(result.status)
# Bulk verification
response = await client.verify_bulk([
"user1@example.com",
"user2@example.com"
])
for r in response.results:
print(f"{r.email}: {r.status}")
asyncio.run(main())Check API health status (no authentication required):
health = client.health_check()
print(health.status) # 'ok'
print(health.version) # API versioncredits = client.get_credits()
print(credits.credits_balance) # Available credits
print(credits.credits_consumed) # Credits used
print(credits.credits_added) # Total credits added
print(credits.api_key_name) # API key nameWebhooks support events: file.completed, file.failed
# Create a webhook
webhook = client.create_webhook(
url="https://your-app.com/webhooks/billionverify",
events=["file.completed", "file.failed"],
)
print(f"Webhook ID: {webhook.id}")
print(f"Secret: {webhook.secret}") # Save this for signature verification
# List webhooks
webhooks = client.list_webhooks()
for wh in webhooks:
print(f"{wh.id}: {wh.url}")
# Delete a webhook
client.delete_webhook(webhook.id)
# Verify webhook signature
from billionverify import BillionVerify
is_valid = BillionVerify.verify_webhook_signature(
payload=raw_body,
signature=signature_header,
secret="your-webhook-secret",
)from billionverify import (
BillionVerify,
AuthenticationError,
RateLimitError,
ValidationError,
InsufficientCreditsError,
NotFoundError,
TimeoutError,
)
try:
result = client.verify("user@example.com")
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except ValidationError as e:
print(f"Invalid input: {e.message}")
except InsufficientCreditsError:
print("Not enough credits")
except NotFoundError:
print("Resource not found")
except TimeoutError:
print("Request timed out")with BillionVerify(api_key="your-api-key") as client:
result = client.verify("user@example.com")
print(result.status)
# Connection is automatically closedThis SDK includes full type annotations for IDE support and type checking.
from billionverify import (
VerificationResult,
BulkVerifyResponse,
FileJobResponse,
CreditsResponse,
VerificationStatus,
)
def process_result(result: VerificationResult) -> None:
if result.status == "valid":
print(f"Email {result.email} is valid")
if result.is_deliverable and not result.is_disposable:
print("Safe to send to this email")The verification status can be one of:
valid- Email is valid and deliverableinvalid- Email is invalid or does not existunknown- Could not determine statusrisky- Email exists but may have delivery issuesdisposable- Temporary/disposable email addresscatchall- Domain accepts all emails (catch-all)role- Role-based email (e.g., info@, support@)
MIT