# Users API

Source: https://frameleaf.app/docs/api/reference/users/

Use your own server and its scoped API keys.

## Get all users

GET /api/users

Retrieve a list of all users on the server.

```json
{
  "description": "Retrieve a list of all users on the server.",
  "operationId": "searchUsers",
  "parameters": [],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "items": {
              "$ref": "#/components/schemas/UserResponseDto"
            },
            "type": "array"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Get all users",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.read"
}
```

## List own backup devices

GET /api/users/me/backup-devices



```json
{
  "operationId": "listBackupDevices",
  "parameters": [
    {
      "name": "limit",
      "required": false,
      "in": "query",
      "schema": {
        "minimum": 1,
        "maximum": 200,
        "default": 100,
        "type": "integer"
      }
    },
    {
      "name": "offset",
      "required": false,
      "in": "query",
      "schema": {
        "minimum": 0,
        "maximum": 1000000,
        "default": 0,
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BackupDeviceListDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "List own backup devices",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.read"
}
```

## Register or report an own backup device

POST /api/users/me/backup-devices

Stable deviceKey scoped to the owner. Success time and pending count are device-reported, never checksum verification. Removing a device preserves assets and reconciliation history.

```json
{
  "description": "Stable deviceKey scoped to the owner. Success time and pending count are device-reported, never checksum verification. Removing a device preserves assets and reconciliation history.",
  "operationId": "registerBackupDevice",
  "parameters": [],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/BackupDeviceWriteDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/BackupDeviceDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Register or report an own backup device",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.update"
}
```

## Remove an own backup device without deleting assets

DELETE /api/users/me/backup-devices/{id}



```json
{
  "operationId": "removeBackupDevice",
  "parameters": [
    {
      "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": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Remove an own backup device without deleting assets",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.update"
}
```

## List own device reconciliation history

GET /api/users/me/backup-devices/{id}/reconciliations

Requires elevated unfiltered session; checkedAt identifies actual inventory snapshot. Includes incomplete runs explicitly; admin metadata access never grants foreign hash access.

```json
{
  "description": "Requires elevated unfiltered session; checkedAt identifies actual inventory snapshot. Includes incomplete runs explicitly; admin metadata access never grants foreign hash access.",
  "operationId": "listBackupReconciliations",
  "parameters": [
    {
      "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": "limit",
      "required": false,
      "in": "query",
      "schema": {
        "minimum": 1,
        "maximum": 200,
        "default": 100,
        "type": "integer"
      }
    },
    {
      "name": "offset",
      "required": false,
      "in": "query",
      "schema": {
        "minimum": 0,
        "maximum": 1000000,
        "default": 0,
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationHistoryDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "List own device reconciliation history",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "asset.read"
}
```

## Start own device inventory reconciliation

POST /api/users/me/backup-devices/{id}/reconciliations

Requires a current elevated session and no active hidden-content filter.256 indexed bucket digests of sorted unique raw SHA256 bytes, maximum2000 hashes per bucket. Differing buckets require complete hash lists. Snapshot database inventory excludes offline/last-checked-missing originals; not a fresh filesystem check.

```json
{
  "description": "Requires a current elevated session and no active hidden-content filter.256 indexed bucket digests of sorted unique raw SHA256 bytes, maximum2000 hashes per bucket. Differing buckets require complete hash lists. Snapshot database inventory excludes offline/last-checked-missing originals; not a fresh filesystem check.",
  "operationId": "startBackupReconciliation",
  "parameters": [
    {
      "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"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReconciliationStartDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationResultDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Start own device inventory reconciliation",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "asset.read"
}
```

## Reconcile one complete differing bucket

POST /api/users/me/backup-devices/{id}/reconciliations/{runId}/buckets

Up to2000 distinct SHA256 hashes matching original count/digest and first-byte bucket. Server extras never count as device missing. Changed server inventory refuses continuation; start a new run. Repeated validated bucket requests do not double-count; a concurrent snapshot conflict returns409 and may be retried. No completed audit until every differing bucket is validated.

```json
{
  "description": "Up to2000 distinct SHA256 hashes matching original count/digest and first-byte bucket. Server extras never count as device missing. Changed server inventory refuses continuation; start a new run. Repeated validated bucket requests do not double-count; a concurrent snapshot conflict returns409 and may be retried. No completed audit until every differing bucket is validated.",
  "operationId": "reconcileBackupBucket",
  "parameters": [
    {
      "name": "id",
      "required": true,
      "in": "path",
      "schema": {
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      }
    },
    {
      "name": "runId",
      "required": true,
      "in": "path",
      "schema": {
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ReconciliationBucketDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ReconciliationResultDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Reconcile one complete differing bucket",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "asset.read"
}
```

## Retrieve calendar heatmap activity

GET /api/users/me/calendar-heatmap

Retrieve activity counts for a specified period, in a calendar heatmap format.

```json
{
  "description": "Retrieve activity counts for a specified period, in a calendar heatmap format.",
  "operationId": "getMyCalendarHeatmap",
  "parameters": [
    {
      "name": "from",
      "required": false,
      "in": "query",
      "description": "Start date in UTC",
      "schema": {
        "format": "date",
        "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])))$",
        "example": "2024-01-01",
        "type": "string"
      }
    },
    {
      "name": "to",
      "required": false,
      "in": "query",
      "description": "End date in UTC",
      "schema": {
        "format": "date",
        "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])))$",
        "example": "2024-01-01",
        "type": "string"
      }
    },
    {
      "name": "type",
      "required": false,
      "in": "query",
      "schema": {
        "default": "Upload",
        "$ref": "#/components/schemas/CalendarHeatmapType"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CalendarHeatmapResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Retrieve calendar heatmap activity",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.read"
}
```

