This guide walks you through everything you need to go from zero to a working AI agent with email capabilities. By the end, your agent will have its own email address, will be able to send messages, and will receive incoming email via webhooks. Total time: about 5 minutes.
Prerequisites
- Python 3.9 or later
- A Dead Simple Email account (join the waitlist for early access)
- A publicly accessible URL for webhooks (we'll cover local testing too)
Step 1: Get Your API Key
After signing up, head to the dashboard and navigate to Settings → API Keys. Click Create API Key, give it a name (e.g., "my-agent"), and copy the key. It starts with dse_ and you'll only see it once, so store it somewhere safe.
Set it as an environment variable:
export DEADSIMPLE_API_KEY="dse_your_api_key_here"
Step 2: Install the SDK
Install the Python SDK from PyPI:
pip install deadsimple
The SDK is a thin wrapper around our REST API. Everything you can do with the SDK, you can also do with curl or any HTTP client. But the SDK handles authentication, retries, and type hints for you.
Step 3: Create an Inbox
An inbox is your agent's email identity. Each inbox gets its own email address on your subdomain. Let's create one:
import os from deadsimple import DeadSimple client = DeadSimple(api_key=os.environ["DEADSIMPLE_API_KEY"]) # Create an inbox — it's ready to send and receive immediately inbox = client.inboxes.create(name="support") print(f"Inbox created: {inbox.email}") print(f"Inbox ID: {inbox.id}") # → Inbox created: support@yourco.deadsimple.email # → Inbox ID: inb_a1b2c3d4e5f6
That's it. No DNS records to configure, no SPF/DKIM setup, no waiting for propagation. The inbox is live the moment it's created. SPF, DKIM, and DMARC are pre-configured on the shared domain.
Step 4: Send Your First Email
Now let's send a message from your new inbox:
# Send an email from your agent's inbox message = inbox.send( to="recipient@example.com", subject="Hello from my AI agent", body="This email was sent programmatically via Dead Simple.", ) print(f"Message sent: {message.id}") print(f"Status: {message.status}") # → Message sent: msg_x9y8z7w6v5u4 # → Status: delivered
You can also send HTML content and include attachments:
inbox.send(
to="recipient@example.com",
subject="Weekly report",
html="<h1>Weekly Report</h1><p>Here's your summary...</p>",
attachments=[
{"filename": "report.pdf", "content": base64_data, "content_type": "application/pdf"}
]
)
Step 5: Receive Email via Webhooks
The real power comes from receiving email. Instead of polling an IMAP server, Dead Simple pushes incoming messages to your webhook endpoint in real time. First, register your webhook:
# Register a webhook endpoint for incoming emails webhook = client.webhooks.create( url="https://your-server.com/webhook/email", events=["message.received"], inbox_id=inbox.id, ) print(f"Webhook active: {webhook.url}") print(f"Secret: {webhook.secret}") # Save the secret — you'll use it to verify signatures
When someone sends an email to your inbox, Dead Simple delivers an HMAC-signed POST request to your endpoint. Here's what the payload looks like:
{
"event": "message.received",
"timestamp": "2026-03-14T10:32:07Z",
"data": {
"id": "msg_k4j3h2g1f0e9",
"inbox_id": "inb_a1b2c3d4e5f6",
"from": "customer@example.com",
"to": "support@yourco.deadsimple.email",
"subject": "Help with my order",
"body_text": "Hi, I need help tracking order #4821...",
"body_html": "<p>Hi, I need help tracking order #4821...</p>",
"attachments": [],
"headers": {
"message-id": "<abc123@mail.example.com>",
"in-reply-to": null
}
}
}
Now write a simple handler to process incoming messages. Here's an example using Flask:
import hmac, hashlib from flask import Flask, request, jsonify app = Flask(__name__) WEBHOOK_SECRET = "whsec_your_secret_here" def verify_signature(payload, signature): expected = hmac.new( WEBHOOK_SECRET.encode(), payload, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature) @app.route("/webhook/email", methods=["POST"]) def handle_email(): # Verify the webhook signature signature = request.headers.get("X-DeadSimple-Signature") if not verify_signature(request.data, signature): return jsonify({"error": "invalid signature"}), 401 event = request.get_json() msg = event["data"] print(f"From: {msg['from']}") print(f"Subject: {msg['subject']}") print(f"Body: {msg['body_text']}") # Your agent logic goes here — parse the email, # call your LLM, and send a reply return jsonify({"status": "ok"}), 200
Step 6: Put It All Together
Here's the complete flow in one script — an AI agent that receives emails and sends automatic replies:
import os from deadsimple import DeadSimple from flask import Flask, request, jsonify client = DeadSimple(api_key=os.environ["DEADSIMPLE_API_KEY"]) inbox = client.inboxes.get("inb_a1b2c3d4e5f6") app = Flask(__name__) @app.route("/webhook/email", methods=["POST"]) def handle_email(): msg = request.get_json()["data"] # Generate a reply (plug in your LLM here) reply_body = generate_reply(msg["body_text"]) # Send the reply from the same inbox inbox.send( to=msg["from"], subject=f"Re: {msg['subject']}", body=reply_body, ) return jsonify({"status": "ok"}), 200
Local Development
During development, you can use a tunneling service to expose your local server to the internet for webhook testing:
# Start your Flask app
python agent.py
# In another terminal, expose it via a tunnel
ngrok http 5000
# Then use the ngrok URL when creating your webhook
Alternatively, you can poll for messages during development instead of using webhooks:
# Poll for new messages (useful for local testing)
messages = inbox.messages.list(status="unread", limit=10)
for msg in messages:
print(f"{msg.sender}: {msg.subject}")
What's Next
You now have a fully functional AI agent with its own email identity. From here, you can:
- Add a custom domain — send from
agent@yourcompany.cominstead of the shared domain - Set up multiple inboxes — one per agent, one per department, one per customer
- Connect your LLM — pipe incoming messages through GPT-4, Claude, or any model to generate intelligent replies
- Track analytics — monitor delivery rates, open rates, and response times from the dashboard
Check out the full API documentation for everything else — attachments, threading, batch sends, rate limits, and more.
Questions? Reach out at hello@deadsimple.email or join our Discord community. We're here to help you ship.