Skip to main content
Package: unosend · Python: 3.8+ · Type hints: Full support included

Installation

pip install unosend

Quick Start

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

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

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

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

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

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

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

email = client.emails.get("email_abc123")

print(email.status)      # 'delivered'
print(email.opened_at)   # '2026-02-28T10:30:00Z'

List Emails

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

# 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

audience = client.audiences.create(name="Newsletter Subscribers")

Add a Contact

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

contacts = client.contacts.list(audience_id=audience.id, limit=100)
print(f"Total: {contacts.total} contacts")

SMS

Send an SMS

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

result = client.sms.send_batch(
    messages=[
        {"to": "+14155551234", "message": "Your code is 123456"},
        {"to": "+447700900123", "message": "Your code is 654321"},
    ]
)

WhatsApp

Send a Template Message

result = client.whatsapp.send(
    to="+919876543210",
    type="template",
    template="order_update",
    language="en",
    variables=["Alice", "ORD-1234"],
)

Send a Chat Message

result = client.whatsapp.send(
    to="+919876543210",
    type="chat",
    message="Your order has shipped! Track: https://track.example.com/1234",
)

Webhooks

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

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

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

# 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

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

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
UNOSEND_API_KEY=un_your_api_key

Full API Reference

See all available endpoints and parameters