Agent Self-Signup

Let your AI agent sign up for any service automatically using browser automation and mails-agent.

Many services require email verification during signup. By combining browser automation (Playwright or Puppeteer) with mails-agent's verification code extraction, your agent can complete the entire signup flow without human intervention.

The Flow

Step 1 -- Claim a mailbox

Create a dedicated email address for the agent to use during signup.

Step 2 -- Navigate to signup page

Use Playwright or Puppeteer to open the target service's registration page.

Step 3 -- Fill in the email

Enter the claimed mailbox address into the email field.

Step 4 -- Submit the form

Click the signup button and wait for the verification email to arrive.

Step 5 -- Extract the verification code

Use mails code --timeout 60 to wait for and extract the code automatically.

Step 6 -- Enter the code

Fill the verification code into the confirmation page. Account created.

Full Example: Playwright + mails-agent CLI

import subprocess
from playwright.sync_api import sync_playwright

MAILS_API_KEY = "your_api_key"
MAILBOX = "[email protected]"

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # Step 1: Navigate to the signup page
    page.goto("https://example.com/signup")

    # Step 2: Fill in the signup form
    page.fill('input[name="email"]', MAILBOX)
    page.fill('input[name="password"]', "SecureP@ss123")
    page.fill('input[name="name"]', "AI Agent")

    # Step 3: Submit the form
    page.click('button[type="submit"]')
    page.wait_for_url("**/verify**")

    # Step 4: Wait for the verification code (blocks up to 60s)
    result = subprocess.run(
        ["mails", "code", "--to", MAILBOX, "--timeout", "60"],
        capture_output=True, text=True
    )
    code = result.stdout.strip()
    print(f"Got verification code: {code}")

    # Step 5: Enter the code
    page.fill('input[name="code"]', code)
    page.click('button[type="submit"]')

    # Step 6: Verify success
    page.wait_for_url("**/dashboard**")
    print("Signup complete!")
    browser.close()

Full Example: Playwright + Python SDK

import time
from playwright.sync_api import sync_playwright
from mails_agent import MailsClient

client = MailsClient(api_key="your_api_key")
MAILBOX = "[email protected]"

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # Navigate and fill signup form
    page.goto("https://example.com/signup")
    page.fill('input[name="email"]', MAILBOX)
    page.fill('input[name="password"]', "SecureP@ss123")
    page.click('button[type="submit"]')
    page.wait_for_url("**/verify**")

    # Wait for verification code via SDK
    code_response = client.wait_for_code(to=MAILBOX, timeout=60)
    code = code_response.code
    print(f"Got code: {code}")

    # Enter code and complete signup
    page.fill('input[name="code"]', code)
    page.click('button[type="submit"]')
    page.wait_for_url("**/dashboard**")
    print("Signup complete!")
    browser.close()

Full Example: Puppeteer + curl

const puppeteer = require("puppeteer");
const { execSync } = require("child_process");

const API = "https://mails-worker.genedai.workers.dev";
const TOKEN = "your_api_key";
const MAILBOX = "[email protected]";

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  // Navigate and fill form
  await page.goto("https://example.com/signup");
  await page.type('input[name="email"]', MAILBOX);
  await page.type('input[name="password"]', "SecureP@ss123");
  await page.click('button[type="submit"]');
  await page.waitForNavigation();

  // Wait for verification code via API
  const resp = await fetch(
    `${API}/v1/code?to=${MAILBOX}&timeout=60`,
    { headers: { Authorization: `Bearer ${TOKEN}` } }
  );
  const { code } = await resp.json();
  console.log(`Got code: ${code}`);

  // Enter code
  await page.type('input[name="code"]', code);
  await page.click('button[type="submit"]');
  await page.waitForNavigation();
  console.log("Signup complete!");

  await browser.close();
})();

Using the CLI only (no browser automation)

If the signup flow is API-based (no browser needed), you can do everything with curl and the mails CLI:

# 1. Register via API
curl -X POST https://example.com/api/register \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "SecureP@ss123"}'

# 2. Wait for verification code
CODE=$(mails code --to [email protected] --timeout 60)
echo "Verification code: $CODE"

# 3. Verify the account
curl -X POST https://example.com/api/verify \
  -H "Content-Type: application/json" \
  -d "{\"email\": \"[email protected]\", \"code\": \"$CODE\"}"

How code extraction works

The /v1/code endpoint and mails code CLI command use pattern matching to extract verification codes from incoming emails. They support:

The --timeout flag makes the request block until a matching email arrives (long-polling), so you do not need to implement retry logic yourself.

Headless Agent Self-Registration

For fully automated (headless) agent registration, use the claim API flow:

# Step 1: Start a claim session
SESSION=$(curl -s -X POST -H "Content-Type: application/json" \
  "https://mails0.com/v1/claim/start" \
  -d '{"name": "my-agent"}' | jq -r '.session_id')

# Step 2: Confirm the claim
curl -s -X POST -H "Content-Type: application/json" \
  "https://mails0.com/v1/claim/confirm" \
  -d "{\"session_id\": \"$SESSION\"}"

This creates [email protected] and returns a mailbox-scoped API key.

Tips for reliability