Package:
unosend · Python: 3.8+ · Type hints: Full support includedInstallation
Copy
pip install unosend
Quick Start
Copy
from unosend import Unosend
client = Unosend(api_key="un_your_api_key")
result = client.emails.send(
from_email="hello@yourdomain.com",
to=["user@example.com"],
subject="Hello from Unosend!",
html="<h1>Welcome!</h1><p>Thanks for signing up.</p>"
)
print(f"Email sent: {result.id}")
Configuration
Copy
from unosend import Unosend
client = Unosend(
api_key="un_your_api_key",
base_url="https://www.unosend.co/api/v1", # default
timeout=30, # request timeout in seconds (default: 30)
)
Never hardcode your API key. Use environment variables:
os.environ["UNOSEND_API_KEY"]Emails
Send an Email
Copy
result = client.emails.send(
from_email="John Doe <john@yourdomain.com>",
to=["user@example.com"],
subject="Order Confirmation",
html="<h1>Order #1234</h1><p>Your order has been confirmed.</p>",
text="Order #1234 - Your order has been confirmed.",
reply_to="support@yourdomain.com",
cc=["manager@yourdomain.com"],
bcc=["archive@yourdomain.com"],
tags=[{"name": "category", "value": "order"}],
headers={"X-Entity-Ref-ID": "order-1234"},
tracking={"open": True, "click": True},
)
Send with Attachments
Copy
import base64
with open("invoice.pdf", "rb") as f:
pdf_content = base64.b64encode(f.read()).decode()
result = client.emails.send(
from_email="billing@yourdomain.com",
to=["customer@example.com"],
subject="Your Invoice",
html="<p>Please find your invoice attached.</p>",
attachments=[
{
"filename": "invoice.pdf",
"content": pdf_content,
"content_type": "application/pdf",
}
],
)
Send with Templates
Copy
result = client.emails.send(
from_email="hello@yourdomain.com",
to=["user@example.com"],
subject="Welcome, {{first_name}}!",
template_id="tmpl_abc123",
template_data={
"first_name": "Alice",
"company": "Acme Inc",
},
)
Schedule an Email
Copy
result = client.emails.send(
from_email="hello@yourdomain.com",
to=["user@example.com"],
subject="Scheduled Newsletter",
html="<h1>Weekly Digest</h1>",
scheduled_for="2026-03-15T09:00:00Z",
)
Send Batch Emails
Copy
results = client.emails.send_batch([
{
"from": "hello@yourdomain.com",
"to": ["alice@example.com"],
"subject": "Welcome, Alice!",
"html": "<h1>Welcome!</h1>",
},
{
"from": "hello@yourdomain.com",
"to": ["bob@example.com"],
"subject": "Welcome, Bob!",
"html": "<h1>Welcome!</h1>",
},
])
Get Email Details
Copy
email = client.emails.get("email_abc123")
print(email.status) # 'delivered'
print(email.opened_at) # '2026-02-28T10:30:00Z'
List Emails
Copy
emails = client.emails.list(limit=50, status="delivered")
for email in emails.data:
print(f"{email.to} — {email.status}")
Domains
Add and Verify a Domain
Copy
# Create domain
domain = client.domains.create(domain="yourdomain.com")
print("Add these DNS records:", domain.dns_records)
# After adding DNS records, verify
verified = client.domains.verify(domain.id)
print(f"Verified: {verified.verified}")
Contacts & Audiences
Create an Audience
Copy
audience = client.audiences.create(name="Newsletter Subscribers")
Add a Contact
Copy
contact = client.contacts.create(
audience_id=audience.id,
email="user@example.com",
first_name="Alice",
last_name="Smith",
metadata={"plan": "pro", "signed_up": "2026-01-15"},
)
List Contacts
Copy
contacts = client.contacts.list(audience_id=audience.id, limit=100)
print(f"Total: {contacts.total} contacts")
SMS
Send an SMS
Copy
sms = client.sms.send(
to="+14155551234",
message="Your verification code is 384729. Expires in 10 minutes.",
)
print(f"SMS sent: {sms.id}")
print(f"Cost: ${sms.cost}")
Send Batch SMS
Copy
result = client.sms.send_batch(
messages=[
{"to": "+14155551234", "message": "Your code is 123456"},
{"to": "+447700900123", "message": "Your code is 654321"},
]
)
Send a Template Message
Copy
result = client.whatsapp.send(
to="+919876543210",
type="template",
template="order_update",
language="en",
variables=["Alice", "ORD-1234"],
)
Send a Chat Message
Copy
result = client.whatsapp.send(
to="+919876543210",
type="chat",
message="Your order has shipped! Track: https://track.example.com/1234",
)
Webhooks
Copy
webhook = client.webhooks.create(
url="https://yourapp.com/api/unosend-webhook",
events=["email.delivered", "email.bounced", "email.opened"],
)
print(f"Signing secret: {webhook.signing_secret}")
Validation
Copy
result = client.validation.validate_email(email="user@example.com")
print(result.valid) # True
print(result.disposable) # False
print(result.has_mx) # True
print(result.confidence) # 95
Error Handling
Copy
from unosend import Unosend
from unosend.exceptions import (
UnosendError,
AuthenticationError,
ValidationError,
RateLimitError,
)
client = Unosend(api_key="un_your_api_key")
try:
result = client.emails.send(
from_email="hello@yourdomain.com",
to=["user@example.com"],
subject="Hello",
html="<h1>Hello</h1>",
)
print(f"Sent: {result.id}")
except AuthenticationError:
print("Invalid API key")
except ValidationError as e:
print(f"Validation error: {e.message}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except UnosendError as e:
print(f"Error {e.status_code}: {e.message}")
Framework Examples
Django
Copy
# views.py
from django.http import JsonResponse
from unosend import Unosend
client = Unosend(api_key=settings.UNOSEND_API_KEY)
def send_welcome_email(request):
if request.method == "POST":
data = json.loads(request.body)
result = client.emails.send(
from_email="welcome@yourdomain.com",
to=[data["email"]],
subject=f"Welcome, {data['name']}!",
html=f"<h1>Welcome, {data['name']}!</h1>",
)
return JsonResponse({"id": result.id})
Flask
Copy
from flask import Flask, request, jsonify
from unosend import Unosend
app = Flask(__name__)
client = Unosend(api_key=os.environ["UNOSEND_API_KEY"])
@app.post("/send-email")
def send_email():
data = request.json
result = client.emails.send(
from_email="hello@yourdomain.com",
to=[data["email"]],
subject=data["subject"],
html=data["html"],
)
return jsonify({"id": result.id})
FastAPI
Copy
from fastapi import FastAPI
from unosend import Unosend
from pydantic import BaseModel
app = FastAPI()
client = Unosend(api_key=os.environ["UNOSEND_API_KEY"])
class EmailRequest(BaseModel):
email: str
subject: str
html: str
@app.post("/send-email")
async def send_email(req: EmailRequest):
result = client.emails.send(
from_email="hello@yourdomain.com",
to=[req.email],
subject=req.subject,
html=req.html,
)
return {"id": result.id}
Environment Variables
.env
Copy
UNOSEND_API_KEY=un_your_api_key
Full API Reference
See all available endpoints and parameters