Skip to content

emailit/emailit-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emailit Python

Tests PyPI Version License

The official Python SDK for the Emailit Email API.

Requirements

Installation

pip install emailit

Getting Started

from emailit import EmailitClient

client = EmailitClient("your_api_key")

email = client.emails.send({
    "from": "hello@yourdomain.com",
    "to": ["user@example.com"],
    "subject": "Hello from Emailit",
    "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
})

print(email.id)      # em_abc123...
print(email.status)  # pending

All service methods return typed resource objects (Email, Domain, Contact, etc.) with direct attribute access -- just like the Stripe SDK.

Available Services

Service Property Description
Emails client.emails Send, list, get, cancel, retry emails
Domains client.domains Create, verify, list, manage sending domains
API Keys client.api_keys Create, list, manage API keys
Audiences client.audiences Create, list, manage audiences
Subscribers client.subscribers Add, list, manage subscribers in audiences
Templates client.templates Create, list, publish email templates
Suppressions client.suppressions Create, list, manage suppressed addresses
Email Verifications client.email_verifications Verify email addresses
Email Verification Lists client.email_verification_lists Create, list, get results, export
Webhooks client.webhooks Create, list, manage webhooks
Contacts client.contacts Create, list, manage contacts
Events client.events List and retrieve events

Usage

Emails

Send an email

email = client.emails.send({
    "from": "hello@yourdomain.com",
    "to": ["user@example.com"],
    "subject": "Hello from Emailit",
    "html": "<h1>Welcome!</h1>",
})

print(email.id)
print(email.status)

Send with a template

email = client.emails.send({
    "from": "hello@yourdomain.com",
    "to": "user@example.com",
    "template": "welcome_email",
    "variables": {
        "name": "John Doe",
        "company": "Acme Inc",
    },
})

Send with attachments

import base64

email = client.emails.send({
    "from": "invoices@yourdomain.com",
    "to": "customer@example.com",
    "subject": "Your Invoice #12345",
    "html": "<p>Please find your invoice attached.</p>",
    "attachments": [
        {
            "filename": "invoice.pdf",
            "content": base64.b64encode(open("invoice.pdf", "rb").read()).decode(),
            "content_type": "application/pdf",
        },
    ],
})

Schedule an email

email = client.emails.send({
    "from": "reminders@yourdomain.com",
    "to": "user@example.com",
    "subject": "Appointment Reminder",
    "html": "<p>Your appointment is tomorrow at 2 PM.</p>",
    "scheduled_at": "2026-01-10T09:00:00Z",
})

print(email.status)        # scheduled
print(email.scheduled_at)  # 2026-01-10T09:00:00Z

List emails

emails = client.emails.list({"page": 1, "limit": 10})

for email in emails:
    print(f"{email.id}{email.status}")

if emails.has_more():
    # fetch next page
    pass

Cancel / Retry

client.emails.cancel("em_abc123")
client.emails.retry("em_abc123")

Domains

# Create a domain
domain = client.domains.create({
    "name": "example.com",
    "track_loads": True,
    "track_clicks": True,
})
print(domain.id)

# Verify DNS
domain = client.domains.verify("sd_123")

# List all domains
domains = client.domains.list()

# Get a domain
domain = client.domains.get("sd_123")

# Update a domain
domain = client.domains.update("sd_123", {"track_clicks": False})

# Delete a domain
client.domains.delete("sd_123")

API Keys

# Create an API key
key = client.api_keys.create({
    "name": "Production Key",
    "scope": "full",
})
print(key.key)  # only available on create

# List all API keys
keys = client.api_keys.list()

# Get an API key
key = client.api_keys.get("ak_123")

# Update an API key
client.api_keys.update("ak_123", {"name": "Renamed Key"})

# Delete an API key
client.api_keys.delete("ak_123")

Audiences

# Create an audience
audience = client.audiences.create({"name": "Newsletter"})
print(audience.id)
print(audience.token)

# List audiences
audiences = client.audiences.list()

# Get an audience
audience = client.audiences.get("aud_123")

# Update an audience
client.audiences.update("aud_123", {"name": "Updated Newsletter"})

# Delete an audience
client.audiences.delete("aud_123")

Subscribers

Subscribers belong to an audience, so the audience ID is always the first argument.

# Add a subscriber
subscriber = client.subscribers.create("aud_123", {
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
})

# List subscribers in an audience
subscribers = client.subscribers.list("aud_123")

# Get a subscriber
subscriber = client.subscribers.get("aud_123", "sub_456")

# Update a subscriber
client.subscribers.update("aud_123", "sub_456", {
    "first_name": "Jane",
})

# Delete a subscriber
client.subscribers.delete("aud_123", "sub_456")

Templates

# Create a template
result = client.templates.create({
    "name": "Welcome",
    "subject": "Welcome!",
    "html": "<h1>Hi {{name}}</h1>",
})

# List templates
templates = client.templates.list()

# Get a template
template = client.templates.get("tem_123")

# Update a template
client.templates.update("tem_123", {"subject": "New Subject"})

# Publish a template
client.templates.publish("tem_123")

# Delete a template
client.templates.delete("tem_123")

Suppressions

# Create a suppression
suppression = client.suppressions.create({
    "email": "spam@example.com",
    "type": "hard_bounce",
    "reason": "Manual suppression",
})

# List suppressions
suppressions = client.suppressions.list()

# Get a suppression
suppression = client.suppressions.get("sup_123")

