Skip to main content

BillionVerify Python SDK

Official Python SDK for the BillionVerify email verification API.

PyPI version Python Versions

PyPI: https://pypi.org/project/billionverify/ Documentation: https://billionverify.com/docs

Installation

pip install billionverify

Quick Start

from 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 False

Configuration

client = 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)
)

Single Email Verification

Uses the /verify/single endpoint:

result = client.verify(
    email="user@example.com",
    check_smtp=True,  # Optional: Perform SMTP verification (default: True)
    force_refresh=False,  # Optional: Bypass cache and force live verification (default: False)
    include_domain_reputation=False,  # Optional: Include domain reputation details (default: False)
)

# 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.check_smtp)         # True (whether SMTP was performed)
print(result.domain_suggestion)  # None or suggested domain correction
print(result.credits_used)       # 1

# Response metadata for audit logs and throttled runners
print(result.response_metadata.request_id)             # Server X-Request-ID
print(result.response_metadata.rate_limit_remaining)   # Remaining requests in current window

Bulk Email Verification (Synchronous)

Verify 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_emails}")
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}")

File Upload (Async Verification)

For large lists, use upload_file() for asynchronous file verification:

# Upload a file for async verification
task = 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"Task ID: {task.task_id}")
print(f"Status: {task.status}")
print(f"Estimated count: {task.estimated_count}")

# Get task status (with optional long-polling)
status = client.get_file_task_status(
    task_id=task.task_id,
    timeout=60,  # Long-poll for up to 60 seconds (0-300)
)
print(f"Progress: {status.progress}%")
print(f"Processed: {status.processed_emails}/{status.total_emails}")

# Wait for completion (polling)
completed = client.wait_for_file_task(
    task_id=task.task_id,
    poll_interval=5.0,  # seconds
    max_wait=600.0,     # seconds
)

# Download results as CSV with optional filters
output_file = client.download_file_results(
    task_id=task.task_id,
    output_path="results.csv",
    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
)
print(f"Results saved to: {output_file}")

Async Support

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())

Health Check

Check API health status (no authentication required):

health = client.health_check()
print(health.status)   # 'ok'
print(health.version)  # API version

Credits

credits = 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 name

Webhooks

Webhooks 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",
)

Error Handling

from billionverify import (
    BillionVerify,
    BillionVerifyError,
    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")
    print(f"Request ID: {e.response_metadata.request_id}")
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")
except BillionVerifyError as e:
    # Catch-all for anything else, including the response-shape codes below.
    print(f"{e.code}: {e.message}")

Malformed or empty server responses

The SDK never lets a malformed API reply leak out as a raw KeyError, TypeError, or json.JSONDecodeError. Empty bodies, null payloads, non-JSON content, and responses missing required fields are all surfaced as a typed BillionVerifyError with response_metadata populated, so you can recover and log the request ID:

error.code When it fires
EMPTY_RESPONSE 2xx with no body, or envelope {"data": null}
INVALID_RESPONSE Non-JSON body, wrong top-level shape, or missing fields
try:
    result = client.verify("user@example.com")
except BillionVerifyError as e:
    if e.code in ("EMPTY_RESPONSE", "INVALID_RESPONSE"):
        log.error("bad upstream reply", extra={
            "request_id": e.response_metadata.request_id,
            "status": e.response_metadata.status_code,
            "details": e.details,
        })
    raise

Context Manager

with BillionVerify(api_key="your-api-key") as client:
    result = client.verify("user@example.com")
    print(result.status)
# Connection is automatically closed

Type Hints

This SDK includes full type annotations for IDE support and type checking.

from billionverify import (
    VerificationResult,
    BulkVerifyResponse,
    FileUploadResponse,
    FileTaskStatus,
    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")

Status Values

The verification status can be one of:

  • valid - Email is valid and deliverable
  • invalid - Email is invalid or does not exist
  • unknown - Could not determine status
  • risky - Email exists but may have delivery issues
  • disposable - Temporary/disposable email address
  • catchall - Domain accepts all emails (catch-all)
  • role - Role-based email (e.g., info@, support@)

License

MIT

Metadata

Release files for billionverify 1.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for billionverify 1.2.2
File Size Uploaded Provenance Actions
billionverify-1.2.2.tar.gz 26.3 kB With provenance Details for billionverify-1.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for billionverify 1.2.2
File Interpreter ABI Platform Actions
billionverify-1.2.2-py3-none-any.whl Python 3 none any Details for billionverify-1.2.2-py3-none-any.whl

Total release size: 41.6 kB

Release files / billionverify-1.2.2.tar.gz

Download URL billionverify-1.2.2.tar.gz
Size 26.3 kB
Tags Source
SHA-256 checksum
How to use checksums
72def2affa296ef6ee7eb6232a54cac6e825d29b42e6e77357ef30fd79df8f5d
BLAKE2b-256 checksum
How to use checksums
9151c325cc9b0cf95e2668f4989ad62285b3185e566163a037859fcae464719a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / billionverify-1.2.2-py3-none-any.whl

Download URL billionverify-1.2.2-py3-none-any.whl
Size 15.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7fb92d81c925dbaf68b4c7e8afd54d08ed924288a24f7fd708cbc86f36c1842b
BLAKE2b-256 checksum
How to use checksums
a8d268d61f79dbb7f43b196e38b8f15c1f90a64866ffa978b3eaf344a71df5b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for billionverify 1.2.2

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for billionverify-1.2.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page