Features

Core Groups

Last updated July 2, 2026

Summary

Core Groups (GroupV1) are taxonomy accounts that organize Collections, Assets, and other groups into higher-level sets — for example a brand umbrella that contains multiple collections, or a curated directory of standalone assets.

  • Groups store their own name and URI, like collections
  • A group can directly contain up to 256 collections, child groups, parent-group links, or assets per vector
  • Collections and assets added to a group receive a Groups plugin listing their parent group addresses

Jump to: Create a group · Manage membership · Fetch groups

Collections vs Groups

Collections and groups solve different problems: collections manage member NFTs, while groups provide higher-level taxonomy across collections, assets, and child groups.

CollectionGroup
PurposeShared metadata and plugins for a series of NFTsTaxonomy / directory over collections, assets, and groups
Owns user NFTsYes — assets reference the collectionNo — assets remain in their collection (if any)
Typical question“Which series is this NFT from?”“Which brand, season, or directory includes this collection?”
On-chain membershipAsset updateAuthority points at the collectionMember listed in group.collections, group.assets, or group.groups

Use a Collection when you need collection-wide royalties, freeze rules, or shared artwork for a mint series. Use a Group when you need to organize multiple collections or standalone assets under one label without changing how those assets are minted.

GroupV1 account

A GroupV1 account stores:

FieldDescription
updateAuthorityAuthority that can update the group and change membership
nameDisplay name
uriOff-chain JSON metadata URI
collectionsCollections that are direct children of this group
groupsChild groups contained by this group
parentGroupsParent groups that contain this group
assetsAssets that are direct members of this group

On-chain limits (from mpl-core):

  • 256 entries max per vector (collections, groups, parentGroups, assets)
  • 8 parent groups max per group (MAX_GROUP_NESTING_DEPTH)

Groups plugin

When a collection or asset is added to a group, mpl-core ensures a Groups authority-managed plugin exists on that member. The plugin stores the parent group public keys.

Creating groups

Use createGroup / createGroupV1 to deploy a new group account:

1import { generateSigner } from '@metaplex-foundation/umi'
2import { createGroup } from '@metaplex-foundation/mpl-core'
3
4const group = generateSigner(umi)
5
6await createGroup(umi, {
7 group,
8 name: 'My Brand Directory',
9 uri: 'https://example.com/my-brand.json',
10 relationships: [],
11}).sendAndConfirm(umi)
12
13console.log('Group created:', group.publicKey)

You can optionally pass relationships at creation time to link collections, child groups, parent groups, or assets in one transaction. Each relationship entry uses RelationshipKind: Collection, ChildGroup, ParentGroup, or Asset.

Managing group membership

All membership changes are signed by the group update authority unless noted.

OperationSDK helperWhat it updates
Add collectionsaddCollectionsToGroupGroup collections + collection Groups plugin
Remove collectionsremoveCollectionsFromGroupBoth sides
Add assetsaddAssetsToGroupGroup assets + asset Groups plugin
Remove assetsremoveAssetsFromGroupBoth sides
Add child groupsaddGroupsToGroupParent groups + child parentGroups
Remove child groupsremoveGroupsFromGroupBoth sides
Update metadata / authorityupdateGroupGroup name, URI, update authority
Close empty groupcloseGroupCloses the group account

Add a collection to a group

1import { publicKey } from '@metaplex-foundation/umi'
2import { addCollectionsToGroup } from '@metaplex-foundation/mpl-core'
3
4const group = publicKey('GroupAddress...')
5const collection = publicKey('CollectionAddress...')
6
7await addCollectionsToGroup(umi, {
8 group,
9 authority: umi.identity,
10})
11 .addRemainingAccounts([
12 { pubkey: collection, isSigner: false, isWritable: true },
13 ])
14 .sendAndConfirm(umi)
15
16console.log('Collection added to group')

Add a standalone asset to a group

1import { publicKey } from '@metaplex-foundation/umi'
2import { addAssetsToGroup } from '@metaplex-foundation/mpl-core'
3
4const group = publicKey('GroupAddress...')
5const asset = publicKey('AssetAddress...')
6
7await addAssetsToGroup(umi, {
8 group,
9 authority: umi.identity,
10})
11 .addRemainingAccounts([
12 { pubkey: asset, isSigner: false, isWritable: true },
13 ])
14 .sendAndConfirm(umi)
15
16console.log('Asset added to group')

