Duplicates 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
DELETE /duplicates— Delete duplicatesGET /duplicates— Retrieve duplicatesGET /duplicates/decisions— Retrieve recent duplicate decisionsPOST /duplicates/resolve— Resolve duplicate groupsGET /duplicates/review— Retrieve the duplicate reviewDELETE /duplicates/{id}— Dismiss a duplicate group
Delete duplicates
DELETE /api/duplicates
Delete multiple duplicate assets specified by their IDs.
Authentication: API key. Permission: duplicate.delete.
Request body
Required.
Field definitions: BulkIdsDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkIdsDto"
}
}
}Responses
{
"204": {
"description": ""
}
}Retrieve duplicates
GET /api/duplicates
Retrieve a list of duplicate assets available to the authenticated user.
Authentication: API key. Permission: duplicate.read.
Responses
Field definitions: DuplicateResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/DuplicateResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Retrieve recent duplicate decisions
GET /api/duplicates/decisions
Your most recent duplicate decision jobs, which can be undone while nothing has changed since, and the decision jobs still running.
Authentication: API key. Permission: duplicate.read.
Responses
Field definitions: DuplicateDecisionHistoryDto
{
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DuplicateDecisionHistoryDto"
}
}
},
"description": ""
}
}Resolve duplicate groups
POST /api/duplicates/resolve
Resolve duplicate groups by synchronizing metadata across assets and deleting/trashing duplicates.
Authentication: API key. Permission: duplicate.delete.
Request body
Required.
Field definitions: DuplicateResolveDto
{
"application/json": {
"schema": {
"$ref": "#/components/schemas/DuplicateResolveDto"
}
}
}Responses
Field definitions: BulkIdResponseDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/BulkIdResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
}Retrieve the duplicate review
GET /api/duplicates/review
Your duplicate groups, each read as a whole: whether it holds copies of one photo or frames of a burst, the evidence behind the suggested keeper, and whether this session may decide it. A group with photos this session does not see, or with another account’s photo, is listed but cannot be decided.
Authentication: API key. Permission: duplicate.read.
Responses
Field definitions: DuplicateReviewGroupDto
{
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/DuplicateReviewGroupDto"
},
"type": "array"
}
}
},
"description": ""
}
}Dismiss a duplicate group
DELETE /api/duplicates/{id}
Dismiss a duplicate group by its ID, unlinking all assets in the group without deleting them.
Authentication: API key. Permission: duplicate.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": ""
}
}© 2026 Frameleaf Inc. All rights reserved.
Frameleaf and the Frameleaf logo are Trademarks of Frameleaf Inc.