ToSend Python SDK
Official Python SDK for the ToSend email API.
Installation
pip install tosend
Examples
See the examples folder for complete working examples:
- Send Email - Send a single email
- Batch Send - Send multiple emails in one request
- Account Info - Get account information and domains
export TOSEND_API_KEY=tsend_your_api_key
python examples/send_email.py
Quick Start
from tosend import ToSend
client = ToSend("tsend_your_api_key")
response = client.send(
from_address={"email": "hello@yourdomain.com", "name": "Your App"},
to=[{"email": "user@example.com"}],
subject="Welcome!",
html="<h1>Hello!</h1><p>Thanks for signing up.</p>",
)
print(response.message_id)
Usage
Send an Email
response = client.send(
from_address={"email": "hello@yourdomain.com", "name": "Your App"},
to=[
{"email": "user@example.com"},
{"email": "another@example.com", "name": "John Doe"},
],
subject="Hello!",
html="<h1>Welcome</h1>",
text="Welcome", # optional
)
With CC, BCC, and Reply-To
response = client.send(
from_address={"email": "hello@yourdomain.com"},
to=[{"email": "user@example.com"}],
cc=[{"email": "cc@example.com"}],
bcc=[{"email": "bcc@example.com"}],
reply_to={"email": "support@yourdomain.com", "name": "Support"},
subject="Hello",
html="<p>Hello World</p>",
)
With Attachments
import base64
with open("invoice.pdf", "rb") as f:
content = base64.b64encode(f.read()).decode()
response = client.send(
from_address={"email": "hello@yourdomain.com"},
to=[{"email": "user@example.com"}],
subject="Your Invoice",
html="<p>Please find your invoice attached.</p>",
attachments=[
{
"type": "application/pdf",
"name": "invoice.pdf",
"content": content,
}
],
)
Batch Sending
Send multiple emails in a single request:
response = client.batch([
{
"from": {"email": "hello@yourdomain.com"},
"to": [{"email": "user1@example.com"}],
"subject": "Hello User 1",
"html": "<p>Welcome!</p>",
},
{
"from": {"email": "hello@yourdomain.com"},
"to": [{"email": "user2@example.com"}],
"subject": "Hello User 2",
"html": "<p>Welcome!</p>",
},
])
for result in response.results:
if result.status == "success":
print(f"Sent: {result.message_id}")
else:
print(f"Failed: {result.message}")
Get Account Info
info = client.get_account_info()
print(info.account.status) # "active"
print(info.account.credit_balance) # None means the account does not consume credits
print(info.account.limit_per_second)
print(info.account.bounce_rate) # a fraction between 0 and 1
for domain in info.domains:
print(f"{domain.domain_name}: {domain.verification_status}")
Admin API
ToSendAdmin is a separate client for the Admin API. It takes an admin key (tsend_admin_...) and refuses a sending key at construction. Each call needs the matching scope on the key; a missing one raises ToSendError with status 403 and error.code == "insufficient_scope".
import os
from tosend import ToSendAdmin
admin = ToSendAdmin(os.environ["TOSEND_ADMIN_KEY"])
# Act on one of your client teams (sends X-Account-Id)
client = admin.for_account(4203)
domain = client.create_domain("client.example.com")
detail = client.get_domain(domain["id"])
print(detail["dns_records"]["dkim"]) # show these records to your client
# Needs api_keys:write and emails:send
key = client.create_sending_key("Client: Acme Corp")
print(key["api_key"]) # returned once, store it now
# Needs emails:send
client.send(
from_address={"email": "hello@client.example.com"},
to=[{"email": "user@example.com"}],
subject="Hi",
html="<p>Hello</p>",
)
Also available: get_info, list_domains, delete_domain, list_emails, get_email, list_suppressions, delete_suppression, list_webhooks, create_webhook, update_webhook, delete_webhook, list_sending_keys, delete_sending_key, list_teams, create_team, update_team and batch. List methods take page and per_page and return a dict with data, total, page and per_page; single-resource methods return the resource as a dict.
Configuration
With Options
client = ToSend(
api_key="tsend_your_api_key",
base_url="https://api.tosend.com", # optional
timeout=60, # optional, in seconds
)
Error Handling
from tosend import ToSend, ToSendError
client = ToSend("tsend_your_api_key")
try:
response = client.send(
from_address={"email": "hello@yourdomain.com"},
to=[{"email": "user@example.com"}],
subject="Hello",
html="<p>Hello</p>",
)
except ToSendError as e:
print(f"Error: {e.message}")
print(f"Status: {e.status_code}")
print(f"Type: {e.error_type}")
print(f"Details: {e.errors}")
if e.is_validation_error:
# Handle validation error (422)
pass
if e.is_authentication_error:
# Handle auth error (401/403)
pass
if e.is_rate_limit_error:
# Handle rate limit (429)
pass
Type Hints
The SDK includes full type hints. You can also use the provided dataclasses:
from tosend import ToSend, Address, SendEmailRequest
client = ToSend("tsend_your_api_key")
# Using Address dataclass
from_addr = Address(email="hello@yourdomain.com", name="Your App")
to_addr = Address(email="user@example.com")
response = client.send(
from_address=from_addr,
to=[to_addr],
subject="Hello!",
html="<h1>Welcome!</h1>",
)
Requirements
- Python 3.8 or higher
- No external dependencies (uses only standard library)
License
MIT
Release files for tosend 1.1.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 | |
|---|---|---|---|
| tosend-1.1.0.tar.gz | 15.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tosend-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.6 kB
Release files / tosend-1.1.0.tar.gz
| Download URL | tosend-1.1.0.tar.gz |
|---|---|
| Size | 15.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4a18baac97b6d38864f033011d0b42c6437a612e74f40af02ac0ef4e8f4a2e78
|
|
BLAKE2b-256 checksum How to use checksums |
b709685d1484f70c34bc77167d0497631fd1c10c9e2623d9f78477b1a1679232
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / tosend-1.1.0-py3-none-any.whl
| Download URL | tosend-1.1.0-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f08a4cd2c3981609421bfb978070cc47827a1d5b27013c20bfeee949a2e4d4c6
|
|
BLAKE2b-256 checksum How to use checksums |
ff0e04ef80f7d964e4a4dd42999b88e828634971da09ec161542ed172de644a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|