SDK
Python SDK
Official Python SDK for send0 with sync and async support.
Installation
pip install send0Requirements: Python >= 3.9
- Powered by
httpxfor HTTP with connection pooling - Pydantic v2 models for type safety and validation
- Both sync (
Send0) and async (AsyncSend0) clients - Zero configuration — just pass your API key
Quick start
from send0 import Send0
client = Send0("sk_live_...")
# Send an email
email = client.emails.send(
from_address="hello@yourdomain.com",
to="user@example.com",
subject="Welcome!",
html="<p>Hello from send0</p>",
)
print(email.id) # em_xxxx
print(email.status) # 'queued'Async support
from send0 import AsyncSend0
client = AsyncSend0("sk_live_...")
async def main():
email = await client.emails.send(
from_address="hello@yourdomain.com",
to="user@example.com",
subject="Welcome!",
html="<p>Hello from send0</p>",
)
print(email.id)
await client.close()Context managers
Both clients support context managers for automatic cleanup:
# Sync
with Send0("sk_live_...") as client:
email = client.emails.send(...)
# Async
async with AsyncSend0("sk_live_...") as client:
email = await client.emails.send(...)Available resources
| Resource | Description |
|---|---|
client.emails | Send, get, list, batch, cancel emails |
client.contacts | Create, update, list, delete contacts |
client.templates | Manage email templates |
client.domains | Domain verification and management |
Configuration
client = Send0(
"sk_live_...",
base_url="https://api.send0.dev/v1", # Custom API URL
timeout=60.0, # Request timeout in seconds
max_retries=5, # Max retry attempts for 5xx
)| Option | Type | Default | Description |
|---|---|---|---|
base_url | str | https://api.send0.dev/v1 | API base URL |
timeout | float | 30.0 | Request timeout in seconds |
max_retries | int | 3 | Max retry attempts for 5xx errors |
Error handling
from send0 import Send0
from send0.errors import APIError, RateLimitError, ValidationError
client = Send0("sk_live_...")
try:
email = client.emails.send(...)
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except APIError as e:
print(f"{e.code}: {e.message} (HTTP {e.status_code})")Error classes
| Class | Description |
|---|---|
Send0Error | Base class for all SDK errors |
APIError | API returned an error response (4xx/5xx) |
RateLimitError | Rate limit exceeded (429) |
NetworkError | Connection or timeout error |
ConfigError | Invalid configuration (bad API key, etc.) |
WebhookVerificationError | Webhook signature verification failed |
Webhook verification
from send0 import Webhooks
event = Webhooks.verify(
payload=request.body,
headers=request.headers,
secret="whsec_...",
)
print(event["type"]) # "email.delivered"Batch send
result = client.emails.batch(
from_address="hello@acme.com",
subject="Monthly Update",
template="tmpl_monthly",
recipients=[
{"to": "jane@example.com", "variables": {"name": "Jane"}},
{"to": "john@example.com", "variables": {"name": "John"}},
],
)
print(result.count) # 2Contacts
# Create
contact = client.contacts.create(
email="jane@example.com",
first_name="Jane",
last_name="Doe",
tags={"segment": "enterprise"},
)
# List
contacts = client.contacts.list(limit=50)
for c in contacts.data:
print(c.email)
# Batch upsert
result = client.contacts.batch_upsert(contacts=[
{"email": "jane@example.com", "first_name": "Jane"},
{"email": "john@example.com", "first_name": "John"},
])Templates
# Create
template = client.templates.create(
name="welcome",
subject="Welcome to {{company}}!",
html="<h1>Welcome, {{name}}!</h1>",
)
# Preview
preview = client.templates.preview(
template.id,
data={"name": "Jane", "company": "Acme"},
)
print(preview.html)Domains
# Add a domain
domain = client.domains.create(domain="mail.acme.com")
# Print DNS records to configure
for record in domain.dns_records:
print(f"{record.type} {record.name} → {record.value}")
# Verify after DNS configuration
result = client.domains.verify(domain.id)
print(result.status) # 'verified'