SendPigeon Python SDK
Official Python SDK for SendPigeon - Transactional Email API.
Installation
pip install sendpigeon
Quick Start
from sendpigeon import SendPigeon
client = SendPigeon("sk_live_xxx")
# Send an email
result = client.send(
to="user@example.com",
subject="Welcome!",
html="<h1>Hello!</h1><p>Welcome to our service.</p>"
)
if result.ok:
print(f"Email sent: {result.data.id}")
else:
print(f"Error: {result.error.message}")
Async Support
from sendpigeon import AsyncSendPigeon
async with AsyncSendPigeon("sk_live_xxx") as client:
result = await client.send(
to="user@example.com",
subject="Hello",
html="<p>Hi there!</p>"
)
Local Development
Use the SendPigeon CLI to catch emails locally:
# Terminal 1: Start local server
npx @sendpigeon-sdk/cli dev
# Terminal 2: Run your app with dev mode
SENDPIGEON_DEV=true python app.py
When SENDPIGEON_DEV=true, the SDK routes requests to localhost:4100 instead of production.
Features
Send Email
result = client.send(
to="user@example.com", # or ["a@x.com", "b@x.com"]
subject="Hello",
html="<p>HTML content</p>",
text="Plain text fallback",
from_="hello@yourdomain.com",
reply_to="support@yourdomain.com",
cc="cc@example.com",
bcc="bcc@example.com",
tags=["welcome", "onboarding"],
metadata={"user_id": "123"},
scheduled_at="2024-01-15T10:00:00Z",
)
Templates
# Use a template
result = client.send(
to="user@example.com",
template_id="tmpl_xxx",
variables={"name": "John", "company": "Acme"},
)
# Manage templates
templates = client.templates.list()
template = client.templates.create(
name="Welcome Email",
subject="Welcome, {{name}}!",
html="<p>Hi {{name}}, welcome to {{company}}!</p>"
)
Batch Sending
result = client.send_batch([
{"to": "a@example.com", "subject": "Hi A", "html": "<p>Hello A</p>"},
{"to": "b@example.com", "subject": "Hi B", "html": "<p>Hello B</p>"},
])
print(f"Sent: {result.data.summary['sent']}, Failed: {result.data.summary['failed']}")
Tracking
Enable open/click tracking per email (opt-in):
from sendpigeon import TrackingOptions
result = client.send(
to="user@example.com",
subject="Welcome!",
html='<p>Check out our <a href="https://example.com">site</a>!</p>',
tracking=TrackingOptions(opens=True, clicks=True),
)
# Response may include warnings if tracking is disabled at org level
if result.data.warnings:
print(f"Warnings: {result.data.warnings}")
Configure organization defaults in Settings → Tracking.
Domains
# List domains
domains = client.domains.list()
# Add and verify a domain
domain = client.domains.create("yourdomain.com")
print(f"Add these DNS records: {domain.data.dns_records}")
# Check verification
verification = client.domains.verify(domain.data.id)
print(f"Verified: {verification.data.verified}")
API Keys
# Create a new API key
key = client.api_keys.create(
name="Production",
mode="live",
permission="sending", # or "full_access"
)
print(f"Save this key: {key.data.key}") # Only shown once!
# List keys
keys = client.api_keys.list()
Webhook Verification
from sendpigeon import verify_webhook
result = verify_webhook(
payload=request.body,
signature=request.headers["X-Webhook-Signature"],
timestamp=request.headers["X-Webhook-Timestamp"],
secret="whsec_xxx",
)
if result.valid:
event = result.payload
print(f"Event: {event['type']}")
Error Handling
The SDK uses a Result pattern - no exceptions are thrown for API errors:
result = client.send(to="user@example.com", subject="Hi", html="<p>Hello</p>")
if result.error:
print(f"Error: {result.error.message}")
print(f"Code: {result.error.code}") # "api_error", "network_error", "timeout_error"
print(f"API Code: {result.error.api_code}") # e.g., "DOMAIN_NOT_VERIFIED"
print(f"Status: {result.error.status}") # HTTP status code
else:
print(f"Success: {result.data.id}")
# Or use unwrap() for quick scripts (raises on error)
email = client.send(...).unwrap()
Configuration
client = SendPigeon(
"sk_live_xxx",
base_url="https://api.sendpigeon.dev", # Override API URL
timeout=30.0, # Request timeout in seconds
max_retries=2, # Retry failed requests (0-5)
debug=True, # Log requests/responses
)
License
MIT
Release files for sendpigeon 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sendpigeon-0.5.0.tar.gz | 15.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sendpigeon-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.1 kB
Release files / sendpigeon-0.5.0.tar.gz
| Download URL | sendpigeon-0.5.0.tar.gz |
|---|---|
| Size | 15.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed18759578e2024f1d4940da736d8a7af942e5ae5de9b7b2019635b3f166ce59
|
|
BLAKE2b-256 checksum How to use checksums |
86b315db4262177df627f611677619ca0396c55a554f166c2bb8cd999c81b11a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / sendpigeon-0.5.0-py3-none-any.whl
| Download URL | sendpigeon-0.5.0-py3-none-any.whl |
|---|---|
| Size | 21.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
39c32c87fa9f329b00940473efb61022098d62ebfedc354eca0fffb1190e3675
|
|
BLAKE2b-256 checksum How to use checksums |
153909547452c145092d81b16e04cd895cb3ae542496c74ebbcc5a2a3e6150c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|