Useful ToolsSend Email

Send Email

Send from your agent mailbox with traceable failures and safe retries.

Usage

Option 1: Import directly

from connectonion import send_email

agent = Agent("assistant", tools=[send_email])

Option 2: Copy and customize

Terminalbash
$co copy send_email
from tools.send_email import send_email  # Your local copy

Quick Debug

Check the effective credential source, then test the same CLI path users run:

# 1. Shows which project/global credential source wins, without printing secrets
co doctor

# 2. Test the managed agent mailbox
co email send your@email.com "Test" "It works"

# 3. Confirm the accepted send after the oo-api Sent endpoint is deployed
co email sent

If a send times out or returns a 5xx response, keep the printed safe retry key and reuse it with--idempotency-key. Do not retry with a new key: the first request may already have been accepted.

Quick Start

30 seconds to first email

One line. That's it.

from connectonion import send_email

send_email("alice@example.com", "Welcome!", "Thanks for joining us!")

Run it:

Code
>>> send_email("alice@example.com", "Welcome!", "Thanks for joining us!")
Result
{'success': True, 'message_id': 'msg_123', 'from': '0x1234abcd@mail.openonion.ai'}

Email sent. Done.

Core Concept

What you get:

Simple function

send_email(to, subject, message)

Managed credentials

Authenticate once with co auth

Your own email

Unique address for every agent

Professional delivery

Good reputation & reliability

The function signature

def send_email(
    to: str,
    subject: str,
    message: str,
    idempotency_key: str | None = None,
) -> dict:
    """Send an email and return correlation data for safe retries."""

Three parameters. Nothing else.

Examples

Basic notification

Code
send_email("user@example.com", "Order shipped", "Track it: ABC123")
Result
{'success': True, 'message_id': 'msg_124'}

Verification code

Code
send_email("bob@example.com", "Your code: 456789", "Verify your account")
Result
{'success': True, 'message_id': 'msg_125'}

Status update

Code
send_email("team@example.com", "Build passed", "All tests green")
Result
{'success': True, 'message_id': 'msg_126'}

HTML content (automatic)

Code
send_email(
    "alice@example.com",
    "Weekly Report",
    "<h1>Progress</h1><p>3 features shipped!</p>"
)
Result
{'success': True, 'message_id': 'msg_127'}

Your Email Address

Every agent automatically gets an email address:

0x1234abcd@mail.openonion.ai
Based on your public key (first 10 characters)
Professional domain with good reputation
Generated during co init
Activated with co auth

Check your email address

Use co doctor to see the effective project/global source without printing credentials:

co doctor
# Reports the effective agent email and whether email is active

Email Activation Lifecycle

1

Generated

Email address created during co init

2

Activation Prompt

You'll be asked to activate your agent's email

3

Active

Email is fully functional after authentication

Two ways to activate:

Option 1: Immediate activation (recommended)

Terminalbash
$co init
Agent email: 0x1234abcd@mail.openonion.ai (inactive) Your agent can send emails! Would you like to activate your agent's email now? [Y/n]: y Email activated! Your agent can now send emails.

Option 2: Activate later

Terminalbash
$co auth

Want a custom name?

Upgrade to a custom email for $0.99:

mybot@mail.openonion.ai
ai-assistant@mail.openonion.ai
support@mail.openonion.ai

Return Values

✓ Success

{
    'success': True,
    'message_id': 'msg_123',
    'from': '0x1234abcd@mail.openonion.ai',
    'request_id': 'send-7f6c...',
    'idempotency_key': 'send-7f6c...'
}

✗ Failure

{
    'success': False,
    'error': 'Request timed out. Retry with the same idempotency key.',
    'request_id': 'send-7f6c...',
    'idempotency_key': 'send-7f6c...'
}

Common errors:

  • "Rate limit exceeded" - Hit your quota
  • "Invalid email address" - Check the recipient
  • "Authentication failed" - Token expired, run co auth
  • "Email not activated" - Run co auth to activate

