Group layout
Control the ordered contents of a group folder: child folders, linked members, and visual separators: as shown on the group page in the app.
Base path: /api/v1/groups/{groupId}/layout. Scope: groupLayout: read for GET, read_write for mutations. Separate from groups (create/rename folders). See Authentication, Scopes, and Groups & folders.
groupId is a group/folder UUID you own.
Concepts
- Layout entry: one row: folder (child group), member (shortcut/link), or separator (labelled divider).
- Position: zero-based sort index within the group. Gaps allowed on read; add-separator shifts rows at or after the insert index.
- Full replace: PUT .../layout deletes all active rows for the group and inserts the request body. Not a merge: send the complete desired layout.
- Folder entries: folderId must be a direct child of groupId (same parent in the tree).
- Member entries: memberId links a member into this group view; member must exist, belong to you, and not be in trash.
- Soft delete: DELETE .../separators/{id} moves the layout row to trash (retention purge applies).
Endpoint index
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/groups/{groupId}/layout | read |
| PUT | /api/v1/groups/{groupId}/layout | read_write |
| POST | /api/v1/groups/{groupId}/layout/separators | read_write |
| PATCH | /api/v1/groups/layout/separators/{id} | read_write |
| DELETE | /api/v1/groups/layout/separators/{id} | read_write |
Separator PATCH/DELETE use the layout row id (from GET _id or POST response), not groupId in the path.
Get group layout
GET/api/v1/groups/{groupId}/layout
200: array of active entries, sorted by position. Empty array if group missing, trashed, or layout unset. No query parameters.
curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups/GROUP_UUID/layout"[
{
"_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"position": 0,
"type": "folder",
"folderId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1"
},
{
"_id": "b47ac10b-58cc-4372-a567-0e02b2c3d480",
"position": 1,
"type": "separator",
"separatorLabel": "Fronters",
"separatorColorPreset": "slate",
"separatorIcon": "minus"
},
{
"_id": "c47ac10b-58cc-4372-a567-0e02b2c3d481",
"position": 2,
"type": "member",
"memberId": "d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1"
}
]Replace group layout
PUT/api/v1/groups/{groupId}/layout
204: replaces entire active layout. Each entry:
| Field | Notes |
|---|---|
type | folder | member | separator |
position | number (stored as given) |
folderId | required for folder: child of this group |
memberId | required for member |
separatorLabel | optional for separator |
separatorColorPreset | optional preset key (e.g. slate) |
separatorIcon | optional Lucide key or custom icon id |
No duplicate folderId or memberId in one payload. Trashed members rejected.
curl -sS -X PUT \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entries": [
{ "type": "folder", "position": 0, "folderId": "CHILD_FOLDER_UUID" },
{ "type": "separator", "position": 1, "separatorLabel": "Fronters" },
{ "type": "member", "position": 2, "memberId": "MEMBER_UUID" }
]
}' \
"https://api.floralitys.com/api/v1/groups/GROUP_UUID/layout"// 204 No Content: empty response bodyAdd separator
POST/api/v1/groups/{groupId}/layout/separators
201: JSON string: new layout row UUID. Inserts at position and bumps existing rows at or after that index.
| Field | Required |
|---|---|
position | yes: number |
label | no |
colorPreset | no |
icon | no: allowed Lucide key or your custom icon id |
curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"position": 3,
"label": "Archive",
"colorPreset": "slate",
"icon": "minus"
}' \
"https://api.floralitys.com/api/v1/groups/GROUP_UUID/layout/separators""e47ac10b-58cc-4372-a567-0e02b2c3d482"Update separator
PATCH/api/v1/groups/layout/separators/{id}
204: partial update. Row must be type separator and not in trash.
| Field | Notes |
|---|---|
label | optional string |
colorPreset | optional string |
icon | string or null to clear |
curl -sS -X PATCH \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "label": "Fronters", "icon": null }' \
"https://api.floralitys.com/api/v1/groups/layout/separators/SEPARATOR_ROW_UUID"// 204 No Content: empty response bodyDelete layout row (soft)
DELETE/api/v1/groups/layout/separators/{id}
204: soft-deletes the layout row by id and reindexes remaining active positions. Use row _id from GET layout.
curl -sS -X DELETE \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/groups/layout/separators/SEPARATOR_ROW_UUID"// 204 No Content: empty response bodyErrors
JSON { "code", "message" }:
UNAUTHORIZED(401): missing/invalid API keyFORBIDDEN(403): missing groupLayout scopeBAD_REQUEST(400): validation, duplicate folder/member, wrong parent folder, trashed member, invalid separator icon, row not a separator (PATCH)NOT_FOUND(404): invalid UUID; layout row or group not found / access deniedPRECONDITION_FAILED(503): DATABASE_URL not configured
See Errors.
{
"code": "BAD_REQUEST",
"message": "Duplicate folder in layout"
}