How to let an AI agent
sign up for a service on its own.
Sign-up flows assume a human with an inbox and a phone. Here's how to give the agent both — and let it complete the flow without a person in the loop.
Modern agents often need to register for services — a data source, a free tier of an API, a trial account. Every sign-up flow assumes the registrant is a human with an email inbox to verify, possibly a phone for 2FA, and a safe place to store the resulting credentials.
A Loomal identity gives the agent all three. This recipe walks through the end-to-end flow: start the sign-up, receive the verification email, complete 2FA, and store the resulting credentials for future use.
1. Submit the sign-up form
The agent drives the form — via Playwright, a browser-automation tool, or the service's API if it exposes a self-serve sign-up. The email field gets the agent's Loomal address; other fields come from the agent's persona configuration.
Don't use a human operator's email for this. The whole point is that the agent has its own identity — verification codes and password resets should come to the agent, not to you.
from playwright.async_api import async_playwright
import os
AGENT_EMAIL = "agent-x8k2m@loomal.ai"
async def sign_up(service_url: str):
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto(service_url + "/signup")
await page.fill('[name="email"]', AGENT_EMAIL)
await page.fill('[name="password"]', generate_password())
await page.click("button[type=submit]")
# Now wait for the verification email2. Poll for the verification email
After submission, the service sends a confirmation link or code to the agent's address. Wait for it, extract the link, follow it.
Most services send within seconds. Cap the wait at a minute or two; if nothing arrives, the sign-up probably failed upstream (captcha, rate limit, etc.).
import asyncio, re, os, requests
async def wait_for_link(sender: str, timeout_s: int = 60) -> str | None:
for _ in range(timeout_s // 2):
res = requests.get(
"https://api.loomal.ai/v0/messages",
headers={"Authorization": f"Bearer {os.environ['LOOMAL_API_KEY']}"},
params={"from": sender, "labels": "unread", "limit": 1},
timeout=5,
)
messages = res.json()["messages"]
if messages:
match = re.search(r"https?://\S+verify\S+", messages[0]["extractedText"])
if match:
return match.group(0)
await asyncio.sleep(2)
return None3. Store the credentials the agent just created
After sign-up, the agent chose a password (or was issued an API key). Put it in the vault immediately — don't keep it in process memory or a log. Label by service name so the agent can look it up on future runs.
def remember(service: str, password: str):
requests.post(
"https://api.loomal.ai/v0/vault",
headers={"Authorization": f"Bearer {os.environ['LOOMAL_API_KEY']}"},
json={"label": f"{service}-password", "value": password},
timeout=5,
)4. Enroll 2FA if the service requires it
If the service requires 2FA post-signup, it typically presents a QR code or an otpauth URL. Capture the secret and store it in the vault's TOTP section. From this point, vault.totp(label) returns the current six-digit code on demand.
# After capturing the otpauth URL during 2FA setup:
curl -X POST https://api.loomal.ai/v0/vault \
-H "Authorization: Bearer $LOOMAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "service-totp",
"otpauth": "otpauth://totp/Service:agent?secret=..."
}'5. Future logins are now fully autonomous
On subsequent runs, the agent looks up vault.get('service-password') for the password and vault.totp('service-totp') for the current 2FA code. No human in the loop, no shared credentials, no .env entries. The credentials live and die with the agent identity.
FAQ
Is it ethical to have an AI agent sign up for services?
Check the service's terms. Most SaaS terms allow automated sign-up under a real identity for legitimate use; some prohibit it. If in doubt, use the service's B2B sales channel to set up the agent's access with explicit consent.
What about captcha?
Captcha is the hardest part. Some can be bypassed with 2captcha-style services; others (reCAPTCHA v3 and similar) are very hard. For critical services, expect to need a human in the signup loop — but only once.
Can I use this pattern for OAuth flows?
Yes, but OAuth grants are a separate concern — the resulting refresh token goes in the vault too. See the OAuth-tokens stop-sharing piece for the design rationale.
Related reading
Last updated: 2026-04-15