Albums API
Base URL: https://YOUR-SERVER/api. Send your API key in x-api-key where authentication is required. A key also needs the listed permission; your account's access rules still apply.
API guide · All endpoints · OpenAPI JSON
GET /albums— List all albumsPOST /albums— Create an albumPUT /albums/assets— Add assets to albumsGET /albums/icons— Retrieve the album icon cataloguePUT /albums/order— Arrange a group of the album directoryGET /albums/statistics— Retrieve album statisticsGET /albums/tree— Retrieve the album directoryDELETE /albums/{id}— Delete an albumGET /albums/{id}— Retrieve an albumPATCH /albums/{id}— Update an albumDELETE /albums/{id}/assets— Remove assets from an albumPUT /albums/{id}/assets— Add assets to an albumPUT /albums/{id}/collection— Move an album into or out of a collectionGET /albums/{id}/descendant-count— Count descendant albumsGET /albums/{id}/map-markers— Retrieve album map markersDELETE /albums/{id}/user/{userId}— Remove user from albumPUT /albums/{id}/user/{userId}— Update user rolePUT /albums/{id}/users— Share album with usersGET /classification/assets/{id}— Retrieve classification contributions for an assetPOST /classification/preview— Preview a classification ruleGET /classification/rules— List classification rulesPOST /classification/rules— Create a classification ruleDELETE /classification/rules/{id}— Delete a classification ruleGET /classification/rules/{id}— Retrieve a classification rulePATCH /classification/rules/{id}— Update a classification rulePOST /classification/rules/{id}/apply— Apply a classification rulePOST /classification/rules/{id}/decisions— Review classification rule matchesGET /classification/rules/{id}/matches— List classification rule matchesPOST /classification/rules/{id}/plan— Plan a classification rule re-evaluationGET /classification/settings— Retrieve classification rule settings
List all albums
GET /api/albums
Retrieve a list of albums available to the authenticated user.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
assetId | query | No | Filter albums containing this asset ID (ignores other parameters) |
id | query | No | Album ID |
isOwned | query | No | Filter by ownership: true = only owned, false = only shared-with-me, undefined = no filter |
isShared | query | No | Filter by shared status: true = only shared, false = not shared, undefined = no filter |
name | query | No | Album name (exact match) |
suppressedOnly | query | No | Return album metadata for suppressed content only |
Parameter types, defaults and constraints
[
{
"name": "assetId",
"required": false,
"in": "query",
"description": "Filter albums containing this asset ID (ignores other parameters)",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "id",
"required": false,
"in": "query",
"description": "Album ID",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "isOwned",
"required": false,
"in": "query",
"description": "Filter by ownership: true = only owned, false = only shared-with-me, undefined = no filter",
"schema": {
"type": "boolean"
}
},
{
"name": "isShared",
"required": false,
"in": "query",
"description": "Filter by shared status: true = only shared, false = not shared, undefined = no filter",
"schema": {
"type": "boolean"
}
},
{
"name": "name",
"required": false,
"in": "query",
"description": "Album name (exact match)",
"schema": {
"type": "string"
}
},
{
"name": "suppressedOnly",
"required": false,
"in": "query",
"description": "Return album metadata for suppressed content only",
"schema": {
"type": "boolean"
}
}
]Responses
Field definitions: AlbumResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/AlbumResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Create an album
POST /api/albums
Create a new album. The album can also be created with initial users and assets.
Authentication: API key. Permission: album.create.
Request body
Required.
Field definitions: CreateAlbumDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateAlbumDto"
}
}
}Responses
Field definitions: AlbumResponseDto
{
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumResponseDto"
}
}
},
"description": ""
}
}Add assets to albums
PUT /api/albums/assets
Send a list of asset IDs and album IDs to add each asset to each album.
Authentication: API key. Permission: albumAsset.create.
Request body
Required.
Field definitions: AlbumsAddAssetsDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumsAddAssetsDto"
}
}
}Responses
Field definitions: AlbumsAddAssetsResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumsAddAssetsResponseDto"
}
}
},
"description": ""
}
}Retrieve the album icon catalogue
GET /api/albums/icons
Every Material Design Icons name an album or collection may use, plus the categorised suggested set shown first in icon choosers. Served as data so clients never bundle the catalogue.
Authentication: API key. Permission: album.read.
Responses
Field definitions: AlbumIconCatalogueResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumIconCatalogueResponseDto"
}
}
},
"description": ""
}
}Arrange a group of the album directory
PUT /api/albums/order
Save the authenticated user's own custom order for one group of their album directory: the albums inside a collection, or at the top level the collections, the albums on their own, or the shared spaces. The order is personal and changes organization only; access and membership are untouched. The ids must be exactly the group as it is now, otherwise 409.
Authentication: API key. Permission: album.update.
Request body
Required.
Field definitions: AlbumOrderDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumOrderDto"
}
}
}Responses
{
"204": {
"description": ""
}
}Retrieve album statistics
GET /api/albums/statistics
Returns statistics about the albums available to the authenticated user.
Authentication: API key. Permission: album.statistics.
Responses
Field definitions: AlbumStatisticsResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumStatisticsResponseDto"
}
}
},
"description": ""
}
}Retrieve the album directory
GET /api/albums/tree
Collections with their albums, albums that stand on their own, and shared spaces, for everything the authenticated user owns or is shared with. Albums nest one level deep inside collections only; collections and shared spaces are always top level.
Authentication: API key. Permission: album.read.
Responses
Field definitions: AlbumTreeResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumTreeResponseDto"
}
}
},
"description": ""
}
}Delete an album
DELETE /api/albums/{id}
Delete a specific album by its ID. Note the album is initially trashed and then immediately scheduled for deletion, but relies on a background job to complete the process.
Authentication: API key. Permission: album.delete.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
{
"204": {
"description": ""
}
}Retrieve an album
GET /api/albums/{id}
Retrieve information about a specific album by its ID.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
key | query | No | string |
slug | query | No | string |
suppressedOnly | query | No | Return album metadata for suppressed content only |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "key",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "slug",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "suppressedOnly",
"required": false,
"in": "query",
"description": "Return album metadata for suppressed content only",
"schema": {
"type": "boolean"
}
}
]Responses
Field definitions: AlbumResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumResponseDto"
}
}
},
"description": ""
}
}Update an album
PATCH /api/albums/{id}
Update the information of a specific album by its ID. This endpoint can be used to update the album name, description, sort order, etc. However, it is not used to add or remove assets or users from the album.
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: UpdateAlbumDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateAlbumDto"
}
}
}Responses
Field definitions: AlbumResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumResponseDto"
}
}
},
"description": ""
}
}Remove assets from an album
DELETE /api/albums/{id}/assets
Remove multiple assets from a specific album by its ID.
Authentication: API key. Permission: albumAsset.delete.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: BulkIdsDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkIdsDto"
}
}
}Responses
Field definitions: BulkIdResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/BulkIdResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Add assets to an album
PUT /api/albums/{id}/assets
Add multiple assets to a specific album by its ID.
Authentication: API key. Permission: albumAsset.create.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: BulkIdsDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkIdsDto"
}
}
}Responses
Field definitions: BulkIdResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/BulkIdResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Move an album into or out of a collection
PUT /api/albums/{id}/collection
Move an album into a collection, or send null to take it out so it stands on its own. Only the album owner can move it (an editor gets 403); the destination must be a collection the user can edit. Collections and shared spaces cannot be moved.
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: MoveAlbumDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/MoveAlbumDto"
}
}
}Responses
Field definitions: AlbumResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumResponseDto"
}
}
},
"description": ""
}
}Count descendant albums
GET /api/albums/{id}/descendant-count
Return the number of descendant albums (children, grandchildren, etc.) for a specific album. Used by the UI to show "Delete X and N nested albums?" confirmations.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
Field definitions: AlbumDescendantCountResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumDescendantCountResponseDto"
}
}
},
"description": ""
}
}Retrieve album map markers
GET /api/albums/{id}/map-markers
Retrieve map marker information for a specific album by its ID.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
fileCreatedAfter | query | No | Filter assets created after this date |
fileCreatedBefore | query | No | Filter assets created before this date |
id | path | Yes | string |
isArchived | query | No | Include archived items (the album default); false leaves them out |
isFavorite | query | No | Filter by the viewer's own favorites; other members' favorites are never matched |
key | query | No | string |
slug | query | No | string |
withPartners | query | No | Include the album's items owned by anyone else (the album default); false keeps only your own |
withSharedAlbums | query | No | Accepted for the shared map settings; has no effect on an album map |
Parameter types, defaults and constraints
[
{
"name": "fileCreatedAfter",
"required": false,
"in": "query",
"description": "Filter assets created after this date",
"schema": {
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"example": "2024-01-01T00:00:00.000Z",
"type": "string"
}
},
{
"name": "fileCreatedBefore",
"required": false,
"in": "query",
"description": "Filter assets created before this date",
"schema": {
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"example": "2024-01-01T00:00:00.000Z",
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "isArchived",
"required": false,
"in": "query",
"description": "Include archived items (the album default); false leaves them out",
"schema": {
"type": "boolean"
}
},
{
"name": "isFavorite",
"required": false,
"in": "query",
"description": "Filter by the viewer's own favorites; other members' favorites are never matched",
"schema": {
"type": "boolean"
}
},
{
"name": "key",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "slug",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "withPartners",
"required": false,
"in": "query",
"description": "Include the album's items owned by anyone else (the album default); false keeps only your own",
"schema": {
"type": "boolean"
}
},
{
"name": "withSharedAlbums",
"required": false,
"in": "query",
"description": "Accepted for the shared map settings; has no effect on an album map",
"schema": {
"type": "boolean"
}
}
]Responses
Field definitions: MapMarkerResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/MapMarkerResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Remove user from album
DELETE /api/albums/{id}/user/{userId}
Remove a user from an album. Use an ID of "me" to leave a shared album.
Authentication: API key. Permission: albumUser.delete.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | Album ID |
userId | path | Yes | Album user ID, or "me" to reference the current user. |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"description": "Album ID",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "userId",
"required": true,
"in": "path",
"description": "Album user ID, or \"me\" to reference the current user.",
"schema": {
"type": "string"
}
}
]Responses
{
"204": {
"description": ""
}
}Update user role
PUT /api/albums/{id}/user/{userId}
Change the role for a specific user in a specific album.
Authentication: API key. Permission: albumUser.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | Album ID |
userId | path | Yes | Album user ID, or "me" to reference the current user. |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"description": "Album ID",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "userId",
"required": true,
"in": "path",
"description": "Album user ID, or \"me\" to reference the current user.",
"schema": {
"type": "string"
}
}
]Request body
Required.
Field definitions: UpdateAlbumUserDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateAlbumUserDto"
}
}
}Responses
{
"204": {
"description": ""
}
}Share album with users
PUT /api/albums/{id}/users
Share an album with multiple users. Each user can be given a specific role in the album.
Authentication: API key. Permission: albumUser.create.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: AddUsersDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddUsersDto"
}
}
}Responses
Field definitions: AlbumResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlbumResponseDto"
}
}
},
"description": ""
}
}Retrieve classification contributions for an asset
GET /api/classification/assets/{id}
Which of your rules put this item in a smart album, added a tag to it or archived it.
Authentication: API key. Permission: asset.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
Field definitions: ClassificationContributionDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/ClassificationContributionDto"
},
"type": "array"
}
}
},
"description": ""
}
}Preview a classification rule
POST /api/classification/preview
What a draft rule matches, without writing anything. Rules with visual categories are previewed over a bounded sample of your newest items.
Authentication: API key. Permission: album.read.
Request body
Required.
Field definitions: ClassificationPreviewDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationPreviewDto"
}
}
}Responses
Field definitions: ClassificationPreviewResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationPreviewResponseDto"
}
}
},
"description": ""
}
}List classification rules
GET /api/classification/rules
Your smart album rules, optionally only the one behind an album.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
albumId | query | No | Only the rule behind this album |
Parameter types, defaults and constraints
[
{
"name": "albumId",
"required": false,
"in": "query",
"description": "Only the rule behind this album",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
Field definitions: ClassificationRuleResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/ClassificationRuleResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Create a classification rule
POST /api/classification/rules
Create a smart album and the rule that fills it. Nothing is matched until the rule is applied. Archiving matches requires `archiveConsent`.
Authentication: API key. Permission: album.create.
Request body
Required.
Field definitions: ClassificationRuleCreateDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationRuleCreateDto"
}
}
}Responses
Field definitions: ClassificationRuleResponseDto
{
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationRuleResponseDto"
}
}
},
"description": ""
}
}Delete a classification rule
DELETE /api/classification/rules/{id}
Stop the rule. Its album stays as an ordinary album with everything in it.
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
{
"204": {
"description": ""
}
}Retrieve a classification rule
GET /api/classification/rules/{id}
One of your smart album rules and its counts.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
Field definitions: ClassificationRuleResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationRuleResponseDto"
}
}
},
"description": ""
}
}Update a classification rule
PATCH /api/classification/rules/{id}
Change what the rule matches, what it does, or turn it off. A rule that is off keeps what it applied. Turning archiving on requires `archiveConsent`.
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: ClassificationRuleUpdateDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationRuleUpdateDto"
}
}
}Responses
Field definitions: ClassificationRuleResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationRuleResponseDto"
}
}
},
"description": ""
}
}Apply a classification rule
POST /api/classification/rules/{id}/apply
Apply the rule to up to 500 items from its plan. Larger plans run as an `apply-classification-rule` bulk media operation.
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: ClassificationApplyDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationApplyDto"
}
}
}Responses
Field definitions: ClassificationApplyResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationApplyResponseDto"
}
}
},
"description": ""
}
}Review classification rule matches
POST /api/classification/rules/{id}/decisions
Accept matches (they stay whatever later processing finds) or reject them (what the rule applied is taken back and never applied again).
Authentication: API key. Permission: album.update.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Request body
Required.
Field definitions: ClassificationDecisionDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationDecisionDto"
}
}
}Responses
Field definitions: ClassificationDecisionResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationDecisionResponseDto"
}
}
},
"description": ""
}
}List classification rule matches
GET /api/classification/rules/{id}/matches
The rule’s matches with one decision, suggestions to review by default.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
decision | query | No | |
id | path | Yes | string |
page | query | No | integer |
size | query | No | integer |
Parameter types, defaults and constraints
Field definitions: ClassificationMatchDecision
[
{
"name": "decision",
"required": false,
"in": "query",
"schema": {
"default": "suggested",
"$ref": "#/components/schemas/ClassificationMatchDecision"
}
},
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
},
{
"name": "page",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"maximum": 9007199254740991,
"default": 1,
"type": "integer"
}
},
{
"name": "size",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"maximum": 500,
"default": 100,
"type": "integer"
}
}
]Responses
Field definitions: ClassificationMatchPageDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationMatchPageDto"
}
}
},
"description": ""
}
}Plan a classification rule re-evaluation
POST /api/classification/rules/{id}/plan
What applying the rule now would add, suggest and take back, without writing anything. Manual decisions are never part of it.
Authentication: API key. Permission: album.read.
Parameters
| Name | Where | Required | Description |
|---|---|---|---|
id | path | Yes | string |
Parameter types, defaults and constraints
[
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
"type": "string"
}
}
]Responses
Field definitions: ClassificationPlanResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationPlanResponseDto"
}
}
},
"description": ""
}
}Retrieve classification rule settings
GET /api/classification/settings
Whether rules may use visual categories, whether those can be compared now, and the default action.
Authentication: API key. Permission: album.read.
Responses
Field definitions: ClassificationSettingsDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ClassificationSettingsDto"
}
}
},
"description": ""
}
}© 2026 Frameleaf Inc. All rights reserved.
Frameleaf and the Frameleaf logo are Trademarks of Frameleaf Inc.