## Delete user onboarding

DELETE /api/users/me/onboarding

Delete the onboarding status of the current user.

```json
{
  "description": "Delete the onboarding status of the current user.",
  "operationId": "deleteUserOnboarding",
  "parameters": [],
  "responses": {
    "204": {
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Delete user onboarding",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userOnboarding.delete"
}
```

## Retrieve user onboarding

GET /api/users/me/onboarding

Retrieve the onboarding status of the current user.

```json
{
  "description": "Retrieve the onboarding status of the current user.",
  "operationId": "getUserOnboarding",
  "parameters": [],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/OnboardingResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Retrieve user onboarding",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userOnboarding.read"
}
```

## Update user onboarding

PUT /api/users/me/onboarding

Update the onboarding status of the current user.

```json
{
  "description": "Update the onboarding status of the current user.",
  "operationId": "setUserOnboarding",
  "parameters": [],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OnboardingDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/OnboardingResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Update user onboarding",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userOnboarding.update"
}
```

## Get my pinned collections

GET /api/users/me/pins

Complete ordered snapshot of current access-filtered titles, counts and covers. Unavailable pins disclose only their opaque pin ID and kind. Requires a user session.

```json
{
  "description": "Complete ordered snapshot of current access-filtered titles, counts and covers. Unavailable pins disclose only their opaque pin ID and kind. Requires a user session.",
  "operationId": "getMyPinnedCollections",
  "parameters": [],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PinnedCollectionsResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Get my pinned collections",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userPreference.read"
}
```

## Replace my pinned collections

PUT /api/users/me/pins

Add, remove or reorder by replacing the complete ordered list against expectedRevision. Stale writes return 409. Retain unavailable pins using their opaque ID, kind and null targetId. Requires a user session.

```json
{
  "description": "Add, remove or reorder by replacing the complete ordered list against expectedRevision. Stale writes return 409. Retain unavailable pins using their opaque ID, kind and null targetId. Requires a user session.",
  "operationId": "setMyPinnedCollections",
  "parameters": [],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PinnedCollectionsUpdateDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/PinnedCollectionsResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Replace my pinned collections",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userPreference.update"
}
```

## Get my preferences

GET /api/users/me/preferences

Retrieve the preferences for the current user.

```json
{
  "description": "Retrieve the preferences for the current user.",
  "operationId": "getMyPreferences",
  "parameters": [],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserPreferencesResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Get my preferences",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userPreference.read"
}
```

## Update my preferences

PUT /api/users/me/preferences

Update the preferences of the current user.

```json
{
  "deprecated": true,
  "description": "Update the preferences of the current user.",
  "operationId": "updateMyPreferences",
  "parameters": [],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/UserPreferencesUpdateDto"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserPreferencesResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Update my preferences",
  "tags": [
    "Users",
    "Deprecated"
  ],
  "x-frameleaf-permission": "userPreference.update"
}
```

## Get my preference history

GET /api/users/me/preferences/history

The newest changes to the current user’s own preferences, with the device that saved each. Locked-content rules appear only as changed.

```json
{
  "description": "The newest changes to the current user’s own preferences, with the device that saved each. Locked-content rules appear only as changed.",
  "operationId": "getMyPreferenceHistory",
  "parameters": [],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserPreferenceHistoryResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Get my preference history",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userPreference.read"
}
```

## Delete user profile image

DELETE /api/users/profile-image

Delete the profile image of the current user.

```json
{
  "description": "Delete the profile image of the current user.",
  "operationId": "deleteProfileImage",
  "parameters": [],
  "responses": {
    "204": {
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Delete user profile image",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userProfileImage.delete"
}
```

## Create user profile image

POST /api/users/profile-image

Upload and set a new profile image for the current user.

```json
{
  "description": "Upload and set a new profile image for the current user.",
  "operationId": "createProfileImage",
  "parameters": [],
  "requestBody": {
    "content": {
      "multipart/form-data": {
        "schema": {
          "$ref": "#/components/schemas/CreateProfileImageDto"
        }
      }
    },
    "description": "A new avatar for the user",
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreateProfileImageResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Create user profile image",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userProfileImage.update"
}
```

## Retrieve a user

GET /api/users/{id}

Retrieve a specific user by their ID.

```json
{
  "description": "Retrieve a specific user by their ID.",
  "operationId": "getUser",
  "parameters": [
    {
      "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": {
    "200": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/UserResponseDto"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Retrieve a user",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "user.read"
}
```

## Retrieve user profile image

GET /api/users/{id}/profile-image

Retrieve the profile image file for a user.

```json
{
  "description": "Retrieve the profile image file for a user.",
  "operationId": "getProfileImage",
  "parameters": [
    {
      "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": {
    "200": {
      "content": {
        "application/octet-stream": {
          "schema": {
            "format": "binary",
            "type": "string"
          }
        }
      },
      "description": ""
    }
  },
  "security": [
    {
      "api_key": []
    }
  ],
  "summary": "Retrieve user profile image",
  "tags": [
    "Users"
  ],
  "x-frameleaf-permission": "userProfileImage.read"
}
```
