Async-ready email SDK
The official Mailpipe Python SDK supports both synchronous and asynchronous usage patterns. Built with type hints throughout, it integrates naturally with Django, FastAPI, Flask, and any other Python web framework.
Install from PyPI using pip or your preferred package manager:
pip install mailpipe
poetry add mailpipe
uv add mailpipe
For async support, the SDK uses httpx under the hood. Install the async extras for full async functionality:
pip install "mailpipe[async]"
Requires Python 3.9 or later. All public APIs are fully annotated with type hints.
Initialize the synchronous client with your API key:
from mailpipe import MailpipeClient client = MailpipeClient(api_key="mp_live_your-api-key-here") # Or read from environment variable (recommended) import os client = MailpipeClient(api_key=os.environ["MAILPIPE_API_KEY"])
For async applications, use the async client:
from mailpipe import AsyncMailpipeClient
# Use as an async context manager for automatic cleanup
async with AsyncMailpipeClient(
api_key=os.environ["MAILPIPE_API_KEY"],
timeout=30.0,
max_retries=3,
) as client:
mailboxes = await client.mailboxes.list()
print(mailboxes)
# Or instantiate directly (remember to close when done)
client = AsyncMailpipeClient(api_key=os.environ["MAILPIPE_API_KEY"])
try:
# ... your code
finally:
await client.close()Synchronous
from mailpipe import MailpipeClient
client = MailpipeClient(api_key="mp_live_your-api-key-here")
message = client.messages.send(
from_email="noreply@yourdomain.com",
to=["user@example.com"],
subject="Welcome to our platform!",
html="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
text="Welcome! Thanks for signing up.",
)
print(f"Sent: {message.id}")Asynchronous
import asyncio
from mailpipe import AsyncMailpipeClient
async def send_welcome_email(user_email: str) -> str:
async with AsyncMailpipeClient(api_key="mp_live_your-api-key-here") as client:
message = await client.messages.send(
from_email="noreply@yourdomain.com",
to=[user_email],
subject="Welcome!",
html="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
)
return message.id
# Run standalone
message_id = asyncio.run(send_welcome_email("user@example.com"))Send to multiple recipients with CC, BCC, and custom headers:
message = client.messages.send(
from_email={"email": "invoices@acme.com", "name": "Acme Billing"},
to=["customer@example.com"],
cc=["accountant@acme.com"],
bcc=["archive@acme.com"],
reply_to="billing@acme.com",
subject="Your invoice #INV-2024-001",
html=invoice_html,
text=invoice_text,
headers={"X-Invoice-Id": "INV-2024-001"},
tags=["invoice", "billing"],
)Retrieve all mailboxes and list messages with filters:
from mailpipe import MailpipeClient
from mailpipe.types import Mailbox
client = MailpipeClient(api_key="mp_live_your-api-key-here")
# List all mailboxes
response = client.mailboxes.list()
for mailbox in response.data:
print(f"{mailbox.email} — {mailbox.unread_count} unread")
# List unread messages in a specific mailbox
messages = client.messages.list(
mailbox_id="mbx_01hx7k3abc",
unread=True,
limit=25,
)
for msg in messages.data:
print(f"[{msg.received_at}] {msg.subject} — from {msg.from_email}")The SDK raises typed exceptions for all API error conditions:
from mailpipe import MailpipeClient
from mailpipe.exceptions import (
MailpipeError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
)
client = MailpipeClient(api_key="mp_live_your-api-key-here")
try:
message = client.messages.send(
from_email="noreply@yourdomain.com",
to=["user@example.com"],
subject="Hello",
html="<p>Hello</p>",
)
except AuthenticationError:
print("Invalid API key — check your credentials")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except ValidationError as e:
print(f"Invalid request: {e.message}")
for field, errors in e.errors.items():
print(f" {field}: {', '.join(errors)}")
except MailpipeError as e:
print(f"API error {e.status_code}: {e.message}")
print(f"Request ID: {e.request_id}")Use Mailpipe as a Django email backend by adding a few settings:
# settings.py
EMAIL_BACKEND = "mailpipe.contrib.django.MailpipeEmailBackend"
MAILPIPE_API_KEY = env("MAILPIPE_API_KEY")
DEFAULT_FROM_EMAIL = "noreply@yourdomain.com"Now all standard Django email functions will route through Mailpipe:
from django.core.mail import send_mail, EmailMultiAlternatives
# Works with the standard Django API
send_mail(
subject="Welcome!",
message="Thanks for signing up.",
from_email="noreply@acme.com",
recipient_list=["user@example.com"],
)
# Or with HTML content
msg = EmailMultiAlternatives(
subject="Your receipt",
body=plain_text,
from_email="billing@acme.com",
to=["customer@example.com"],
)
msg.attach_alternative(html_content, "text/html")
msg.send()Inject the async client as a FastAPI dependency for clean async email sending:
from fastapi import FastAPI, Depends, BackgroundTasks
from mailpipe import AsyncMailpipeClient
import os
app = FastAPI()
async def get_mailpipe() -> AsyncMailpipeClient:
return AsyncMailpipeClient(api_key=os.environ["MAILPIPE_API_KEY"])
@app.post("/register")
async def register_user(
email: str,
background_tasks: BackgroundTasks,
mailpipe: AsyncMailpipeClient = Depends(get_mailpipe),
):
# Create user in DB...
user = await create_user(email)
# Send welcome email in the background
background_tasks.add_task(
mailpipe.messages.send,
from_email="welcome@acme.com",
to=[email],
subject="Welcome to Acme!",
html=f"<h1>Hi {user.name}!</h1><p>Thanks for joining.</p>",
)
return {"status": "created", "user_id": user.id}Explore the full REST API documentation with all available endpoints.
View API Reference