Skip to main content

Dead Simple Email — Python SDK for the email API for AI agents

Reason this release was yanked:

broken project URL metadata; superseded by 0.1.1

Project description

Dead Simple Email — Python SDK

The official Python SDK for Dead Simple Email, the email API for AI agents.

  • Typed responses — dataclass models with IDE autocompletion, not raw dicts
  • Sync + asyncDeadSimple for synchronous code, AsyncDeadSimple for async/await
  • Idempotency — pass idempotency_key to any create/send method for safe retries
  • Webhook verification — HMAC-SHA256 signature validation built in
  • Full API coverage — inboxes, messages, threads, webhooks, domains, API keys, pods, usage, attachments

Install

pip install deadsimple-email

Quick Start

from deadsimple import DeadSimple

client = DeadSimple("dse_your_api_key")

# Create an inbox
inbox = client.inboxes.create(display_name="Support Bot")
print(f"Inbox: {inbox.email}")

# Send an email
result = client.messages.send(
    inbox_id=inbox.inbox_id,
    to="user@example.com",
    subject="Hello from my AI agent",
    text_body="This email was sent by an AI agent using Dead Simple Email.",
)
print(f"Sent: {result.message_id}")

# Read received messages
messages = client.messages.list(inbox_id=inbox.inbox_id)
for msg in messages.messages:
    print(f"  {msg.from_email}: {msg.subject}")

# Reply to a message
client.messages.reply(
    inbox_id=inbox.inbox_id,
    message_id=messages.messages[0].message_id,
    text_body="Thanks for your email!",
)

# List conversation threads
threads = client.threads.list(inbox_id=inbox.inbox_id)
for t in threads.threads:
    print(f"  Thread: {t.subject} ({t.message_count} messages)")

# Register a webhook for real-time notifications
webhook = client.webhooks.create(
    url="https://your-app.com/webhook",
    events=["message.received"],
)
print(f"Webhook secret: {webhook.signing_secret}")

Async Usage

from deadsimple import AsyncDeadSimple

async with AsyncDeadSimple("dse_your_api_key") as client:
    inbox = await client.inboxes.create(display_name="Async Bot")
    await client.messages.send(
        inbox_id=inbox.inbox_id,
        to="user@example.com",
        subject="Hello from async",
        text_body="Sent asynchronously.",
    )

Bulk Operations

# Create 50 inboxes at once
result = client.inboxes.bulk_create([
    {"display_name": f"Agent {i}", "tags": ["batch-1"]}
    for i in range(50)
])
print(f"Created {result.created}, failed {result.failed}")

Custom Domains

# Add your domain
domain = client.domains.add("mail.yourcompany.com")

# Shows DNS records to configure
for record in domain.dns_records:
    print(f"  {record['type']} {record['name']} -> {record['value']}")

# Check verification
status = client.domains.verify(domain.domain_id)
print(f"Status: {status.status}")

Multi-Tenant Pods

# Create an isolated namespace for a customer
pod = client.pods.create(name="customer-acme", description="Acme Corp")
print(f"Pod API key: {pod.api_key['key']}")

# Use the pod's scoped API key for isolated access
acme_client = DeadSimple(pod.api_key["key"])
acme_inbox = acme_client.inboxes.create(display_name="Acme Support")

Idempotent Requests

import uuid

# Safe to retry — same key = same result, no duplicates
key = str(uuid.uuid4())
inbox = client.inboxes.create(display_name="Bot", idempotency_key=key)
inbox_again = client.inboxes.create(display_name="Bot", idempotency_key=key)  # Returns same inbox

Webhook Signature Verification

from deadsimple.webhooks import verify_signature

# In your webhook handler (e.g., Flask, FastAPI):
try:
    verify_signature(
        payload=request.body,
        signature=request.headers["X-DSE-Signature"],
        secret="whsec_your_signing_secret",
    )
    # Signature valid — process the event
except Exception:
    # Signature invalid — reject the request
    return Response(status_code=401)

Usage Metrics

usage = client.usage.get()
print(f"Plan: {usage.plan_name}")
print(f"Inboxes: {usage.inboxes['used']} / {usage.inboxes['limit']}")
print(f"Emails this month: {usage.emails['sent_this_month']}")

Error Handling

from deadsimple import DeadSimple, RateLimitError, NotFoundError, ValidationError
import time

client = DeadSimple("dse_your_api_key")

try:
    inbox = client.inboxes.get("nonexistent")
except NotFoundError:
    print("Inbox not found")
except RateLimitError as e:
    print(f"Rate limited, retry in {e.retry_after}s")
    time.sleep(e.retry_after)
except ValidationError as e:
    print(f"Bad request: {e.message}")
    for detail in e.details:
        print(f"  {detail['field']}: {detail['message']}")

All Resources

Resource Methods
client.inboxes create, bulk_create, list, get, update, delete
client.messages send, list, get, reply, reply_all, forward
client.threads list, get
client.webhooks create, list, delete
client.domains add, list, verify, delete
client.api_keys create, list, delete
client.pods create, list, get, delete
client.usage get
client.attachments get_url

Pricing

Plan Price Inboxes Emails/mo
Free $0 5 5,000
Hobby $5/mo 15 15,000
Pro $29/mo 100 100,000
Scale $99/mo 500 500,000

Webhook signing included on all plans (competitors charge $200/mo).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deadsimple_email-0.1.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deadsimple_email-0.1.0-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file deadsimple_email-0.1.0.tar.gz.

File metadata

  • Download URL: deadsimple_email-0.1.0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for deadsimple_email-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d10d21a8d0a932a132b9aedbf957621cd9f89ec52bd841e544aa0b9af03fd2d3
MD5 38470345c8fe5752e46816868bd4ca6e
BLAKE2b-256 647d6b255e63bde65da2ab06918f3c05df185c87362e63bdff3ca4bf18fa8e37

See more details on using hashes here.

File details

Details for the file deadsimple_email-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for deadsimple_email-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d5336e139ee53b8b2a4ca7ed047eaf422e7ecdbdbd7311f68e0d888de0c794f
MD5 3951759070b4029765fc76a9edd43d95
BLAKE2b-256 04187e5611f3dc796b57123bfb5e42ae93025d64580a35339e9fe969cb40042d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page