auth.group

The auth.group namespace provides methods for managing groups (organizations, teams, workspaces, etc.). Groups can be nested to form a hierarchy.

Methods

MethodSignatureReturnsDescription
create(ctx, { data: { name, slug?, type?, parentGroupId?, extend? } })Id<"Group">Creates a new group. Optionally nest under a parent group.
get(ctx, { id })Doc<"Group">Reads a group document by ID.
list(ctx, { where?, paginationOpts, orderBy?, order? })PaginationResult<Doc<"Group">>{ page, isDone, continueCursor }Lists groups, optionally filtered by parent. Convex-native shape.
update(ctx, { id, patch })nullUpdates a group’s name, slug, type, parent, or extend metadata.
remove(ctx, { id })nullDeletes a group and all its nested children, members, and invites.

Examples

Create a group with tags

Tags are useful for categorizing groups (e.g. plan tier, region):

const groupId = await auth.group.create(ctx, {
  data: {
    name: "Acme Corp",
    type: "workspace",
    extend: { plan: "pro" },
  },
});

Create a nested group

const teamId = await auth.group.create(ctx, {
  data: {
    name: "Engineering",
    parentGroupId: orgId,
    type: "team",
  },
});

Walk the hierarchy

const tree = await auth.group.get(ctx, { id: teamId, tree: true });
// tree?.ancestors => [{ _id: orgId, name: "Acme Corp", ... }]

Update group metadata

await auth.group.update(ctx, {
  id: groupId,
  patch: {
    slug: "acme",
    extend: { plan: "enterprise" },
  },
});

Denormalized fields

Groups include two denormalized fields maintained automatically:

FieldTypeDescription
rootGroupIdId<"Group">The root ancestor of this group. Self-referencing for root groups.
isRootbooleantrue when the group has no parent. Used for efficient root group queries.

These fields are computed at creation time and cascaded on hierarchy changes. You can use them for efficient queries like listing all root groups:

const workspaces = await auth.group.list(ctx, {
  where: { isRoot: true },
  paginationOpts: { numItems: 25, cursor: null },
});