Most agent signups fail at the verification step, not the form, because the service sends a code somewhere the agent can't read. This post explains why that step breaks, shows how an agent reads an emailed code from its own inbox, and sorts the usual signup blockers into the ones an inbox solves, the ones a sign-in built for agents removes, and the ones neither touches.
When your AI agent needs an emailed one-time code to sign up, it needs an inbox it can read, or an app that doesn't send the code at all. An AgentMail inbox gives the agent that inbox today, and apps that accept AgentID, our sign-in for AI agents, skip the code because the agent's address arrives already verified.
Text-message codes and CAPTCHAs are a different problem, and we'll be plain about that below. The pattern is familiar to anyone who has watched an agent try to sign up for something. It fills in the form in seconds, submits, and then waits on a screen that says "enter the code we sent you", with no way to see the code. Either a person steps in and reads it out, or the task dies. We'll look at why that step and the login flows around it break for agents, then at the three ways through, including the one that works today in a dozen lines of code.
Why do agent signups die at the verification step?
Agent signups die at the verification step because the code goes to an email address or phone the agent doesn't control. A one-time passcode, or OTP, is the short number a service sends to prove you own an address or a phone, and the whole point is that only the owner can read it. An agent signing up with its owner's address has handed that proof to someone else. Email as identity for AI agents explains why the email address carries so much weight online; the OTP is where that weight lands.
So the agent needs an address of its own, one that receives mail it can read through an API. Without one, every signup has a human-shaped hole in the middle.
Why do login and OAuth flows break when an AI agent tries to sign in?
Login and OAuth flows break for agents at two mechanisms built around a person: consent screens that wait for a human click, and CAPTCHA.
An OAuth consent screen is the page that lists what an app will receive and waits for someone to click Allow. Nothing in that step is designed for software to answer, so an agent driving a browser either stalls there or clicks through on a person's behalf, which makes the consent that person's in name only.
A CAPTCHA exists to tell people from software. An agent that fails one is doing exactly what the test was built to catch, and an agent that gets past one has defeated its purpose. Neither outcome is a fix, which is why we don't offer one.
How does an agent read an email OTP from its own inbox?
An agent reads an email OTP by watching its own inbox for the service's message and pulling the code out of the body. The function below polls an AgentMail inbox until a message from the expected sender arrives, then returns the first six-digit number in it.
import { AgentMailClient } from "agentmail";
const client = new AgentMailClient({ apiKey: process.env.AGENTMAIL_API_KEY });
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
// Poll the agent's inbox for a one-time code from one sender.
async function waitForCode(inboxId: string, sender: string, timeoutMs = 300_000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const { messages } = await client.inboxes.messages.list(inboxId, {});
const hit = messages.find((m) => m.labels.includes("received") && m.from.includes(sender));
if (hit) {
const message = await client.inboxes.messages.get(inboxId, hit.messageId);
const code = message.text?.match(/\b\d{6}\b/)?.[0];
if (code) return code;
}
await sleep(3000);
}
throw new Error(`No code from ${sender} within ${timeoutMs / 1000} seconds.`);
}
const code = await waitForCode(process.env.AGENT_INBOX_ID as string, "@example.com");Two changes make it production-ready. Subscribe to the message.received webhook or websocket event rather than polling, so the agent reacts the moment the code lands, and ignore messages that arrived before the agent asked for the code, so an old code from the same sender isn't reused. Codes aren't always six digits, so match the format the service actually sends. Setting up the inbox itself is covered in an email address for your AI agent's signups.
Is relaying the code through a human a real fix?
Relaying the code through a human works, but it isn't a fix. Someone has to be awake, watching the right inbox or phone, and fast enough to pass the code on before it expires, and the agent waits the whole time.
It also ties the agent to one person's accounts. Every signup becomes a small interruption for its owner, and the agent can't do the task at three in the morning, which is usually why it was given the task in the first place.
When can the agent skip the OTP entirely?
The agent skips the OTP entirely at apps that accept AgentID. Its inbox address is its AgentID, and the app receives that address already verified, checked live when the sign-in token is minted, with email_verified always set to true. There is no code to send because the sign-in itself proves the agent controls the address.
The consent step changes shape too. The agent approves what the app will receive with its own sign-in key, and that approval is remembered for 180 days for that inbox and app. If the app asks who owns the agent and the agent isn't allowed to share it, the owner approves from their AgentMail account instead of a code going to their phone. The app side of this is explained in how an AI agent proves its identity to your app.
Which signup blockers can an agent get past?
An agent with its own inbox gets past emailed codes, and AgentID removes them at the apps that accept it. The rest of the usual blockers need something else entirely.
| Signup blocker | What an agent inbox solves | What AgentID solves | What neither solves |
|---|---|---|---|
| Email OTP or link | The agent reads the code or link itself | No code at apps that accept AgentID; the address arrives verified | Nothing left over |
| SMS OTP | Nothing; an inbox receives email, not texts | Nothing | The service still wants a phone number |
| OAuth consent screen | Nothing | The agent approves with its own key at apps that accept AgentID | Consent screens at other apps still expect a person |
| CAPTCHA | Nothing | Nothing | The test exists to stop software |
| Credit card | Receipts and invoices arrive in the agent's inbox | Nothing | Paying is a separate problem |
Email verification is solved, and the rest of that table is not ours to claim. The AgentID overview on AgentMail shows how the inbox and the sign-in fit together, and the pricing page lists what each plan includes.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.

