Python SDK
Pydantic models, type hints, async support, and automatic retries for SendMesh.
SDK packages will be published to PyPI soon. The API below shows the interface you can expect. Use the REST API directly in the meantime.
Installation
bash
pip install sendmesh
# For async support:
pip install sendmesh[async]Requires Python 3.8+. Uses httpx under the hood.
Initialization
python
from sendmesh import SendMesh
client = SendMesh(
api_key="sk_live_your_secret_key",
# Optional configuration:
base_url="https://api.sendmesh.co", # default
timeout=30, # seconds
max_retries=3, # retries on 5xx
)
# Async client:
from sendmesh import AsyncSendMesh
async_client = AsyncSendMesh(api_key="sk_live_your_secret_key")
response = await async_client.emails.send(...)Error Handling
python
from sendmesh import SendMesh, SendMeshError, ValidationError, RateLimitError
try:
client.emails.send(...)
except ValidationError as e:
print("Validation failed:", e.message)
print("Details:", e.details) # field-level errors
except RateLimitError as e:
print("Rate limited. Retry after:", e.retry_after)
except SendMeshError as e:
print("API error:", e.code, e.message, e.status_code)Method Reference
POST
emails.send()Send a single email to one or more recipients.
Parameters
python
from_email: dict # {"email": "...", "name": "..."}
to: list[dict] # [{"email": "...", "name": "..."}]
subject: str
html: str | None = None
text: str | None = None
reply_to: str | None = None
tags: list[str] | None = None
metadata: dict | None = None
template_id: str | None = None
template_data: dict | None = NoneReturns
python
SendResponse
.data["id"] # str - email ID
.data["status"] # str - "queued", "sent", "delivered"
.data["created_at"] # str - ISO timestampExample
python
response = client.emails.send(
from_email={"email": "hello@yourdomain.com", "name": "Your App"},
to=[{"email": "user@example.com", "name": "Jane Doe"}],
subject="Welcome to Our App!",
html="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
tags=["welcome", "transactional"],
)
print("Email ID:", response.data["id"])POST
emails.batch()Send up to 1,000 emails in a single batch request.
Parameters
python
from_email: dict
messages: list[dict] # each has "to", "subject", "html"/"text"Returns
python
BatchResponse
.data["batch_id"] # str
.data["queued"] # int
.data["failed"] # intExample
python
batch = client.emails.batch(
from_email={"email": "hello@yourdomain.com"},
messages=[
{"to": [{"email": "user1@example.com"}], "subject": "Hello 1", "html": "<p>Hi 1</p>"},
{"to": [{"email": "user2@example.com"}], "subject": "Hello 2", "html": "<p>Hi 2</p>"},
],
)
print(f"Queued: {batch.data['queued']}")GET
emails.list()List sent emails with filtering and cursor-based pagination.
Parameters
python
cursor: str | None = None
limit: int = 20 # max 100
status: str | None = None
from_date: str | None = None
to_date: str | None = NoneReturns
python
ListResponse
.data # list[dict] - email summaries
.meta["total"] # int
.meta["cursor"] # str | None
.meta["has_more"] # boolExample
python
emails = client.emails.list(limit=50, status="delivered")
for email in emails.data:
print(email["id"], email["subject"], email["status"])
if emails.meta["has_more"]:
next_page = client.emails.list(cursor=emails.meta["cursor"])GET
emails.get()Retrieve details of a specific email including delivery events.
Parameters
python
email_id: strReturns
python
EmailDetail
.data["id"] # str
.data["status"] # str
.data["events"] # list[dict]Example
python
email = client.emails.get("em_abc123def456")
print("Status:", email.data["status"])
for event in email.data["events"]:
print(event["type"], event["timestamp"])GitHub Repository
View source, report issues, and contribute.