Skip to main content
Neon Postgres Docs

Search documentation

Type to search this documentation.

On this pageOverview

Admin

Managed Better Auth is built on Better Auth and provides support for Admin plugin APIs through the Neon SDK. You do not need to manually install or configure the Better Auth Admin plugin. The Admin pl...

Managed Better Auth is built on Better Auth and provides support for Admin plugin APIs through the Neon SDK. You do not need to manually install or configure the Better Auth Admin plugin.

The Admin plugin provides APIs to manage your users and their authentication state. It’s commonly used to build internal tooling (admin dashboards, support tools) that can:

  • Create and update users
  • Assign roles
  • Ban and unban users
  • List and revoke sessions
  • Impersonate a user for support/debugging
  • A Neon project with Auth enabled

  • An existing user with an admin role to call Admin APIs.

    You can assign the admin role to a user through the Neon Console. Navigate to Auth → Users, open the three‑dot menu next to the user, and select Make admin.

    Assign admin role in Neon Console

You can call Admin plugin methods using the Neon SDK auth client.

If you haven’t set up Managed Better Auth yet, follow the Next.js or React quick start to create an authClient.

Use the Admin APIs to create users on behalf of others (for example, back-office onboarding).

View parameters
ParameterTypeRequiredNotes
emailstring✓Email address for the new user
passwordstring✓Password for the new user
namestring✓Display name
rolestring | string[] | undefinedOptional role(s) for the user (for example: user , admin )
dataRecord<string, any> | undefinedOptional custom fields
TypeScript
const { data, error } = await authClient.admin.createUser({
  email: 'user@email.com',
  password: 'secure-password',
  name: 'User Name',
  role: 'user',
  data: { customUserField: 'value' },
});

List users with optional search, filtering, sorting, and pagination.

View parameters
ParameterTypeRequiredNotes
searchValuestring | undefinedValue to search for
searchField'email' | 'name' | undefinedField to search in
searchOperator'contains' | 'starts_with' | 'ends_with' | undefinedSearch operator
limitnumber | string | undefinedMax users to return (page size)
offsetnumber | string | undefinedNumber of users to skip (pagination)
sortBystring | undefinedField to sort by
sortDirection'asc' | 'desc' | undefinedSort direction
filterFieldstring | undefinedField to filter by
filterValuestring | number | boolean | undefinedFilter value
filterOperator'eq' | 'ne' | 'lt' | 'lte' | 'gt' | 'gte' | undefinedFilter operator
TypeScript
const { data, error } = await authClient.admin.listUsers({
  query: {
    // Following parameters are optional
    searchValue: 'text to search',
    searchField: 'email',
    searchOperator: 'contains',
    limit: 10,
    offset: 0,
    sortBy: 'name',
    sortDirection: 'asc',
  },
});

Use filterField, filterValue, and filterOperator to further filter results (for example, by role etc)

The data object contains a list of users and pagination metadata:

TypeScript
{
  users: [/* array of user objects */],
  total: 100, // total number of users matching the query
  limit: 10,  // limit used in the query
  offset: 0   // offset used in the query
}

Use the total, limit, and offset values to implement pagination in your admin tooling.

Assign roles to control who can call admin operations.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to update
rolestring | string[]✓Role(s) to apply (for example, admin )
TypeScript
const { error } = await authClient.admin.setRole({ userId: 'user-id', role: 'admin' });

Set or reset a user’s password.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to update
newPasswordstring✓The new password
TypeScript
const { error } = await authClient.admin.setUserPassword({
  userId: 'user-id',
  newPassword: 'new-secure-password',
});

Update user information such as email, name, and custom fields.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to update
dataRecord<string, any>✓Fields to update (email, name, custom fields)
TypeScript
const { error } = await authClient.admin.updateUser({
  userId: 'user-id',
  data: { name: 'New Name' },
});

Banning prevents sign-in for a user. You can optionally provide a reason and expiration for the ban.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to ban
banReasonstring | undefinedReason for the ban
banExpiresInnumber | undefinedDuration in seconds until the ban expires. If not provided, the ban does not expire
TypeScript
const { error } = await authClient.admin.banUser({
  userId: 'user-id',
  banReason: 'Policy violation',
  // banExpiresIn: 60 * 60 * 24, // optional (seconds)
});

Unban a previously banned user.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to unban
TypeScript
const { error } = await authClient.admin.unbanUser({ userId: 'user-id' });

Use session APIs to view active sessions and revoke them.

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID whose sessions you want to list
TypeScript
const { data, error } = await authClient.admin.listUserSessions({ userId: 'user-id' });
View parameters
ParameterTypeRequiredNotes
sessionTokenstring✓The session token to revoke
TypeScript
const { error } = await authClient.admin.revokeUserSession({ sessionToken: 'session-token' });
View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID whose sessions you want to revoke
TypeScript
const { error } = await authClient.admin.revokeUserSessions({ userId: 'user-id' });

Impersonation creates a session that behaves like the target user (useful for support and debugging).

View parameters
ParameterTypeRequiredNotes
userIdstring✓The user ID to impersonate
TypeScript
const { data, error } = await authClient.admin.impersonateUser({ userId: 'user-id' });

Stop an active impersonation session.

View parameters

This method does not take any parameters.

TypeScript
const { error } = await authClient.admin.stopImpersonating();
  • Admin operations require an authenticated session (HTTP-only cookies). This means your admin tooling must run on the same site that can send those cookies to the Managed Better Auth API.
  • Impersonation sessions are intentionally time‑limited, lasting for the duration of the active browser session or up to 1 hour. This design helps minimize security risks associated with long‑lived impersonation.

Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu