Python SDK

Official Python SDK for the Tratto Email API

The official SDK for Python: tratto-email. No external dependencies, built on urllib. Requires Python 3.10+.

Installation

pip install tratto-email

Initialization

from tratto import Tratto

client = Tratto('tratto_live_...')

Send Email

from tratto import SendEmailOptions

result = client.emails.send(SendEmailOptions(
    from_='[email protected]',
    to='[email protected]',
    subject='Hello!',
    html='<h1>Welcome!</h1>',
    text='Welcome to Tratto',
))

print(result['id'])  # email_abc123

Send with Template

result = client.emails.send(SendEmailOptions(
    from_='[email protected]',
    to='[email protected]',
    subject='Welcome to Acme!',
    template_id='tmpl_abc123',
    variables={
        'firstName': 'Alice',
        'code': 'SECRET123',
    },
))

Send with Markdown

The markdown field ships in SDK version 1.1.0, which is not published yet. On the current 1.0.0 release these examples fail — until then, call the REST API directly.

Send Markdown and let the server render responsive email HTML — markdown is mutually exclusive with html:

# Coming in 1.1.0
result = client.emails.send(SendEmailOptions(
    from_='[email protected]',
    to='[email protected]',
    subject='Welcome!',
    markdown='# Welcome, {{firstName}}!',
    variables={'firstName': 'Alice'},
))

The same release adds markdown to templates.create / templates.update (creating format: 'emailmd' templates), with format, source and renderWarnings in the template responses.

Schedule Email

result = client.emails.send(SendEmailOptions(
    from_='[email protected]',
    to='[email protected]',
    subject='Reminder',
    text='See you tomorrow!',
    scheduled_at='2025-07-01T09:00:00Z',
))

Get Email Status

email = client.emails.get('email_abc123')
print(email['data']['status'])  # 'delivered'

List Emails

response = client.emails.list(limit=50)
for email in response['data']:
    print(f"{email['id']}: {email['status']}")

Register a Domain

domain = client.domains.add('hello.yourdomain.com')
for record in domain['data']['records']:
    print(record['type'], record['host'], record['value'])

Verify Domain

result = client.domains.verify('dom_abc123')
print(result['data']['status'])  # 'pending', 'verified' or 'failed'

Create Contact

from tratto import CreateContactOptions

contact = client.contacts.create(CreateContactOptions(
    email='[email protected]',
    first_name='Alice',
    last_name='Smith',
    tags=['vip', 'newsletter'],
    custom_fields={'plan': 'pro'},
))

Create Campaign

from tratto import CreateCampaignOptions

campaign = client.campaigns.create(CreateCampaignOptions(
    name='Q3 Sale',
    template_id='tmpl_abc123',
    audience_id='aud_abc123',
    from_name='Acme Newsletter',
    from_email='[email protected]',
    subject_a='Our top picks for Q3',
))

print(campaign['data']['id'])

Send Campaign

sent = client.campaigns.send('camp_xyz789')
print(sent['data']['status'])  # 'sending'

Get Campaign Stats

stats = client.campaigns.get_stats('camp_xyz789')
print(stats['data']['stats']['delivered'])   # 4950
print(stats['data']['rates']['openRate'])    # 50 → 50%, rates are percentages

Register Webhook

from tratto import CreateWebhookOptions

webhook = client.webhooks.create(CreateWebhookOptions(
    url='https://yourapi.com/webhooks/tratto',
    events=['sent', 'delivered', 'opened', 'clicked', 'bounced'],
))

print(webhook['data']['secret'])  # whsec_xyz789... (returned only once)

Error Handling

from tratto import TrattoError

try:
    result = client.emails.send(SendEmailOptions(
        from_='[email protected]',
        to='[email protected]',
        subject='Hello',
        text='Test',
    ))
except TrattoError as e:
    if e.code == 'FORBIDDEN':
        # The message names the domain that is not verified.
        print(e)


Edit this page on GitHub

Last updated on