Skip to main content

Groups

Groups are hierarchical containers that organize Resources, Notes, and other Groups. Each Group can own entities (parent-child), relate to entities (many-to-many), and form typed relationships with other Groups via the Relations system.

Groups list

Group Properties

PropertyTypeDescription
namestringDisplay name (required, non-empty)
descriptionstringFree-text description
urlURLOptional external URL
metaJSONArbitrary key-value metadata (defaults to {})
ownerIdintegerFK to parent Group
categoryIdintegerFK to Category for typing
createdAtdatetimeCreation timestamp
updatedAtdatetimeLast update timestamp
@-Mentions in descriptions

Group descriptions support @-mentions — type @ to search and link to resources, notes, other groups, and tags. For groups, removing a resource or note mention from the description removes that relation on save (unlike notes, where mentions are additive only). Tag and group mentions are always additive. See Mentions.

Hierarchical Organization

Groups form a tree through ownership:

Company (Group)
+-- Engineering (Group) [owned]
| +-- Backend Team (Group) [owned]
| +-- Frontend Team (Group) [owned]
+-- Marketing (Group) [owned]
+-- Sales (Group) [owned]

Ownership Rules

  • Each Group can have one owner (parent)
  • Root Groups have no owner
  • Deleting a parent Group deletes its child Groups and owned Notes. Owned Resources are preserved with ownerId set to NULL.
Group deletion cascades to child Groups and owned Notes

When you delete a Group, its child Groups and owned Notes are cascade-deleted. Owned Resources survive with their owner set to NULL.

Ancestor Chain

The GET /v1/group/parents endpoint resolves the full parent chain (recursive CTE, max depth 20). The UI uses this for breadcrumb navigation.

Group Tree

The GET /v1/group/tree/children endpoint returns child Groups with counts, supporting lazy-loaded tree views. Parameters: parentId (Group ID, 0 for roots), limit (default 50, max 100).

ConnectionCardinalityDeletion Behavior
Owned Groupsone-to-manyCASCADE (deleted with parent)
Owned Notesone-to-manyCASCADE (deleted with parent)
Owned Resourcesone-to-manySET NULL (Resources preserved)
Related Groupsmany-to-manyIndependent lifecycle
Related Notesmany-to-manyIndependent lifecycle
Related Resourcesmany-to-manyIndependent lifecycle

Categories

Categories define types of Groups with custom presentation. See Tags and Categories for details.

Categories support:

  • Custom HTML templates (header, sidebar, summary, avatar)
  • JSON Schema metadata validation via metaSchema
  • Category-based filtering in queries
Deleting a Category cascades to Groups

Deleting a Category cascade-deletes all Groups assigned to that Category.

Group name search supports exact matching when the query is wrapped in double quotes:

GET /v1/groups?Name="Exact Group Name"

Without quotes, Name performs a LIKE (partial) match.

Cloning

POST /v1/group/clone creates a new Group with identical name, description, meta, URL, owner, and Category. It also copies all association references: related Resources, Notes, Groups, and Tags.

Merging

POST /v1/groups/merge combines multiple Groups into one:

  1. All Tags from losers transfer to the winner
  2. Owned Groups, Notes, and Resources transfer to the winner
  3. Related entities link to the winner
  4. Typed Relations transfer to the winner
  5. Metadata merges (loser values added)
  6. Loser data is backed up in the winner's meta
  7. Loser Groups are deleted

Query Parameters

Filter Groups with these parameters on GET /v1/groups:

ParameterTypeDescription
NamestringLIKE search (exact match with "quotes")
DescriptionstringLIKE search
OwnerIdintegerFilter by parent Group
Tagsinteger[]Filter by Tag IDs (AND logic)
Groupsinteger[]Filter by related Groups or parent
Notesinteger[]Filter by related/owned Notes
Resourcesinteger[]Filter by related/owned Resources
Categoriesinteger[]Filter by multiple Category IDs
CategoryIdintegerFilter by single Category ID
Idsinteger[]Filter by specific Group IDs
URLstringLIKE search on URL
CreatedBeforestringDate upper bound
CreatedAfterstringDate lower bound
RelationTypeIdintegerFilter Groups matching a Relation Type's category
RelationSideinteger0 = from side, non-zero = to side
SearchParentsForNamebooleanAlso search parent Group names
SearchChildrenForNamebooleanAlso search child Group names
SearchParentsForTagsbooleanAlso check parent Group Tags
SearchChildrenForTagsbooleanAlso check child Group Tags
MetaQuerystring[]JSON meta queries (supports parent.key and child.key prefixes)
SortBystring[]Sort columns (prefixed with groups., supports meta->>'key')

MetaQuery Prefixes

Group MetaQuery supports special key prefixes:

  • parent.keyname -- searches the parent Group's meta
  • child.keyname -- searches child Groups' meta
GET /v1/groups?MetaQuery=parent.status:active

Relationships

Ownership

  • A Group can be owned by one parent Group
  • Creates the hierarchical tree structure

Owned Entities

  • A Group can own multiple Groups, Notes, and Resources
  • Each entity type has different deletion behavior (see table above)
  • Many-to-many connections to Groups, Notes, and Resources
  • Independent lifecycles

Typed Relations

  • Directed, typed connections between Groups via the Relations system
  • See Relationships

Tags

  • Many-to-many via group_tags

Bulk Operations

EndpointDescription
POST /v1/groups/addTagsAdd Tags to multiple Groups
POST /v1/groups/removeTagsRemove Tags from multiple Groups
POST /v1/groups/addMetaMerge metadata into multiple Groups
POST /v1/groups/deleteDelete multiple Groups
POST /v1/groups/mergeMerge Groups into one

API Operations

For full API details, see API: Groups.