daimon.email
ExamplesOutbound

Service Signup Agent

Agent that signs up for external services and verifies via email

Overview

A service signup agent can autonomously register for external services, verify email addresses, and complete account activation flows without human intervention. This is the foundation of zero-human provisioning.

Info

This pattern enables agents to access services that require email verification, from API platforms to SaaS tools to e-commerce sites.

How It Works

  1. Create an inbox for the signup process
  2. Submit registration form using the inbox address
  3. Poll for confirmation email
  4. Extract verification link from ctaLinks
  5. Follow the link to complete activation
  6. Extract credentials or API keys from confirmation

Complete Implementation

import { DaimonClient } from 'daimon-email';

const client = new DaimonClient();

// Step 1: Create dedicated inbox for service
async function createServiceInbox(serviceName: string) {
  const inbox = await client.inboxes.create({
    username: `${serviceName}-${Date.now()}`,
    clientId: `service-${serviceName}-primary`
  });

  console.log(`Created inbox for ${serviceName}: ${inbox.address}`);

  return inbox;
}

// Step 2: Sign up for external service
async function signUpForService(email: string, serviceName: string) {
  // Example: Sign up for a hypothetical API service
  const response = await fetch('https://api.example-service.com/signup', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: email,
      name: 'AI Agent',
      company: 'Acme Corp',
      use_case: 'Automated integration'
    })
  });

  if (!response.ok) {
    throw new Error(`Signup failed: ${response.statusText}`);
  }

  console.log(`Signup initiated for ${serviceName}`);
  return await response.json();
}

// Step 3: Wait for confirmation email
async function waitForConfirmationEmail(
  inboxId: string,
  fromDomain: string,
  timeoutSeconds: number = 300
): Promise<any> {
  const startTime = Date.now();
  const authedClient = new DaimonClient({ apiKey: process.env.DAIMON_API_KEY });

  while (Date.now() - startTime < timeoutSeconds * 1000) {
    const messages = await authedClient.inboxes.messages.list(inboxId);

    const confirmationEmail = messages.find(msg =>
      msg.from.includes(fromDomain) &&
      (msg.subject.toLowerCase().includes('confirm') ||
       msg.subject.toLowerCase().includes('verify') ||
       msg.subject.toLowerCase().includes('activate'))
    );

    if (confirmationEmail) {
      console.log(`Received confirmation email: ${confirmationEmail.subject}`);
      return confirmationEmail;
    }

    // Poll every 5 seconds
    await new Promise(resolve => setTimeout(resolve, 5000));
  }

  throw new Error('Timeout waiting for confirmation email');
}

// Step 4: Extract and follow verification link
async function activateAccount(confirmationEmail: any) {
  // daimon.email automatically detects CTA links
  const ctaLinks = confirmationEmail.ctaLinks;

  if (ctaLinks.length === 0) {
    throw new Error('No verification link found in email');
  }

  const verificationLink = ctaLinks[0]; // First CTA is usually the main action
  console.log(`Found verification link: ${verificationLink.text}`);
  console.log(`URL: ${verificationLink.url}`);

  // "Click" the verification link
  const response = await fetch(verificationLink.url, {
    method: 'GET',
    redirect: 'follow'
  });

  if (response.ok) {
    console.log('Account activated successfully!');
    return true;
  } else {
    throw new Error(`Activation failed: ${response.statusText}`);
  }
}

// Step 5: Extract credentials from welcome email
async function extractCredentials(inboxId: string, fromDomain: string) {
  const authedClient = new DaimonClient({ apiKey: process.env.DAIMON_API_KEY });

  // Wait for welcome/credentials email
  await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10s

  const messages = await authedClient.inboxes.messages.list(inboxId);

  const welcomeEmail = messages.find(msg =>
    msg.from.includes(fromDomain) &&
    (msg.subject.toLowerCase().includes('welcome') ||
     msg.subject.toLowerCase().includes('getting started') ||
     msg.subject.toLowerCase().includes('api key'))
  );

  if (!welcomeEmail) {
    console.log('No credentials email found (may require manual retrieval)');
    return null;
  }

  // Extract API key or other credentials from email body
  const apiKeyMatch = welcomeEmail.body.match(/API Key:\s*([A-Za-z0-9_-]+)/);

  if (apiKeyMatch) {
    console.log(`Extracted API key: ${apiKeyMatch[1].substring(0, 10)}...`);
    return {
      apiKey: apiKeyMatch[1],
      email: welcomeEmail.to
    };
  }

  return null;
}

// Complete flow
async function completeServiceSignup(serviceName: string, fromDomain: string) {
  try {
    // Step 1: Create inbox
    const inbox = await createServiceInbox(serviceName);

    // Step 2: Sign up for service
    await signUpForService(inbox.address, serviceName);

    // Step 3: Wait for confirmation email
    const confirmationEmail = await waitForConfirmationEmail(
      inbox.id,
      fromDomain,
      300 // 5 minute timeout
    );

    // Step 4: Activate account
    await activateAccount(confirmationEmail);

    // Step 5: Extract credentials
    const credentials = await extractCredentials(inbox.id, fromDomain);

    console.log('\n✅ Service signup complete!');
    console.log(`Inbox: ${inbox.address}`);
    console.log(`Credentials:`, credentials);

    return {
      inbox,
      credentials,
      success: true
    };

  } catch (error) {
    console.error('Signup failed:', error);
    return {
      success: false,
      error: error.message
    };
  }
}

// Usage
completeServiceSignup('example-api', 'noreply@example-service.com');
from daimon_email import DaimonClient
import requests
import time
import re
from typing import Optional, Dict

client = DaimonClient()

# Step 1: Create dedicated inbox for service
def create_service_inbox(service_name: str):
    inbox = client.inboxes.create(
        username=f"{service_name}-{int(time.time())}",
        client_id=f"service-{service_name}-primary"
    )

    print(f"Created inbox for {service_name}: {inbox.address}")

    return inbox

# Step 2: Sign up for external service
def sign_up_for_service(email: str, service_name: str):
    # Example: Sign up for a hypothetical API service
    response = requests.post('https://api.example-service.com/signup', json={
        'email': email,
        'name': 'AI Agent',
        'company': 'Acme Corp',
        'use_case': 'Automated integration'
    })

    response.raise_for_status()

    print(f"Signup initiated for {service_name}")
    return response.json()

# Step 3: Wait for confirmation email
def wait_for_confirmation_email(
    inbox_id: str,
    from_domain: str,
    timeout_seconds: int = 300
) -> Optional[Dict]:
    start_time = time.time()
    authed_client = DaimonClient(api_key=os.environ.get('DAIMON_API_KEY'))

    while time.time() - start_time < timeout_seconds:
        messages = authed_client.inboxes.messages.list(inbox_id)

        confirmation_email = next(
            (msg for msg in messages
             if from_domain in msg['from']
             and any(keyword in msg['subject'].lower()
                    for keyword in ['confirm', 'verify', 'activate'])),
            None
        )

        if confirmation_email:
            print(f"Received confirmation email: {confirmation_email['subject']}")
            return confirmation_email

        # Poll every 5 seconds
        time.sleep(5)

    raise TimeoutError('Timeout waiting for confirmation email')

# Step 4: Extract and follow verification link
def activate_account(confirmation_email: Dict):
    # daimon.email automatically detects CTA links
    cta_links = confirmation_email.get('cta_links', [])

    if not cta_links:
        raise ValueError('No verification link found in email')

    verification_link = cta_links[0]  # First CTA is usually the main action
    print(f"Found verification link: {verification_link['text']}")
    print(f"URL: {verification_link['url']}")

    # "Click" the verification link
    response = requests.get(verification_link['url'], allow_redirects=True)

    if response.ok:
        print('Account activated successfully!')
        return True
    else:
        raise Exception(f"Activation failed: {response.status_code}")

# Step 5: Extract credentials from welcome email
def extract_credentials(inbox_id: str, from_domain: str):
    authed_client = DaimonClient(api_key=os.environ.get('DAIMON_API_KEY'))

    # Wait for welcome/credentials email
    time.sleep(10)

    messages = authed_client.inboxes.messages.list(inbox_id)

    welcome_email = next(
        (msg for msg in messages
         if from_domain in msg['from']
         and any(keyword in msg['subject'].lower()
                for keyword in ['welcome', 'getting started', 'api key'])),
        None
    )

    if not welcome_email:
        print('No credentials email found (may require manual retrieval)')
        return None

    # Extract API key or other credentials from email body
    api_key_match = re.search(r'API Key:\s*([A-Za-z0-9_-]+)', welcome_email['body'])

    if api_key_match:
        api_key = api_key_match.group(1)
        print(f"Extracted API key: {api_key[:10]}...")
        return {
            'api_key': api_key,
            'email': welcome_email['to']
        }

    return None

# Complete flow
def complete_service_signup(service_name: str, from_domain: str):
    try:
        # Step 1: Create inbox
        inbox = create_service_inbox(service_name)

        # Step 2: Sign up for service
        sign_up_for_service(inbox.address, service_name)

        # Step 3: Wait for confirmation email
        confirmation_email = wait_for_confirmation_email(
            inbox.id,
            from_domain,
            300  # 5 minute timeout
        )

        # Step 4: Activate account
        activate_account(confirmation_email)

        # Step 5: Extract credentials
        credentials = extract_credentials(inbox.id, from_domain)

        print('\n✅ Service signup complete!')
        print(f"Inbox: {inbox.address}")
        print(f"Credentials: {credentials}")

        return {
            'inbox': inbox,
            'credentials': credentials,
            'success': True
        }

    except Exception as e:
        print(f"Signup failed: {e}")
        return {
            'success': False,
            'error': str(e)
        }

# Usage
if __name__ == '__main__':
    complete_service_signup('example-api', 'noreply@example-service.com')

Real-World Examples

API Platform Signup

// Sign up for Stripe, Twilio, etc.
await completeServiceSignup('stripe', 'noreply@stripe.com');
await completeServiceSignup('twilio', 'noreply@twilio.com');

SaaS Trial Activation

// Activate free trials for testing
await completeServiceSignup('datadog', 'noreply@datadoghq.com');
await completeServiceSignup('mongodb-atlas', 'noreply@mongodb.com');

E-commerce Account Creation

// Create accounts on e-commerce platforms
await completeServiceSignup('shopify', 'noreply@shopify.com');

Key Features

  • CTA detection: Automatically identifies verification/confirmation links
  • Polling with timeout: Graceful handling of delayed emails
  • Credential extraction: Parse API keys and login details from emails
  • Idempotent: Use clientId to prevent duplicate signups

Next Steps