Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mailbreeze.com/llms.txt

Use this file to discover all available pages before exploring further.

Installation

pip install mailbreeze

Requirements

  • Python 3.10+
  • httpx for HTTP requests
  • pydantic for type validation

Quick Start

import asyncio
from mailbreeze import MailBreeze

async def main():
    client = MailBreeze(api_key="sk_live_xxx")

    result = await client.emails.send(
        from_="hello@yourdomain.com",
        to="user@example.com",
        subject="Welcome!",
        html="<h1>Welcome to our platform!</h1>",
    )

    print(f"Email sent: {result.id}")

asyncio.run(main())

Configuration

client = MailBreeze(
    api_key="sk_live_xxx",                    # Required
    base_url="https://api.mailbreeze.com",    # Optional: custom API URL
    timeout=30.0,                             # Optional: request timeout (seconds)
    max_retries=3,                            # Optional: max retry attempts
)

Resources

Emails

# Send email
result = await client.emails.send(
    from_="hello@yourdomain.com",  # Note: from_ to avoid Python keyword
    to="user@example.com",
    subject="Hello",
    html="<p>Hello!</p>",
)

# Send with template
result = await client.emails.send(
    from_="hello@yourdomain.com",
    to="user@example.com",
    template_id="welcome-template",
    variables={"name": "John"},
)

# List emails
result = await client.emails.list(
    status="delivered",
    page=1,
    limit=20,
)
for email in result.data:
    print(email.subject)

# Get email
email = await client.emails.get("msg_xxx")

# Get stats
stats = await client.emails.stats()
print(f"Total: {stats.total}, Sent: {stats.sent}, Success rate: {stats.success_rate}%")

Attachments

import aiohttp

# Create upload URL
upload = await client.attachments.create_upload(
    file_name="report.pdf",
    content_type="application/pdf",
    file_size=1024000,
)

# Upload file
with open("report.pdf", "rb") as f:
    file_data = f.read()

async with aiohttp.ClientSession() as session:
    await session.put(
        upload.upload_url,
        data=file_data,
        headers={"Content-Type": "application/pdf"},
    )

# Confirm upload
await client.attachments.confirm(upload_token=upload.upload_token)

# Use in email
await client.emails.send(
    attachment_ids=[upload.attachment_id],
    # ... other params
)

Lists

# Create list
list_ = await client.lists.create(
    name="Newsletter",
    custom_fields=[
        {"key": "company", "label": "Company", "type": "text"},
    ],
)

# List all
result = await client.lists.list()

# Get, update, delete
list_ = await client.lists.get("lst_xxx")
await client.lists.update("lst_xxx", name="New Name")
await client.lists.delete("lst_xxx")

# Get stats
stats = await client.lists.stats("lst_xxx")

Contacts

# Get contacts for a list
contacts = client.contacts("lst_xxx")

# Create contact
contact = await contacts.create(
    email="user@example.com",
    first_name="John",
    custom_fields={"company": "Acme"},
)

# List, get, update, delete
result = await contacts.list(status="active")
contact = await contacts.get("cnt_xxx")
await contacts.update("cnt_xxx", first_name="Jane")
await contacts.delete("cnt_xxx")

# Suppress contact
await contacts.suppress("cnt_xxx", "bounced")

Verification

# Verify single email
result = await client.verification.verify(email="user@example.com")
if result.is_valid:
    print("Safe to send")

# Batch verify
batch = await client.verification.batch(
    emails=["user1@example.com", "user2@example.com"]
)

# Poll for results
status = await client.verification.get(batch.verification_id)

# List and stats
result = await client.verification.list()
stats = await client.verification.stats()

Error Handling

from mailbreeze import MailBreeze, MailBreezeError

try:
    await client.emails.send(...)
except MailBreezeError as e:
    print(e.code)     # e.g., "VALIDATION_ERROR"
    print(e.message)  # Human-readable message
    print(e.status)   # HTTP status code

    # Handle specific errors
    if e.code == "DNS_VERIFICATION_FAILED":
        # Domain not verified
        pass
    elif e.code == "RATE_LIMIT_EXCEEDED":
        # Retry after delay
        pass

Type Hints

Full Pydantic models for all params and responses:
from mailbreeze import MailBreeze
from mailbreeze.types import SendEmailParams, Email, EmailStats

params = SendEmailParams(
    from_="hello@yourdomain.com",
    to=["user@example.com"],
    subject="Hello",
    html="<p>Hello!</p>",
)

result: Email = await client.emails.send(**params.model_dump())

Synchronous Usage

For synchronous code, use asyncio.run():
import asyncio
from mailbreeze import MailBreeze

client = MailBreeze(api_key="sk_live_xxx")

# Sync wrapper
def send_email():
    return asyncio.run(client.emails.send(
        from_="hello@yourdomain.com",
        to="user@example.com",
        subject="Hello",
        html="<p>Hello!</p>",
    ))

result = send_email()

Features

  • Async/await - Full async support with httpx
  • Type-safe - Pydantic models for all types
  • Automatic retries - Exponential backoff for failures
  • 99% test coverage

PyPI Package

View on PyPI

GitHub

Source code