Nest groups

1import { addGroupsToGroup } from '@metaplex-foundation/mpl-core'
2
3// parentGroup and childGroup are existing GroupV1 accounts
4
5await addGroupsToGroup(umi, {
6 parentGroup: parentGroup.publicKey,
7 groups: [childGroup.publicKey],
8 authority: umi.identity,
9})
10 .addRemainingAccounts([
11 { pubkey: childGroup.publicKey, isSigner: false, isWritable: true },
12 ])
13 .sendAndConfirm(umi)
14
15console.log('Child group nested under parent')

Parent and child vectors stay synchronized: the parent lists the child in groups, and the child lists the parent in parentGroups.

Fetching groups

Use the mpl-core SDK to read on-chain state:

1import { publicKey } from '@metaplex-foundation/umi'
2import { fetchGroupV1 } from '@metaplex-foundation/mpl-core'
3
4const groupAddress = publicKey('GroupAddress...')
5
6const group = await fetchGroupV1(umi, groupAddress)
7
8console.log(group.name)
9console.log(group.collections)
10console.log(group.groups)
11console.log(group.assets)

To list all groups for an update authority, use getGroupV1GpaBuilder (a GPA query — fine for groups, but prefer DAS for large asset scans):

1import { publicKey } from '@metaplex-foundation/umi'
2import { getGroupV1GpaBuilder, Key } from '@metaplex-foundation/mpl-core'
3
4const updateAuthority = publicKey('UpdateAuthorityAddress...')
5
6const groups = await getGroupV1GpaBuilder(umi)
7 .whereField('updateAuthority', updateAuthority)
8 .whereField('key', Key.GroupV1)
9 .getDeserialized()
10
11for (const group of groups) {
12 console.log(group.publicKey, group.name)
13}

Notes

  • Groups do not traverse collection membership automatically. Adding a collection to a group does not add that collection’s NFTs to group.assets. To work with NFTs in a grouped collection, operate on the collection and its assets separately
  • The Groups plugin blocks burning a group member itself (the collection account or a directly grouped asset) while it still belongs to at least one group. Burning an asset inside a grouped collection does not remove the collection from the group

Glossary

The terms below define the Core Groups concepts used on this page.

TermDefinition
GroupV1A Core account that organizes collections, assets, and child groups into a higher-level taxonomy
Groups pluginAn authority-managed plugin on a member that stores parent group public keys
Direct memberA collection, asset, or child group explicitly listed in a group’s on-chain vectors

Quick reference

The tables below list the mpl-core program ID and SDK helpers for common group operations.

Program ID

The mpl-core program ID is the same on mainnet and devnet.

NetworkAddress
MainnetCoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d
DevnetCoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d

SDK helpers

Use these SDK functions for create, fetch, update, and membership operations.

TaskFunction
CreatecreateGroup
FetchfetchGroupV1
List by authoritygetGroupV1GpaBuilder
UpdateupdateGroup
Add collectionaddCollectionsToGroup
Add assetaddAssetsToGroup
Nest groupaddGroupsToGroup
ClosecloseGroup

FAQ

What is the difference between a Collection and a Group?

A Collection groups Core Assets under shared metadata and collection-level plugins. A Group is a taxonomy container that can reference collections, standalone assets, and other groups. Collections answer “which series does this NFT belong to?” Groups answer “which higher-level set does this collection or asset belong to?”

Can a collection belong to multiple groups?

Yes. When a collection is added to a group, mpl-core writes the parent group address into the collection’s Groups plugin. A collection can list multiple parent groups, up to the on-chain vector limit.

Can groups be nested?

Yes. A group can contain child groups and also list parent groups. Parent/child links are kept in sync on both accounts. A group may belong to up to 8 parent groups.

Do assets inside a grouped collection automatically belong to the group?

No. Group membership is stored on direct members only. Putting a collection in a group adds the collection to group.collections and writes the Groups plugin on the collection. NFTs minted into that collection are not automatically added to group.assets.

Can a standalone asset be a direct member of a group?

Yes. Use addAssetsToGroup to add an asset directly to group.assets without a collection. Collection-managed assets can also be added explicitly when the correct authority signs.

Who can modify group membership?

The group update authority signs add/remove instructions. For collection-managed assets, the collection update authority (or an authorized delegate) can add or remove those assets on the group’s behalf.