Python SDK
Official Python SDK for the Transactional Email, SMS, and Communication APIs.
The usetransactional Python SDK provides both synchronous and asynchronous clients for the Transactional API. Send emails, SMS messages, manage templates, suppressions, bounces, and more with full type hints and built-in error handling.
Installation
pip install usetransactionalQuick Start
from usetransactional import Transactional
client = Transactional(api_key="your-api-key")
response = client.emails.send(
from_email="sender@yourdomain.com",
to="recipient@example.com",
subject="Hello from Transactional",
html_body="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
text_body="Welcome! Thanks for signing up.",
)
print("Message ID:", response.message_id)Configuration
client = Transactional(
api_key="your-api-key",
base_url="https://api.usetransactional.com",
timeout=30,
retries=3,
)| Option | Type | Default | Description |
|---|---|---|---|
api_key | str | required | Your Transactional API key |
base_url | str | https://api.usetransactional.com | API base URL (override for self-hosted or testing) |
timeout | int | 30 | Request timeout in seconds |
retries | int | 3 | Number of automatic retries on transient failures |
Sync Client vs Async Client
The SDK provides two client classes. Use Transactional for synchronous code and AsyncTransactional for async/await workflows.
Sync Client
from usetransactional import Transactional
client = Transactional(api_key="your-api-key")
response = client.emails.send(
from_email="sender@yourdomain.com",
to="recipient@example.com",
subject="Hello",
html_body="<p>Hello, world!</p>",
)Async Client
The async client uses a context manager to properly manage connections:
from usetransactional import AsyncTransactional
async def main():
async with AsyncTransactional(api_key="your-api-key") as client:
response = await client.emails.send(
from_email="sender@yourdomain.com",
to="recipient@example.com",
subject="Hello",
html_body="<p>Hello, world!</p>",
)
print("Message ID:", response.message_id)Send an Email
response = client.emails.send(
from_email="sender@yourdomain.com",
to="recipient@example.com",
subject="Order Confirmation",
html_body="<h1>Your order is confirmed</h1>",
text_body="Your order is confirmed",
tag="order-confirmation",
)Send with a Template
response = client.emails.send_with_template(
from_email="sender@yourdomain.com",
to="recipient@example.com",
template_alias="welcome-email",
template_model={
"name": "Alice",
"company_name": "Acme Inc",
},
)Send Batch Emails
responses = client.emails.send_batch([
{
"from_email": "sender@yourdomain.com",
"to": "alice@example.com",
"subject": "Welcome, Alice!",
"html_body": "<p>Welcome aboard, Alice.</p>",
"tag": "welcome",
},
{
"from_email": "sender@yourdomain.com",
"to": "bob@example.com",
"subject": "Welcome, Bob!",
"html_body": "<p>Welcome aboard, Bob.</p>",
"tag": "welcome",
},
])SMS
Send an SMS
response = client.sms.send(
to="+15559876543",
template_alias="verification-code",
template_model={"code": "123456"},
)Send Batch SMS
responses = client.sms.sendBatch([
{
"to": "+15559876543",
"template_alias": "shipping-notification",
"template_model": {"tracking_id": "TRK123"},
},
{
"to": "+15551112222",
"template_alias": "shipping-notification",
"template_model": {"tracking_id": "TRK456"},
},
])Retrieve SMS Messages
# Get a specific SMS by ID
sms = client.sms.get("sms_abc123")
# List sent SMS messages
messages = client.sms.list()
# List inbound SMS messages (with optional count)
inbound = client.sms.list_inbound(count=50)Templates
List Templates
templates = client.templates.list()
for template in templates:
print(f"{template.id}: {template.name}")Get a Template
template = client.templates.get(template_id="template_abc123")
print("Subject:", template.subject)
print("HTML:", template.html_body)Create a Template
template = client.templates.create(
name="Welcome Email",
subject="Welcome to {{company_name}}",
html_body="<h1>Welcome, {{name}}!</h1><p>Thanks for joining {{company_name}}.</p>",
)
print("Created template:", template.id)Suppressions
Manage your suppression list to prevent sending to addresses that have opted out or bounced.
List Suppressions
suppressions = client.suppressions.list()
for entry in suppressions:
print(f"{entry.email} - {entry.reason}")Check an Email
result = client.suppressions.check("user@example.com")
print("Suppressed:", result.suppressed)Add a Suppression
client.suppressions.add(
email="user@example.com",
reason="manual-suppression",
)Remove a Suppression
client.suppressions.remove("user@example.com")Bounces
List Bounces
bounces = client.bounces.list()
for bounce in bounces:
print(f"{bounce.email} - {bounce.type} - {bounce.bounced_at}")Get a Bounce
bounce = client.bounces.get(bounce_id="bounce_abc123")
print("Email:", bounce.email)
print("Type:", bounce.type)
print("Description:", bounce.description)Reactivate a Bounced Email
If a bounce was transient, you can reactivate the email address for future sends:
client.bounces.activate("user@example.com")Error Handling
The SDK raises specific exceptions for different failure modes. All error classes are available in transactional.errors:
from usetransactional import Transactional
from usetransactional.errors import (
TransactionalError,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
)
client = Transactional(api_key="your-api-key")
try:
response = client.emails.send(
from_email="sender@yourdomain.com",
to="recipient@example.com",
subject="Test",
html_body="<p>Hello</p>",
)
except AuthenticationError:
print("Invalid API key. Check your credentials.")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds.")
except ValidationError as e:
print(f"Invalid request: {e.message}")
except NotFoundError:
print("Resource not found.")
except TransactionalError as e:
print(f"API error: {e.message}")Error Types
| Error Class | Description |
|---|---|
TransactionalError | Base error class for all SDK errors |
AuthenticationError | Invalid or missing API key (HTTP 401/403) |
RateLimitError | Too many requests; includes retry_after attribute (seconds) |
ValidationError | Request payload failed validation (HTTP 422) |
NotFoundError | Requested resource does not exist (HTTP 404) |
Async Support
For high-throughput applications or async frameworks like FastAPI, use the AsyncTransactional client with asyncio:
import asyncio
from usetransactional import AsyncTransactional
async def send_emails():
async with AsyncTransactional(api_key="your-api-key") as client:
# Send multiple emails concurrently
tasks = [
client.emails.send(
from_email="sender@yourdomain.com",
to=f"user{i}@example.com",
subject=f"Notification #{i}",
html_body=f"<p>Hello user {i}!</p>",
)
for i in range(10)
]
results = await asyncio.gather(*tasks)
for result in results:
print(f"Sent: {result.message_id}")
asyncio.run(send_emails())The async client supports all the same methods as the sync client, with await in front of each call. It uses async with as a context manager to properly open and close the underlying HTTP session.
Requirements
- Python 3.8 or later
On This Page
- Installation
- Quick Start
- Configuration
- Sync Client vs Async Client
- Sync Client
- Async Client
- Send an Email
- Send with a Template
- Send Batch Emails
- SMS
- Send an SMS
- Send Batch SMS
- Retrieve SMS Messages
- Templates
- List Templates
- Get a Template
- Create a Template
- Suppressions
- List Suppressions
- Check an Email
- Add a Suppression
- Remove a Suppression
- Bounces
- List Bounces
- Get a Bounce
- Reactivate a Bounced Email
- Error Handling
- Error Types
- Async Support
- Requirements