API reference
Every route of the PhotoMemory API. Base URL https://photomemory.thundera.eu.
Conventions
- Auth — "User" routes need a Thundera SSO session: the
thundera_token cookie, or Authorization: Bearer <access token>. "Admin" routes need a token with a system-super-admin, system-admin or system-support role, or the X-Admin-Key header. "Public" needs nothing.
- Format — JSON. IDs are UUIDs. Lists take
page (from 1) and per_page (default 50, max 200).
- Errors —
{"detail": "..."} with 400 invalid input (unsupported format, file over 50 MB), 401 not authenticated or invalid token, 403 not allowed, 404 not found, 409 duplicate photo, 410 share expired, 429 rate limited.
Account
| Method | Path | Auth | Description |
|---|
GET | /api/auth/me | User | Current user: id, email, username, full_name, avatar_url, storage_used, storage_limit (GB), quality_preference, plan, has_plan. |
PATCH | /api/auth/settings | User | Body {quality_preference?, full_name?}; quality is full or optimized. Returns the user. |
POST | /api/auth/select-plan?plan_id= | User | Choose a local storage plan (id from /api/plans/local). 404 if unknown. |
Photos
| Method | Path | Auth | Description |
|---|
POST | /api/photos/upload | User | multipart/form-data field file (max 50 MB). 201 with the photo. 409 if the same file (checksum) already exists. |
GET | /api/photos | User | Query page, per_page, sort (taken_at, created_at, file_size), order (asc, desc). |
GET | /api/photos/timeline | User | Query year, month. Returns [{date, photos[]}]. |
GET | /api/photos/map | User | Query lat, lon, radius_km. Photos with GPS, max 500. |
GET | /api/photos/search | User | Query q, camera_make, camera_model, date_from, date_to, person_id, tags, is_favorite, page, per_page. |
GET | /api/photos/trash | User | Deleted photos (30-day retention). |
DELETE | /api/photos/trash/empty | User | Permanently delete everything in the Trash. |
GET | /api/photos/stats/cameras | User | Camera usage statistics. |
GET | /api/photos/{id} | User | One photo with EXIF, location, tags, ai_tags, thumbnail_url, medium_url. |
GET | /api/photos/{id}/download | User | Decrypted original file. |
PATCH | /api/photos/{id} | User | Body {description?, tags?, is_favorite?, is_archived?}. |
POST | /api/photos/{id}/rotate | User | Rotate; degrees must be 90, 180 or 270. |
DELETE | /api/photos/{id}?permanent=false | User | Move to Trash, or delete for good with permanent=true. |
POST | /api/photos/{id}/restore | User | Restore from Trash. |
Albums
| Method | Path | Auth | Description |
|---|
POST | /api/albums | User | Body {title, description?}. 201. |
GET | /api/albums | User | List albums with photo_count and cover_url. |
GET | /api/albums/{id} | User | Album with its photos (paged). |
PATCH | /api/albums/{id} | User | Body {title, description?}. |
POST | /api/albums/{id}/photos | User | Body: JSON array of photo UUIDs. |
DELETE | /api/albums/{id}/photos | User | Body: JSON array of photo UUIDs to remove. |
DELETE | /api/albums/{id} | User | Delete the album (photos are kept). |
People
| Method | Path | Auth | Description |
|---|
GET | /api/people | User | People found in your photos. |
GET | /api/people/{id} | User | One person with their photos. |
PATCH | /api/people/{id} | User | Rename: body {name}. |
POST | /api/people/{id}/merge/{other_id} | User | Merge other_id into id. |
Sharing
| Method | Path | Auth | Description |
|---|
POST | /api/shares | User | Body {album_id? | photo_id?, shared_with_email?, permission, is_public, expires_hours?, password?, max_views?}. Returns link_token. |
GET | /api/shares/link/{token}?password= | Public | Open a shared item. 404 unknown, 410 expired or max views reached, 401 password required or wrong. |
GET | /api/shares/shared-with-me | User | Items shared with your email. |
DELETE | /api/shares/{id} | User | Revoke a share. |
Families
| Method | Path | Auth | Description |
|---|
POST | /api/families | User | Body {name}. 201. |
GET | /api/families | User | Your families with members. |
POST | /api/families/{id}/invite | User | Body {email, role} (owner, admin, member). |
GET | /api/families/{id}/photos | User | Family photo stream. |
DELETE | /api/families/{id}/members/{user_id} | User | Remove a member. |
Sync
| Method | Path | Auth | Description |
|---|
GET | /api/sync/status | User | Account and library status for a sync client. |
GET | /api/sync/manifest | User | Every photo id, checksum, filename, size and updated_at; plus server_time. |
GET | /api/sync/changes?since= | User | Photos changed since an ISO timestamp (includes is_deleted); per_page up to 1000. |
GET | /api/sync/photo/{id}/original | User | Decrypted original. |
GET | /api/sync/photo/{id}/thumbnail | User | Thumbnail. |
GET | /api/sync/photo/{id}/metadata | User | Full metadata. |
Plans
| Method | Path | Auth | Description |
|---|
GET | /api/plans | Public | Plan catalogue proxied from auth.thundera.eu: {plans:[{id, tier, billing_period, name, tagline, unit_amount_cents, currency, features, limits, is_popular}]}. Cached 60 s. |
GET | /api/plans/local | Public | Local storage plans selectable at first access. |
Admin
| Method | Path | Auth | Description |
|---|
GET | /api/admin/stats | Admin | System totals (users, photos, albums, people, faces, storage). |
GET | /api/admin/users?search= | Admin | Paged user list. |
GET | /api/admin/users/{id} | Admin | User detail. |
PATCH | /api/admin/users/{id} | Admin | Body may contain is_active, quality_preference, full_name, is_verified, plan_id (storage limit follows the plan). |
DELETE | /api/admin/users/{id} | Admin | Delete a user with all data in the database and S3. |
POST | /api/admin/reprocess-metadata | Admin | Fill missing metadata (background). |
POST | /api/admin/reprocess-metadata-overwrite | Admin | Re-extract and overwrite all metadata. |
GET | /api/admin/thumbnail-presets | Admin | Presets low, medium, high. |
POST | /api/admin/reprocess-thumbnails?preset=&user_id=&user_ids= | Admin | Regenerate thumbnails for one, several or all users. |
GET | /api/plans/admin/all | Admin | All local plans. |
POST | /api/plans/admin | Admin | Create a local plan. |
PATCH | /api/plans/admin/{id} | Admin | Update a local plan. |
DELETE | /api/plans/admin/{id} | Admin | Discontinue (soft delete). |
Health and metrics
| Method | Path | Auth | Description |
|---|
GET | /api/health | Public | Liveness. |
GET | /metrics | Public | Prometheus metrics (scraped in-cluster). |
Example
curl -H "Authorization: Bearer $TOKEN" \
"https://photomemory.thundera.eu/api/photos/search?q=lisbon&is_favorite=true"