Skip to main content

Overview

Admin Users API manages platform administrator accounts through Clerk. Provides tools to list current admins, grant or revoke admin access, invite new admins, and search for existing users. All functions are Convex actions (Node.js runtime) that interact with the Clerk API. All functions require admin authorization. Location: convex/admins/adminUsers.ts

List Admin Users

Lists all users who have the admin role set in their Clerk public metadata. Returns up to 100 users. No arguments required.
const admins = await convex.action(api.admins.adminUsers.listAdminUsers, {});
[
  {
    "id": "user_abc123",
    "firstName": "Ali",
    "lastName": "Ahmed",
    "email": "ali@example.com",
    "imageUrl": "https://img.clerk.com/...",
    "createdAt": 1700000000000,
    "lastSignInAt": 1702500000000
  },
  {
    "id": "user_def456",
    "firstName": "Sara",
    "lastName": null,
    "email": "sara@example.com",
    "imageUrl": "https://img.clerk.com/...",
    "createdAt": 1701000000000,
    "lastSignInAt": null
  }
]
Fields firstName, lastName, email, and lastSignInAt may be null. The email is taken from the user’s first email address in Clerk.

Grant Admin Access

Grants admin access to an existing Clerk user by setting role: "admin" in their public metadata. The user must already exist in Clerk.
email
string
required
Email address of the existing Clerk user to promote
const result = await convex.action(api.admins.adminUsers.grantAdminAccess, {
  email: "newadmin@example.com"
});
{
  "success": true,
  "userId": "user_xyz789",
  "name": "Mohammed Khan"
}
Throws an error if no user is found with the given email or if the user is already an admin. The name field is constructed from Clerk’s firstName and lastName, defaulting to “Unknown” if both are empty.

Revoke Admin Access

Removes admin access from a user by removing the role key from their Clerk public metadata. Prevents self-revocation.
userId
string
required
Clerk user ID to revoke admin access from
const result = await convex.action(api.admins.adminUsers.revokeAdminAccess, {
  userId: "user_xyz789"
});
{
  "success": true
}
Throws an error if the requesting admin attempts to revoke their own access (identity.subject === args.userId).

Invite Admin

Sends a Clerk invitation email to a new user with admin role metadata. The invited user will be granted admin access upon signing up.
email
string
required
Email address to send the admin invitation to
const result = await convex.action(api.admins.adminUsers.inviteAdmin, {
  email: "newhire@example.com"
});
{
  "success": true,
  "invitationId": "inv_abc123"
}
Throws an error if a user with the given email already exists in Clerk. In that case, use grantAdminAccess instead. The invitation is created with { role: "admin" } public metadata so the user is automatically an admin upon signup.

Search User By Email

Searches for an existing Clerk user by email address. Used in the admin panel’s “add admin” dialog to preview user details before granting access.
email
string
required
Email address to search for
const user = await convex.action(api.admins.adminUsers.searchUserByEmail, {
  email: "someone@example.com"
});
{
  "id": "user_xyz789",
  "firstName": "Mohammed",
  "lastName": "Khan",
  "email": "someone@example.com",
  "imageUrl": "https://img.clerk.com/...",
  "isAdmin": false
}
Returns null if no user is found with the given email. The isAdmin flag indicates whether the user already has role: "admin" in their Clerk public metadata.