Using with an Agent

Give your agent the ability to send emails:

from connectonion import Agent, send_email

# Create an agent with email capability
agent = Agent(
    "customer_support",
    tools=[send_email],
    system_prompt="You help users and send them email confirmations"
)

# The agent can now send emails autonomously
response = agent.input("Send a welcome email to alice@example.com")
# Agent sends: send_email("alice@example.com", "Welcome!", "Thanks for joining...")

Real-world monitoring example

from connectonion import Agent, send_email
import time

def check_system_status() -> dict:
    """Check if the system is running properly."""
    cpu_usage = 95  # Simulated high CPU
    return {"status": "warning", "cpu": cpu_usage}

# Create monitoring agent
monitor = Agent(
    "system_monitor",
    tools=[check_system_status, send_email],
    system_prompt="Monitor system health and alert admin@example.com if issues"
)

# Agent checks system and sends alerts
monitor.input("Check the system and alert if there are problems")
# Agent will:
# 1. Call check_system_status() 
# 2. See high CPU (95%)
# 3. Call send_email("admin@example.com", "Alert: High CPU", "CPU at 95%...")

Complete Example

Here's a real-world example sending different types of emails:

from connectonion import send_email

# Welcome email
result = send_email(
    "new_user@example.com",
    "Welcome to our platform!",
    "We're excited to have you. Check out our docs to get started."
)
print(f"Welcome email: {result['success']}")

# Alert notification
result = send_email(
    "admin@example.com",
    "🚨 High CPU usage detected",
    "Server CPU at 95% for the last 5 minutes"
)
print(f"Alert sent: {result['success']}")

# Daily report with HTML
result = send_email(
    "team@example.com",
    "Daily Summary",
    """
    <h2>Today's Metrics</h2>
    <ul>
        <li>Users: 1,234</li>
        <li>Revenue: $5,678</li>
        <li>Uptime: 99.9%</li>
    </ul>
    """
)
print(f"Report sent: {result['success']}")

The Details

Quotas

  • Free tier:100 emails/month
  • Plus tier:10,000 emails/month
  • Pro tier:50,000 emails/month

Rate Limiting

Automatic rate limiting prevents abuse:

  • Returns error on limit exceeded
  • Resets monthly
  • No configuration needed

Content Types

  • Plain text

    Just send a string

  • HTML

    Auto-detected from tags

  • Mixed

    HTML with plain fallback

From Address

  • Free tier:
    0x{key_prefix}@mail.openonion.ai
  • Custom name:
    yourname@mail.openonion.ai

Behind the Scenes

Authenticate with co auth
co doctor reports credential precedence safely
Uses Resend API for delivery
Idempotent retries when the same key is reused
Returns Request IDs for support and tracing
SPF/DKIM configured

Troubleshooting

Check the effective credential source

co doctor
# Reports project/global precedence and email activation without exposing tokens

If credentials are missing or expired, run co auth, then rerun doctor.

Check for errors

result = send_email("test@example.com", "Test", "Testing")
if not result['success']:
    print(f"Error: {result['error']}")
    print(f"Request ID: {result['request_id']}")
    print(f"Safe retry key: {result['idempotency_key']}")

Give the Request ID to support. Reuse the same idempotency key only when retrying that exact message.

Sent mailbox says it is unavailable

Sending and listing Sent mail are separate backend capabilities. During a staggered rollout, sending can succeed while co email sent reports that its endpoint is not deployed yet.

co email sent
# If unavailable, deploy the matching oo-api release before the client release.

Philosophy

One function, one purpose: Send an email

No templates to learn. No configuration files. No complex APIs.

Just send_email(to, subject, message).

Keep simple things simple.

Star us on GitHub

If ConnectOnion saves you time, a ⭐ goes a long way — and earns you a coffee chat with our founder.