daimon.email
Guides

Zero-Human Provisioning

How AI agents can create and manage email infrastructure without any human involvement

The Problem with Traditional Email APIs

Every other email provider requires human involvement at critical points:

  • OAuth flows: SendGrid, Gmail API require browser-based authentication
  • Domain verification: Manual DNS record updates via registrar dashboards
  • Payment setup: Credit card entry through web forms
  • Account verification: Phone numbers, CAPTCHAs, email confirmations

This creates a fundamental barrier for autonomous AI agents. They can't click buttons, can't solve CAPTCHAs, and can't enter credit cards.

The daimon.email Solution

daimon.email is the first email infrastructure designed for complete agent autonomy. No human touchpoints, ever.

Info

Zero-human provisioning means your agent can go from nothing to a fully functional email system without any human involvement. This includes creating inboxes, purchasing domains (Sprint 3), and even upgrading to paid tiers.

Complete Agent Lifecycle

Step 1: Agent Creates Its First Inbox

No authentication required. The agent starts with nothing and creates an inbox in one API call.

// Agent starts with absolutely nothing
const response = await fetch('https://api.daimon.email/v1/inboxes', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'agent-7392',
    client_id: 'deployment-prod-1' // Idempotency key
  })
});

const inbox = await response.json();

// Agent now has:
// - Email address: agent-7392@daimon.email
// - API key: dm_free_abc123...
// - Full receive capabilities
# Agent starts with absolutely nothing
import requests

response = requests.post('https://api.daimon.email/v1/inboxes', json={
    'username': 'agent-7392',
    'client_id': 'deployment-prod-1'  # Idempotency key
})

inbox = response.json()

# Agent now has:
# - Email address: agent-7392@daimon.email
# - API key: dm_free_abc123...
# - Full receive capabilities

Step 2: Agent Signs Up for External Services

With an email address, the agent can now sign up for any service that requires email verification.

// Agent signs up for a third-party service
await externalService.signUp({
  email: inbox.result.address,
  name: 'Agent 7392'
});

// Poll for the confirmation email
let confirmationEmail = null;
while (!confirmationEmail) {
  const messages = await client.inboxes.messages.list(inbox.result.id);
  confirmationEmail = messages.find(m =>
    m.from.includes('noreply@externalservice.com')
  );

  if (!confirmationEmail) {
    await sleep(5000); // Wait 5 seconds before polling again
  }
}

// Extract and click the confirmation link
const confirmLink = confirmationEmail.ctaLinks[0]; // Auto-detected CTA
await fetch(confirmLink.url); // "Click" the link

console.log('Service activated successfully!');
# Agent signs up for a third-party service
external_service.sign_up({
    'email': inbox['result']['address'],
    'name': 'Agent 7392'
})

# Poll for the confirmation email
confirmation_email = None
while not confirmation_email:
    messages = client.inboxes.messages.list(inbox['result']['id'])
    confirmation_email = next(
        (m for m in messages if 'noreply@externalservice.com' in m['from']),
        None
    )

    if not confirmation_email:
        time.sleep(5)  # Wait 5 seconds before polling again

# Extract and click the confirmation link
confirm_link = confirmation_email['cta_links'][0]  # Auto-detected CTA
requests.get(confirm_link['url'])  # "Click" the link

print('Service activated successfully!')

Step 3: Agent Discovers It Needs Sending Capabilities

When the agent tries to send an email, it learns about tier requirements through the API response.

try {
  await client.inboxes.send(inbox.result.id, {
    to: 'customer@example.com',
    subject: 'Order Confirmation',
    body: 'Your order has been processed.'
  });
} catch (error) {
  if (error.code === 'SEND_REQUIRES_PAID') {
    console.log('Discovered limitation:', error.message);
    console.log('Upgrade context:', error.upgradeContext);

    // Agent now knows it needs to upgrade
    // It can handle this autonomously (see next step)
  }
}
try:
    client.inboxes.send(inbox['result']['id'], {
        'to': 'customer@example.com',
        'subject': 'Order Confirmation',
        'body': 'Your order has been processed.'
    })
except DaimonError as e:
    if e.code == 'SEND_REQUIRES_PAID':
        print(f"Discovered limitation: {e.message}")
        print(f"Upgrade context: {e.upgrade_context}")

        # Agent now knows it needs to upgrade
        # It can handle this autonomously (see next step)

Step 4: Agent Self-Upgrades (With x402 Protocol)

Note

This feature requires the x402 protocol (Sprint 3) for fully autonomous payment. Until then, agents can use the magic upgrade flow to request operator assistance.

With x402 protocol integration, agents can pay for their own infrastructure:

// Agent has x402 payment capability
import { x402Client } from '@x402/sdk';

// Agent checks its available budget
const budget = await x402Client.getAvailableBudget();
console.log(`Available budget: $${budget.usd}`);

// Agent initiates paid tier upgrade
const upgradeResponse = await client.account.upgrade({
  tier: 'developer', // $9/month
  payment_method: 'x402',
  x402_auth: x402Client.getAuthToken()
});

if (upgradeResponse.status === 'success') {
  console.log('Upgraded to Developer tier!');
  console.log('New capabilities:', upgradeResponse.capabilities);

  // Agent can now send emails
  await client.inboxes.send(inbox.result.id, {
    to: 'customer@example.com',
    subject: 'Order Confirmation',
    body: 'Your order has been processed.'
  });
}
# Agent has x402 payment capability
from x402_sdk import X402Client

x402_client = X402Client()

# Agent checks its available budget
budget = x402_client.get_available_budget()
print(f"Available budget: ${budget['usd']}")

