AgentOnboard Docs

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:

app/api/notes/route.ts
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:

app/api/signup/route.ts
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.

On this page