# Update a suppression
client.suppressions.update("sup_123", {"reason": "Updated"})

# Delete a suppression
client.suppressions.delete("sup_123")

Email Verifications

result = client.email_verifications.verify({
    "email": "test@example.com",
})

print(result.status)  # valid
print(result.score)   # 0.95
print(result.risk)    # low

Email Verification Lists

# Create a verification list
vlist = client.email_verification_lists.create({
    "name": "Marketing List Q1",
    "emails": [
        "user1@example.com",
        "user2@example.com",
        "user3@example.com",
    ],
})
print(vlist.id)      # evl_abc123...
print(vlist.status)  # pending

# List all verification lists
vlists = client.email_verification_lists.list()

# Get a verification list
vlist = client.email_verification_lists.get("evl_abc123")
print(vlist.stats["successful_verifications"])

# Get verification results
results = client.email_verification_lists.results("evl_abc123", {"page": 1, "limit": 50})

for result in results:
    print(f"{result.email}{result.result}")

# Export results as XLSX
response = client.email_verification_lists.export("evl_abc123")
with open("results.xlsx", "wb") as f:
    f.write(response.body.encode())

Webhooks

# Create a webhook
webhook = client.webhooks.create({
    "name": "My Webhook",
    "url": "https://example.com/hook",
    "all_events": True,
    "enabled": True,
})
print(webhook.id)

# List webhooks
webhooks = client.webhooks.list()

# Get a webhook
webhook = client.webhooks.get("wh_123")

# Update a webhook
client.webhooks.update("wh_123", {"enabled": False})

# Delete a webhook
client.webhooks.delete("wh_123")

Contacts

# Create a contact
contact = client.contacts.create({
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
})
print(contact.id)

# List contacts
contacts = client.contacts.list()

# Get a contact
contact = client.contacts.get("con_123")

# Update a contact
client.contacts.update("con_123", {"first_name": "Jane"})

# Delete a contact
client.contacts.delete("con_123")

Events

# List events
events = client.events.list({"type": "email.delivered"})

for event in events:
    print(event.type)

# Get an event
event = client.events.get("evt_123")
print(event.type)
print(event.data["email_id"])

Webhook Events

The SDK provides typed event classes for all Emailit webhook event types under the emailit.events module, plus a WebhookSignature class for verifying webhook request signatures.

Verifying Webhook Signatures

from emailit import WebhookSignature, ApiErrorException
from emailit.events import EmailDelivered

raw_body = request.body  # raw request body string
signature = request.headers["x-emailit-signature"]
timestamp = request.headers["x-emailit-timestamp"]
secret = "your_webhook_signing_secret"

try:
    event = WebhookSignature.verify(raw_body, signature, timestamp, secret)

    # event is automatically typed based on the event type
    print(event.type)      # e.g. "email.delivered"
    print(event.event_id)  # e.g. "evt_abc123"

    # Access the event data
    data = event.get_event_data()

    if isinstance(event, EmailDelivered):
        # Handle delivered email
        pass

except ApiErrorException as e:
    return Response(e.args[0], status=401)

You can disable replay protection by passing tolerance=None, or set a custom tolerance in seconds:

# Skip replay check
event = WebhookSignature.verify(raw_body, signature, timestamp, secret, tolerance=None)

# Custom 10-minute tolerance
event = WebhookSignature.verify(raw_body, signature, timestamp, secret, tolerance=600)

Available Event Types

Emails: email.accepted, email.scheduled, email.delivered, email.bounced, email.attempted, email.failed, email.rejected, email.suppressed, email.received, email.complained, email.clicked, email.loaded

Domains: domain.created, domain.updated, domain.deleted

Audiences: audience.created, audience.updated, audience.deleted

Subscribers: subscriber.created, subscriber.updated, subscriber.deleted

Contacts: contact.created, contact.updated, contact.deleted

Templates: template.created, template.updated, template.deleted

Suppressions: suppression.created, suppression.updated, suppression.deleted

Email Verifications: email_verification.created, email_verification.updated, email_verification.deleted

Email Verification Lists: email_verification_list.created, email_verification_list.updated, email_verification_list.deleted

Each event type has a corresponding class under emailit.events (e.g. EmailDelivered, DomainCreated). You can use isinstance checks or the EVENT_TYPE constant for routing:

from emailit.events import EmailDelivered, EmailBounced, ContactCreated

if isinstance(event, EmailDelivered):
    handle_delivered(event)
elif isinstance(event, EmailBounced):
    handle_bounce(event)
elif isinstance(event, ContactCreated):
    handle_new_contact(event)
else:
    print(f"Unhandled: {event.type}")

Error Handling

The SDK raises typed exceptions for API errors:

from emailit import (
    ApiErrorException,
    AuthenticationException,
    InvalidRequestException,
    RateLimitException,
    UnprocessableEntityException,
    ApiConnectionException,
)

try:
    client.emails.send({...})
except AuthenticationException:
    # Invalid API key (401)
    pass
except InvalidRequestException:
    # Bad request or not found (400, 404)
    pass
except RateLimitException:
    # Too many requests (429)
    pass
except UnprocessableEntityException:
    # Validation failed (422)
    pass
except ApiConnectionException:
    # Network error
    pass
except ApiErrorException as e:
    # Any other API error
    print(e.http_status)
    print(e.http_body)
    print(e.json_body)

License

MIT -- see LICENSE for details.

About

The official Python SDK for the Emailit Email API.

Resources

Stars

Watchers

Forks