+
+
+
+
+
+
+
+
Blog/Blog

How an AI Agent Creates Its Own Account

BPBinoy Perera

How an AI agent signs up for a service on its own: an AgentMail inbox as its email address, a one-time browser enrollment, and a click on Sign in with AgentID. No OTP goes to a human and no human credentials are involved.

Guide
Blog
AgentID
agent-accounts
agent-email
TL;DR
  • The OTP is where agents get stuck today. The verification email goes to a human's inbox, so the agent either waits for a person or borrows their account. An inbox of its own removes both.
  • Enrollment happens once. The agent posts an API key, its browser generates a non-extractable key, and every later sign-in is a fresh signature from that browser.
  • Signup is one click. At an app with the button, the agent signs in as itself; the app creates the account from the id_token.
  • The account is the agent's. Its own inbox, its own credential, its own revocation. The owner is a separate claim the app can request.

An AI agent creates its own account the way a person does, once it has the two things a person brings to a signup form: an email address it can read, and a way to prove it is the same entity next time.

With AgentMail, the agent gets an inbox of its own.

With AgentID, the sign-in for AI agents built on those inboxes, it enrolls a browser once. That generates a private key that stays in the browser, and from then on the agent clicks Sign in with AgentID at any app that shows the button.

The app receives a verified email and a stable identifier. It sends its confirmation and its receipts to the agent's inbox, and the agent reads them.

No human types an OTP, and no human's credentials are involved.

The whole path from bare agent to working account is three steps plus a hand-off for agents without a browser. Only the first two happen once.

Why can't an AI agent just fill in the signup form?

An AI agent can fill in a signup form but cannot finish the process, because signup was designed around a person who owns an email address and a phone.

Walk through what happens. The agent types an email into the form. Whose?

If it uses its owner's address, the confirmation code lands in the owner's inbox. The agent either has to wait for the owner to paste it back, or already has access to the owner's mail, which means the owner has handed over far more than a signup.

From there, the problems compound:

  • The app records the owner as the customer. The agent is invisible in the account record.
  • Agents blur together. If the owner runs five agents, the app sees one person with five accounts, or one account shared five ways, and cannot tell which.
  • Email goes to the wrong person. When the app later emails a receipt, a support reply, or a security alert, it goes to a person who may not know the account exists.

That last case is not hypothetical. After AgentMail shipped an API endpoint that let agents sign up directly, the company started emailing new users to ask how they had heard about it.

Many of them did not know they had signed up at all, because their agent had done it. Most support requests started arriving from agents.

Browser-automation tutorials that teach an agent to complete a signup form with a human's address are teaching the problem. The fix is to give the agent the two things the form is really asking for.

Step one: how does an AI agent get its own email address?

An AI agent gets its own email address through AgentMail, which creates an inbox by API call, with an address like support@acme.agentmail.to or on a domain the owner controls.

The inbox is the agent's identity for everything that follows. It is where:

  • Confirmation emails arrive.
  • The agent receives invoices and product updates.
  • The agent can open and answer support threads.

Inboxes are programmatic, so an agent framework can create one per agent, and the owner's organization holds the API key that created them. Inboxes start at $20 per month.

This is also what makes AgentID work at almost every app. An OpenID Connect identity that is an email address is one that existing signup flows already know how to handle; the app can email it, and the email will be read.

Step two: how does the agent enroll a browser for sign-in?

Enrollment is the one-time step that turns an AgentMail inbox into a sign-in credential.

  1. The agent posts its AgentMail API key to the enrollment endpoint on auth.agentid.com.
  2. JavaScript on that page generates a P-256 keypair inside the agent's browser.
  3. The page submits the public key to AgentID.

The private key is a non-extractable WebCrypto key stored in IndexedDB under the auth.agentid.com origin. In AgentMail's words: "Your private key is generated and stored in your browser and cannot be exported through browser JavaScript APIs."

A headless browser is fine; most agents run one already.

The API key is used at enrollment and is never part of a sign-in afterwards, so it does not travel to any app the agent later signs into.

If the agent runs in an environment with no browser at all, it does not lose the ability to sign in. The hand-off described below covers that case.

Step three: how does the agent sign up at an app?

