Using with Better Auth
How to authenticate AI agents with Better Auth — resolve users by email and provision agent-created accounts.
Better Auth manages human sessions, cookies, and social logins. AgentOnboard provides the machine-to-machine identity layer so AI agents can call your Better Auth-protected API.
1. Verifying existing Better Auth users
In your route handler, use requireAgentAccount and query your database or Better Auth instance:
import { auth } from "@/lib/auth"; // Your Better Auth server instance
import { requireAgentAccount } from "@agentonboard/sdk/next";
export async function POST(request: Request) {
const session = await requireAgentAccount(request, {
audience: "notes.com",
resolveAccount: async ({ email }) => {
// Find user in Better Auth database
const user = await db.query.user.findFirst({
where: (users, { eq }) => eq(users.email, email.toLowerCase()),
});
return user?.id ?? null;
},
});
// Automatically returns 401 or 403
if (!session.ok) return session.response;
// session.user is your Better Auth user ID
return Response.json({ success: true, user_id: session.user });
}2. Enabling agent signup with Better Auth
To allow agents to sign up on behalf of users, add an explicit signup route using createAgentAccount:
import { auth } from "@/lib/auth";
import { createAgentAccount } from "@agentonboard/sdk";
export async function POST(request: Request) {
const outcome = await createAgentAccount({
token: request.headers.get("Authorization") ?? "",
audience: "notes.com",
resolveAccount: async ({ email }) => {
const user = await db.query.user.findFirst({
where: (users, { eq }) => eq(users.email, email.toLowerCase()),
});
return user?.id ?? null;
},
createAccount: async ({ email }) => {
// Create user in your Better Auth user table
const [newUser] = await db.insert(usersTable).values({
id: crypto.randomUUID(),
email: email.toLowerCase(),
emailVerified: true,
createdAt: new Date(),
updatedAt: new Date(),
}).returning();
return newUser.id;
},
});
if (!outcome.ok) {
return Response.json(
{ code: outcome.code, error: outcome.error },
{ status: outcome.code === "RESOLVER_ERROR" ? 500 : 401 }
);
}
return Response.json(
{ user_id: outcome.user, created: outcome.created },
{ status: 201 }
);
}emailVerified: true
Because AgentOnboard tokens are only issued to humans who have verified their inbox, you can set emailVerified: true immediately upon account creation.