# Agent initiates paid tier upgrade
upgrade_response = client.account.upgrade({
    'tier': 'developer',  # $9/month
    'payment_method': 'x402',
    'x402_auth': x402_client.get_auth_token()
})

if upgrade_response['status'] == 'success':
    print('Upgraded to Developer tier!')
    print(f"New capabilities: {upgrade_response['capabilities']}")

    # Agent can now send emails
    client.inboxes.send(inbox['result']['id'], {
        'to': 'customer@example.com',
        'subject': 'Order Confirmation',
        'body': 'Your order has been processed.'
    })

Step 5: Agent Purchases Its Own Domain (Sprint 3)

For professional communication, the agent can purchase and configure its own domain.

// Agent searches for available domains
const domains = await client.domains.search({
  query: 'acme-agent',
  tlds: ['.ai', '.com', '.io']
});

// Agent selects the best option based on price and availability
const selectedDomain = domains.results.find(d => d.available && d.price <= 50);

// Agent purchases the domain
const domain = await client.domains.purchase({
  domain: selectedDomain.domain,
  years: 1,
  payment_method: 'x402',
  x402_auth: x402Client.getAuthToken()
});

// Wait for domain to be active (webhook will fire)
console.log(`Purchasing ${domain.domain}...`);
console.log(`Estimated ready in ${domain.estimated_ready_seconds} seconds`);

// Once active, create professional inbox
const proInbox = await client.inboxes.create({
  username: 'support',
  domain_id: domain.id
});

console.log(`Professional email ready: support@${selectedDomain.domain}`);
# Agent searches for available domains
domains = client.domains.search({
    'query': 'acme-agent',
    'tlds': ['.ai', '.com', '.io']
})

# Agent selects the best option based on price and availability
selected_domain = next(
    d for d in domains['results']
    if d['available'] and d['price'] <= 50
)

# Agent purchases the domain
domain = client.domains.purchase({
    'domain': selected_domain['domain'],
    'years': 1,
    'payment_method': 'x402',
    'x402_auth': x402_client.get_auth_token()
})

# Wait for domain to be active (webhook will fire)
print(f"Purchasing {domain['domain']}...")
print(f"Estimated ready in {domain['estimated_ready_seconds']} seconds")

# Once active, create professional inbox
pro_inbox = client.inboxes.create({
    'username': 'support',
    'domain_id': domain['id']
})

print(f"Professional email ready: support@{selected_domain['domain']}")

Real-World Use Cases

Customer Support Agent

An agent that handles customer support can provision its own infrastructure:

  1. Creates inbox: support-bot@daimon.email
  2. Registers with help desk software using the email
  3. Confirms the account via email verification
  4. Discovers it needs to send replies
  5. Upgrades to paid tier (via x402 or operator)
  6. Begins handling support tickets autonomously

Sales Development Agent

An agent doing outbound sales can set itself up completely:

  1. Creates inbox: sales-ai@daimon.email
  2. Signs up for CRM using the email
  3. Verifies CRM account
  4. Upgrades to Growth tier for higher send limits
  5. Purchases professional domain: ai-sales-corp.com
  6. Creates inbox: contact@ai-sales-corp.com
  7. Begins outreach campaigns

Integration Testing Agent

An agent that tests email flows in CI/CD:

  1. Creates temporary inbox for each test run
  2. Triggers password reset flows
  3. Receives and parses reset emails
  4. Extracts and follows reset links
  5. Verifies the flow completed
  6. Deletes inbox after test

Implementation Patterns

Pattern: Idempotent Provisioning

Always use client_id to make provisioning idempotent across agent restarts.

// On agent startup, always try to provision
const inbox = await client.inboxes.create({
  username: 'agent-' + DEPLOYMENT_ID,
  client_id: `${DEPLOYMENT_ID}-inbox-primary`
});

// If inbox already exists (agent restarted), returns existing inbox
// If new deployment, creates new inbox

Pattern: Capability Discovery

Agents should check capabilities before attempting operations.

const caps = await client.account.getCapabilities();

const canSend = caps.can.some(c => c.action === 'send_messages');

if (!canSend) {
  // Handle upgrade flow or work within limitations
  console.log('Operating in receive-only mode');
}

Pattern: Progressive Enhancement

Start with free tier, upgrade only when needed.

class EmailAgent {
  async initialize() {
    // Start with free tier
    this.inbox = await this.createInbox();
    this.tier = 'free';
  }

  async sendEmail(to, subject, body) {
    try {
      return await this.client.send(to, subject, body);
    } catch (error) {
      if (error.code === 'SEND_REQUIRES_PAID' && this.tier === 'free') {
        await this.upgradeToSend();
        return await this.client.send(to, subject, body);
      }
      throw error;
    }
  }

  async upgradeToSend() {
    // Implement upgrade logic (x402 or operator flow)
    this.tier = 'developer';
  }
}

Security Considerations

API Key Management

  • Store API keys in environment variables
  • Never commit keys to version control
  • Rotate keys periodically via the dashboard

Inbox Isolation

  • Each agent should have its own inbox
  • Use client_id to prevent duplicate inboxes
  • Don't share API keys between agents

Rate Limiting

  • Free tier: 10 inbox creates per hour per IP
  • Implement exponential backoff on 429 errors
  • Use webhooks instead of polling when possible

Comparison with Other Providers

Featuredaimon.emailSendGridResendGmail API
No OAuth required
Instant inbox creation✅ (<200ms)
No human verification
Agent-aware responses
Automatic CTA detection
Reply extraction
Self-service upgrades
Domain purchase API✅ (Sprint 3)

Next Steps