The agent visits an app that shows Sign in with AgentID and clicks it, the way a person clicks Sign in with Google.

  1. The app redirects. The app redirects to https://auth.agentid.com/v0/authorize with a PKCE challenge.
  2. The browser signs. The enrolled browser recognizes its session and produces a fresh, one-time signature over a transaction the server generated for this sign-in.
  3. The agent reviews. A disclosure screen shows which app is asking and what it will receive: the agent's inbox address and name, and the owner's email and name if the app requested them.
  4. The agent decides. The agent approves or abandons.
  5. The app exchanges the code. The browser returns to the app's callback with an authorization code, the app exchanges it, and the app now holds an id_token.

From the app's side this is a standard OpenID Connect sign-in. OIDC for AI agents: the complete guide has the wire format.

The id_token contains a stable sub, the agent's verified email, and email_verified: true. The app creates an account keyed on sub, or resumes the existing one if this agent has been here before.

There is no password to store and no OTP to send, because the identity was verified by AgentID at token mint.

The confirmation email the app sends anyway lands in the agent's inbox, and the agent reads it.

Signup stepAgent borrowing its owner's accountAgent with its own AgentID
Email address on the formThe owner'sThe agent's own AgentMail inbox
Verification codeSent to the owner; agent waits or reads the owner's mailNone needed; email verified live at token mint
Credential stored by the appA password the agent and owner both knowNothing reusable; the app verifies a signature against published keys
Who the app thinks the customer isThe ownerThe agent, with the owner available as a claim
Where receipts and support replies goThe owner's inboxThe agent's inbox
Revoking the agentChange the owner's password, breaking everything elseRevoke one enrolled credential; nothing else is touched

What if the agent has no browser?

If the agent has no browser, its owner signs in for it, and the resulting account still belongs to the agent.

  1. The owner opens the app's sign-in in their own browser.
  2. The owner chooses Approve manually.
  3. The owner authenticates in the AgentMail console at console.agentmail.to.
  4. The owner selects the agent's inbox and approves.

The flow has to finish in that same browser; there is no approval code to carry to another session.

The app receives the same id_token it would have received from the agent's browser, naming the agent as the subject. The account belongs to the agent rather than the person who clicked.

For the app, the customer record is still the agent's inbox rather than the owner's account, and any later sign-in from an enrolled browser resolves to the same sub.

What does the app learn about the agent and its owner?

The app learns only what it asked for, and it learns about the owner only if it registered a client.

  • Open clients (a URL as the client_id, no registration) receive openid and email, and nothing about the owner.
  • Registered clients (registered with an AgentMail API key) can request the owner_email and owner_profile scopes.

Those owner values are not in the id_token. The app reads them from /v0/userinfo with the access token after the exchange.

If the agent's credential does not permit owner disclosure, a sign-in that requests it fails with a 403 instead of returning a token quietly missing the claim.

The disclosure screen the agent sees lists exactly these items before it approves.

On the app side, the owner claim is what turns "an agent signed up" into "an agent signed up and here is the person to call." That is the property that lets apps allow agents rather than block them.

The relying-party view of that decision is in can an AI agent sign up for a SaaS.

What does the agent do with the account afterwards?

An AI agent uses its account the same way a user does.

  • Onboarding: it receives the onboarding sequence in its own inbox and can act on it.
  • Billing: it gets invoices and receipts addressed to itself.
  • Support: when something breaks, it opens a support ticket from its own address and reads the reply.
  • Owner access: if the owner wants access to what the agent set up, the agent can invite them into the app's organization as a separate member with their own permissions, rather than sharing a login.

Because the agent's identity is an email address, the app does not need to build anything new to communicate with it. Every transactional email an app already sends to human users works for agent users unchanged.

AgentMail is building a Providers directory inside its console where agents can discover apps that accept AgentID and start sign-ins from there; that work is in progress.

The public list of apps accepting the button today is at the AgentID directory.

What does this look like from the developer's side?

From the developer's side, agent builders follow three steps and app builders follow one.

If you build agents:

  1. Create an inbox per agent through the AgentMail API.
  2. Run the browser enrollment once per agent.
  3. Point the agent at apps that show the button.

If you build apps, the sequence is shorter. Add AgentID as a custom OIDC provider with the issuer and a client_id, or run npx @agentmail/agentid-cli init in your project to have it detect and configure Clerk, Supabase, Auth0, Better Auth, or Auth.js.

The relying-party walkthrough is in how to let an AI agent sign in to your website.

AgentID gives your agent a verified identity and its own email address. Free for apps to add.

FAQ

Let your agent sign in. Give it an AgentID and its own email address.