Skip to main content

Glossary

Several concepts go by different names in the UI, the models, the URLs and the clients. This page says which name is canonical. Name new code (variables, types, endpoints, UI strings, docs) after the term in the first column. Legacy names stay where they are because clients depend on them, but new code does not copy them.

Backend paths are relative to apps/backend.

Rules for new code​

  • JSON keys are snake_case. api/tests/infra/test_api_naming.py fails on a camelCase serializer field, openapi.json property or dict key; the legacy keys listed there only shrink.
  • A new route takes a photo as Photo.id in a photo_id URL argument; image_hash is for content-hash lookups. The same test fails on a new image_hash URL argument.
  • "Tag" means the user's Tag. What OpenCLIP detects in a photo is a "thing".

Terms​

Term (UI)CodeAPILegacy names
PhotoPhoto (api/models/photo.py), a photo or a video; identified by id (UUID)api/photos/url serializer field (repeats image_hash)
Image hashPhoto.image_hash: content MD5 plus owner id; names the thumbnail filesapi/photos/<image_hash>/file/<file_hash>/, main-file/ (the only routes keyed by it)
FileFile (api/models/file.py), one file on disk, keyed by File.hash; a photo has files and a main_filefile_variants on a photo
File variantAnother File of the same photo: RAW next to JPEG, a live photo's videofile_variants, api/photos/<image_hash>/file/<file_hash>/the raw_jpeg and live_photo stack types
Embedded mediaFile.embedded_media, a clip extracted from a motion photoembedded_media[].id (a File.hash)
File copyFileCopy (api/models/file.py), another path holding the exact bytes of a File; it shares that row, and the scan treats the path as known
ThumbnailThumbnail (api/models/thumbnail.py), sizes in SQUARE_THUMBNAIL_HEIGHTS (api/thumbnails/render.py) and the BIG_THUMBNAIL_HEIGHT setting: big 1080 px by default, grid 500 px and 250 px high, aspect ratio kept (videos: short mp4)big_thumbnail_url, /media/square_thumbnails, square_thumbnails_small (directories, /media/ paths), square_thumbnail_url, small_square_thumbnail_url, api-client squareThumbnailUrl, squareThumbnailSmallUrl: not square, kept so files and shipped apps keep working
StackPhotoStack (api/models/photo_stack.py): burst, exposure bracket or manualapi/stacks/
DuplicateDuplicate (api/models/duplicate.py): exact copies or visual duplicates, reviewed by the userapi/duplicates/
EventAlbumAuto (api/models/album_auto.py), photos grouped by time; web route /album/events/$idapi/albums/auto/, api/autoalbumgen/, api/autoalbumtitlegen/auto album, event album, JOB_GENERATE_AUTO_ALBUMS
Day groupAlbumDate (api/models/album_date.py), the per-day groups the timeline is built from; never shown as an albumapi/albums/date/date album
ThingAn OpenCLIP label for what is in a photo: captions_json["openclip_vitb32"]["tags"], AlbumThing with thing_type=TAG_THING_TYPE (api/search/semantic.py); hashtag_attribute things come from caption hashtagsapi/albums/thing/, api/sync/albums/thing/auto tags, tag album, scene classification (FEATURE_SCENE_CLASSIFICATION), tags service, JOB_GENERATE_TAGS
TagTag (api/models/tag.py), the user's own labelapi/tags/, api/sync/albums/tag/tag album (SyncTagAlbumsView)
KeywordPhotoMetadata.keywords (api/models/photo_metadata.py), from XMP Subject and IPTC Keywords; a scan also adds each one as a Tag (link_tags_from_keywords)keywords in photo metadata
ArchivePhoto.archived (api/models/photo.py): off the timeline (archived in api/albums/timeline_filter.py) and Memories only; not part of visible_photo_q, unlike hidden, which takes a photo out of every viewapi/photosedit/archive/, archived on api/albums/date/ and in a select-all query, web route /archived
Media categoryPhoto.is_screenshot, Photo.is_document, category_source; a separate classifier, not Thingsapi/classifymedia/, api/photosedit/category/
PersonPerson (api/models/person.py), UI "People"; kind user-labelled, cluster or unknownapi/persons/, people on an event (items carry id)
GroupPersonGroup (api/models/person_group.py), the user's own grouping of their people ("Family", "Work"); Person.groups. Not a Tag, which labels photosapi/person-groups/, api/persons/<id>/groups/, group_ids on a person, ?group= on api/persons/ and api/faces/incomplete/
FaceFace (api/models/face.py), one detected face, labelled with a Personapi/faces/, people on a photo (items are faces and carry face_id)
Face clusterCluster (api/models/cluster.py), unlabelled faces grouped by similarityapi/clusterfaces/
PlaceAlbumPlace (api/models/album_place.py), photos grouped by geocoded locationapi/albums/place/
My albumAlbumUser (api/models/album_user.py), an album the user madeapi/albums/user/user album
CollectionAlbumCollection (api/models/album_collection.py), the user's own grouping of their albums ("Travel", "Family"); an album can be in several, and only its owner sees them. Not a Tag, which labels photosapi/albums/collections/, PUT api/albums/user/<id>/collections/, collection_ids on an album, ?collection= on api/albums/user/list/album tags, album folders (#1009, #871)
MemoryComputed in api/views/memories.py, no modelapi/memories/
JobLongRunningJob (api/models/long_running_job.py)api/jobs/
Image tagThe backend image's tag (IMAGE_TAG), not a Tagapi/imagetag/

Client types​

TypeWhereWhat
PhotoPersonpackages/api-client/src/schemas/photos.tsOne face entry in Photo.people (face_id, location). People is its deprecated alias.
PersonListapps/frontend/src/api_client/albums/hooks/useFetchPeopleAlbumsQuery.tsA list of Person (the People album list).

Legacy camelCase keys​

These keys predate the snake_case rule. Renaming one is an API break for the web app, packages/api-client and shipped mobile builds, so it needs a deprecation period that sends both keys. test_api_naming.py holds the list.

aspectRatio, dominantColor, birthTime (photo summaries), focalLength35Equivalent, digitalZoomRatio, subjectDistance (photo detail), numberOfItems (day groups, memories), removedPhotos (album edit), newPersonName (person edit), isFirstTimeSetup (api/firsttimesetup/).