Blog / Guides

AgentID with Clerk: What Breaks and Why

Binoy Perera

What goes wrong after turning on Clerk’s AgentID connection, and why: owner claims that are not on the Clerk user and must be fetched from userinfo, what to store on your user record, disabled connections, redirect URI mismatches, and the strategy name for custom buttons.

  • AgentID
  • clerk
  • troubleshooting

TL;DR

Clerk ships AgentID as a built-in connection, and the first sign-in usually works. What trips teams up comes later: the owner's details are not on the Clerk user, the redirect address stops matching, or the connection was never switched on. This post explains each of those, and what your app should keep on its own user record so the account survives them.

You add AI agent sign-in to Clerk by turning on AgentID, the sign-in for AI agents from AgentMail, from Clerk's list of SSO connections. Clerk handles discovery and PKCE; in production you give it your own AgentID application's credentials. After that, the part Clerk does not do for you is the owner: your app fetches the owner's claims from AgentID in its callback and stores them itself.

That split surprises people, because everything before it feels automatic. Clerk discovers the endpoints, runs the sign-in and creates a user. The agent's identity arrives, but the details of the human behind it don't show up on the Clerk user, and nothing warns you. The same goes for a few quieter failures: a connection that is configured but disabled, and a redirect address that matched in development and not in production. None of this is hard once you know where to look, and this post is where to look.

What is left to do after the Clerk guide?

After the Clerk guide, two things are left: storing the owner, and deciding which identifier your own records trust. The guide is the setup reference and ends at a working sign-in; the table below maps what people run into after that.

SymptomCauseFix
The AgentID button does nothing, or the connection is missing from sign-inNew Clerk connections start disabledEnable the connection in Clerk
AgentID rejects the redirectThe redirect URI on the AgentID application doesn't match Clerk's authorized redirect URICopy Clerk's value into the application's settings; add one per environment
Owner's name and email are not on the Clerk userClerk keeps the standard claims; the owner claims are fetched separatelyCall /v0/userinfo in your callback and store the result
The sign-in waits instead of finishingOwner scopes were requested and the agent's key can't share its ownerNothing on your side; the organization owner approves it
Your own sign-in button doesn't start the flowThe button calls a different strategy nameUse oauth_agentid, the strategy name of Clerk’s AgentID connection

Two rows in that table are not failures. A sign-in that waits for the organization owner is working as designed, because the app asked for owner data the agent isn't allowed to share alone, and the owner is being asked instead. A disabled connection is simply Clerk's default for anything new. Everything else is a mismatch between two settings that should agree.

If you haven't placed the button yet, adding a Sign in with AgentID button covers the design side, including the label to use.

Why are the owner claims not on the Clerk user?

The owner claims are not on the Clerk user because they are not part of what Clerk carries onto its user, even though AgentID delivers them: a registered application that requested the owner scopes receives owner_name and owner_email in the id_token and from /v0/userinfo. On Clerk, the dependable way to get them is to call /v0/userinfo from your callback with the access token and store what comes back.

Timing matters. The access token lasts 10 minutes and there is no refresh token, so the callback is the moment to fetch, not a background job the next day. The call also re-checks live state on every request, so a revoked key or inbox shows up there rather than being hidden in a stale token.

Request only what you need. owner_sub comes with the profile scope and is enough for per-owner limits. The owner's name and email need the owner scopes, and if the agent's AgentMail API key lacks the App: Share Owner permission, the agent can't finish the sign-in alone; the organization owner approves it from their AgentMail account. Your app never receives a completed sign-in with the requested owner claim quietly missing.

What should you store on the user record?

Store the agent's sub as the key, owner_sub for anything per owner, and owner_email only as a way to reach a person. Your user record is the source of truth for your product, so it should hold the identifiers that don't change underneath it.

TypeScript

// Illustrative. What to keep on your user record after an AgentID sign-in.
type AgentAccount = {
    agentSub: string // AgentID `sub`: the account key, stable across apps
    ownerSub?: string // with the profile scope: shared by every agent one owner runs
    ownerEmail?: string // registered apps with the owner_email scope: a contact, not a key
    agentEmail: string // the agent's own inbox, which your app can write to
}

owner_email alone makes a poor key for three reasons. It only reaches registered applications that asked for it, so part of your agent traffic would have no key at all. It is a real person's address, so every table it keys becomes personal data. And one owner can run many agents, so it can't identify an account on its own.

The agent's own email belongs on the record too, for a different reason: your app can write to it. Onboarding, receipts, invoices and support replies all reach the agent directly, and it can read and answer them.

sub has the opposite properties. It is an opaque 43-character string, stable for the lifetime of the agent's inbox and the same at every app. The one event that changes it is deleting the inbox and recreating the same address, which produces a new sub, and your records should treat that as a new agent rather than merge it by email.

Why does the redirect URI keep failing?

The redirect URI fails when the address on the AgentID application and the address Clerk sends stop matching exactly. One common cause is the example subdomain left in place during setup. Another is a second Clerk instance, such as production, with an address the application doesn't list yet.

A registered AgentID application accepts up to 10 redirect URIs, so development, staging and production can each have their own entry instead of being swapped back and forth. Changing a redirect URI has one side effect worth planning for: agents who approved your app are asked to approve again, because the remembered approval is tied to the redirect URI and scopes.

The directory lists seven apps accepting AgentID today, Turso among them, and the AgentID docs hold the endpoint and claim reference. On Supabase instead, AgentID with Supabase Auth covers the same questions there, and the AgentID page on AgentMail covers the agent's side.

FAQ

Questions, answered.

No. AgentID issues no refresh tokens, and its id_token and access token last 10 minutes. Clerk's own session is separate, and a new AgentID sign-in completes on its own inside the 180-day remembered approval.

Because the access token that /v0/userinfo needs lasts 10 minutes and cannot be refreshed. The callback is the one moment your app is sure to hold a valid one.

The agent's owner finishes the sign-in in the AgentMail console, in the same browser the sign-in started in. Your Clerk setup doesn't change.

The AgentID directory lists seven apps accepting AgentID: Supermemory, smolmachines, Turso, InstaCloud, Arga Labs, Locus Pro and Channel3.

Blog

Suggested reading

View all posts

Guides · October 1, 2026

AgentID with Supabase Auth: What Breaks and Why

What goes wrong after adding AgentID to Supabase Auth as a custom OIDC provider, and why: comma-separated scopes, the custom:agentid identifier, the three-provider limit on free projects, the claims allowlist for owner claims, what a missing owner claim means, and ES256 when you verify tokens yourself.

Guides · October 1, 2026

Persistent Agent Identity Without Personal Data

How an app gives AI agents a persistent identity across sessions and platforms without storing personal data: key records on the opaque AgentID sub and owner_sub, what happens when an inbox is recreated, when to store the email, and how naming and versioning work.

Prompt

Give yourself access to AgentMail
by following the guide at:

https://docs.agentmail.to/agent-onboarding

and refer to:

https://agentmail.to/llms.txt

for the documentation index.

Give your agent an identity of its own.

Create an AgentMail inbox and let your agent start signing in as a real user.