Groups & folders
Two surfaces under /api/v1/groups: member collections (flat groups with member counts) and folder nodes (tree hierarchy under /api/v1/groups and /api/v1/groups/tree). Every route here is authorized with the same effective API key scope: the higher of the stored groups and directories values (see Scopes). Read operations require effective read; write operations require effective read_write. Read operations require effective read; Write operations require effective read_write.
Dashboard: Use Settings → API keys → Member groups to attach privacy buckets to each API group (friend visibility uses bucket overlap on that group). Group CRUD over HTTP is documented in the sections below; there is no separate folder-tree UI for groups.
List groups
GET/api/v1/groups
Returns all active groups for the account, sorted by name, with member counts.
Response
200
[{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "string",
"description": "string",
"icon": "string",
"colorPreset": "string",
"memberCount": 3,
"createdAt": 1714233600000,
"updatedAt": 1714237200000
}]curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups"Status codes
- 200: JSON array of group objects
- 401 / 403: : JSON error
Group object fields
| Field | Type | Notes |
|---|---|---|
_id | string | Group id (UUID) |
name | string | Display name |
description | string? | Optional |
icon / colorPreset | string? | Optional presentation |
memberCount | number | Active members in this group |
createdAt / updatedAt | number | Unix ms |
Create group
POST/api/v1/groups
JSON body: name (string, required); optional description, icon, colorPreset.
Response
201
Created group object (same fields as list rows).
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "string",
"description": "string",
"icon": "string",
"colorPreset": "string",
"memberCount": 3,
"createdAt": 1714233600000,
"updatedAt": 1714237200000
}curl -sS \
-X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Team A","description":"optional"}' \
"https://api.floralitys.com/api/v1/groups"400
{
"code": "BAD_REQUEST",
"message": "Invalid request body."
}Status codes
- 201: Created group object
- 400: Validation error
Get group
GET/api/v1/groups/{groupId}
Response
200
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "string",
"description": "string",
"icon": "string",
"colorPreset": "string",
"memberCount": 3,
"createdAt": 1714233600000,
"updatedAt": 1714237200000
}404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Status codes
- 200: Group object
- 404: Group not found
Update group
PATCH/api/v1/groups/{groupId}
JSON body (at least one field): optional name; optional description, icon, colorPreset (string or null to clear).
Response
200
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "string",
"description": "string",
"icon": "string",
"colorPreset": "string",
"memberCount": 3,
"createdAt": 1714233600000,
"updatedAt": 1714237200000
}curl -sS \
-X PATCH \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Team A renamed"}' \
"https://api.floralitys.com/api/v1/groups/GROUP_ID"404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Status codes
- 200: Updated group
- 404: Group not found
Delete group
DELETE/api/v1/groups/{groupId}
Soft-deletes the group and its group-member links for the account.
Response
204
// 204 No Content: empty response bodycurl -sS \
-X DELETE \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups/GROUP_ID"404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Status codes
- 204: Success, no body
- 404: Group not found
List folder nodes (flat)
GET/api/v1/groups
All active (non-trashed) folder nodes for the account as a flat JSON array (no sideSystemId / subSystemId query).
Response
200
[{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"name": "string",
"parentId": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"icon": "home",
"iconColorPreset": "blue",
"createdAt": 1714233600000,
"updatedAt": 1714237200000,
"version": 2,
"deletedAt": null,
"purgeAt": null,
"originalParentId": null
}]curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups"Folder node object fields
| Field | Type | Notes |
|---|---|---|
_id | string | Folder node id (UUID) |
userId | string | Internal account id |
name | string | Folder name (root may be stored as internal name; tree endpoint shows "Root") |
parentId | string? | Parent folder id; omitted for canonical root |
icon / iconColorPreset | string? | Optional |
version | number | Optimistic concurrency (renames) |
createdAt / updatedAt | number? | Unix ms |
Group tree
GET/api/v1/groups/tree
Nested tree from the canonical root: nodes are DirectoryTreeNode (id, name, optional icon / iconColorPreset, children, memberCount).
Response
200
{
"id": "root-uuid",
"name": "Root",
"memberCount": 2,
"children": [
{
"id": "child-uuid",
"name": "Folder",
"icon": "folder",
"iconColorPreset": "violet",
"memberCount": 0,
"children": []
}
]
}404
When the canonical root row is missing.
{
"code": "NOT_FOUND",
"message": "Root group not found."
}curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups/tree"Get folder node
GET/api/v1/groups/{groupId}
Response
200
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"name": "string",
"parentId": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"icon": "home",
"iconColorPreset": "blue",
"createdAt": 1714233600000,
"updatedAt": 1714237200000,
"version": 2,
"deletedAt": null,
"purgeAt": null,
"originalParentId": null
}404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Status codes
- 200: Folder node object
- 404: Not found or not accessible
Group path (breadcrumb)
GET/api/v1/groups/{groupId}/path
JSON array of { id, name } from root to the folder (root segment uses name Root).
Response
200
[
{ "id": "root-uuid", "name": "Root" },
{ "id": "folder-uuid", "name": "Work" }
]404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Create folder node
POST/api/v1/groups
JSON body: name (string, required); optional parentId (UUID of parent folder; omit to create under the account root); optional clientMutationId (UUID).
Response 201: { group, receipt }. group is the same shape as GET. receipt includes entityId, entityVersion, operation, serverTimestamp, replayKey, and optional clientMutationId.
Response
201
{
"group": {
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"name": "string",
"parentId": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"icon": "home",
"iconColorPreset": "blue",
"createdAt": 1714233600000,
"updatedAt": 1714237200000,
"version": 2,
"deletedAt": null,
"purgeAt": null,
"originalParentId": null
},
"receipt": {
"entityId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"entityVersion": 0,
"operation": "create",
"clientMutationId": "optional-uuid-from-request",
"serverTimestamp": 1714233600000,
"replayKey": "directory:f47ac10b-58cc-4372-a567-0e02b2c3d479:0:create"
}
}400
{
"code": "BAD_REQUEST",
"message": "Invalid request body."
}500
Rare: directory created but reload failed.
{
"code": "INTERNAL_ERROR",
"message": "Group was created but could not be loaded."
}const res = await fetch("https://api.floralitys.com/api/v1/groups", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "New folder" }),
});
if (!res.ok) throw new Error(await res.text());
const { group, receipt } = await res.json();Update folder node (rename / move)
PATCH/api/v1/groups/{groupId}
JSON body: at least one of name (rename) or parentId (UUID or null to move under root). Optional expectedVersion (non-negative int) applies to the rename step when name is sent; if the version does not match, the server returns 409.
Response
200
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"name": "string",
"parentId": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"icon": "home",
"iconColorPreset": "blue",
"createdAt": 1714233600000,
"updatedAt": 1714237200000,
"version": 2,
"deletedAt": null,
"purgeAt": null,
"originalParentId": null
}400 / 404
{
"code": "BAD_REQUEST",
"message": "Invalid request body."
}{
"code": "NOT_FOUND",
"message": "Group not found."
}409
{
"code": "CONFLICT",
"message": "Version conflict on rename."
}Status codes
- 200: Updated folder node object
- 400: Business rule (e.g. duplicate name, cannot move root)
- 404: Folder node or parent not found
- 409: Version conflict on rename
Delete folder node
DELETE/api/v1/groups/{groupId}
Soft-deletes the folder (and descendants); members in those folders are moved to the account root. Cannot delete the root group.
Response
204
// 204 No Content: empty response body400 / 404
{
"code": "BAD_REQUEST",
"message": "Invalid request body."
}Status codes
- 204: Success, no body
- 400: e.g. cannot delete root, already in trash
- 404: Not found
Update folder icon
PATCH/api/v1/groups/{groupId}/icon
JSON body: at least one of icon or iconColorPreset (string or null). Plan limits may return 403 for premium icons or colours.
Response
200
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"name": "string",
"parentId": "b1c2d3e4-f5a6-7890-abcd-ef1234567890",
"icon": "home",
"iconColorPreset": "blue",
"createdAt": 1714233600000,
"updatedAt": 1714237200000,
"version": 2,
"deletedAt": null,
"purgeAt": null,
"originalParentId": null
}403
{
"code": "FORBIDDEN",
"message": "Missing API key scope: groups & folders (effective of groups and directories) requires read_write"
}404
{
"code": "NOT_FOUND",
"message": "Group not found."
}Status codes
- 200: Updated folder node object
- 403: Pro-only icon or colour
- 404: Folder node not found
