docs: auto-generate API route documentation

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id0d1f9769b7ccdbf83d5fa78adef62e46a6a6964
This commit is contained in:
raf 2026-03-21 02:18:48 +03:00
commit 934691c0f9
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
40 changed files with 17444 additions and 1 deletions

117
docs/api/analytics.md Normal file
View file

@ -0,0 +1,117 @@
# Analytics
Usage analytics and viewing history
## Endpoints
### POST /api/v1/analytics/events
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Event recorded |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/analytics/most-viewed
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `limit` | query | No | Maximum number of results |
| `offset` | query | No | Pagination offset |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Most viewed media |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/analytics/recently-viewed
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `limit` | query | No | Maximum number of results |
| `offset` | query | No | Pagination offset |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Recently viewed media |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/progress
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Watch progress |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### PUT /api/v1/media/{id}/progress
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Progress updated |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---

27
docs/api/audit.md Normal file
View file

@ -0,0 +1,27 @@
# Audit
Audit log entries
## Endpoints
### GET /api/v1/audit
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Page size |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Audit log entries |
| 401 | Unauthorized |
| 500 | Internal server error |
---

103
docs/api/auth.md Normal file
View file

@ -0,0 +1,103 @@
# Auth
Authentication and session management
## Endpoints
### POST /api/v1/auth/login
**Authentication:** Not required
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Login successful |
| 400 | Bad request |
| 401 | Invalid credentials |
| 500 | Internal server error |
---
### POST /api/v1/auth/logout
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Logged out |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/auth/me
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Current user info |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/auth/refresh
Refresh the current session, extending its expiry by the configured
duration.
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Session refreshed |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/auth/revoke-all
Revoke all sessions for the current user
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | All sessions revoked |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/auth/sessions
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Active sessions |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

27
docs/api/backup.md Normal file
View file

@ -0,0 +1,27 @@
# Backup
Database backup
## Endpoints
### POST /api/v1/admin/backup
Create a database backup and return it as a downloadable file.
POST /api/v1/admin/backup
For `SQLite`: creates a backup via VACUUM INTO and returns the file.
For `PostgreSQL`: returns unsupported error (use `pg_dump` instead).
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Backup file download |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

208
docs/api/books.md Normal file
View file

@ -0,0 +1,208 @@
# Books
Book metadata, series, authors, and reading progress
## Endpoints
### GET /api/v1/books
List all books with optional search filters
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `isbn` | query | No | Filter by ISBN |
| `author` | query | No | Filter by author |
| `series` | query | No | Filter by series |
| `publisher` | query | No | Filter by publisher |
| `language` | query | No | Filter by language |
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of books |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/books/authors
List all authors with book counts
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Authors with book counts |
| 401 | Unauthorized |
---
### GET /api/v1/books/authors/{name}/books
Get books by a specific author
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `name` | path | Yes | Author name |
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Books by author |
| 401 | Unauthorized |
---
### GET /api/v1/books/reading-list
Get user's reading list
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `status` | query | No | Filter by reading status |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Reading list |
| 401 | Unauthorized |
---
### GET /api/v1/books/series
List all series with book counts
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of series with counts |
| 401 | Unauthorized |
---
### GET /api/v1/books/series/{name}
Get books in a specific series
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `name` | path | Yes | Series name |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Books in series |
| 401 | Unauthorized |
---
### GET /api/v1/books/{id}/metadata
Get book metadata by media ID
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Book metadata |
| 401 | Unauthorized |
| 404 | Not found |
---
### GET /api/v1/books/{id}/progress
Get reading progress for a book
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Reading progress |
| 401 | Unauthorized |
| 404 | Not found |
---
### PUT /api/v1/books/{id}/progress
Update reading progress for a book
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 204 | Progress updated |
| 400 | Bad request |
| 401 | Unauthorized |
---

157
docs/api/collections.md Normal file
View file

@ -0,0 +1,157 @@
# Collections
Media collections
## Endpoints
### GET /api/v1/collections
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of collections |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/collections
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Collection created |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/collections/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Collection ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Collection |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/collections/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Collection ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Collection deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/collections/{id}/members
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Collection ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Collection members |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/collections/{id}/members
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Collection ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Member added |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/collections/{id}/members/{media_id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Collection ID |
| `media_id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Member removed |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---

120
docs/api/config.md Normal file
View file

@ -0,0 +1,120 @@
# Config
Server configuration
## Endpoints
### GET /api/v1/config
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Current server configuration |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/config/roots
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Updated configuration |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### DELETE /api/v1/config/roots
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Updated configuration |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### PATCH /api/v1/config/scanning
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Updated configuration |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/config/ui
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | UI configuration |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### PATCH /api/v1/config/ui
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Updated UI configuration |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

51
docs/api/database.md Normal file
View file

@ -0,0 +1,51 @@
# Database
Database administration
## Endpoints
### POST /api/v1/admin/database/clear
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Database cleared |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/admin/database/stats
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Database statistics |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/admin/database/vacuum
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Database vacuumed |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

20
docs/api/duplicates.md Normal file
View file

@ -0,0 +1,20 @@
# Duplicates
Duplicate media detection
## Endpoints
### GET /api/v1/media/duplicates
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Duplicate groups |
| 401 | Unauthorized |
| 500 | Internal server error |
---

71
docs/api/enrichment.md Normal file
View file

@ -0,0 +1,71 @@
# Enrichment
External metadata enrichment
## Endpoints
### POST /api/v1/media/enrich/batch
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Enrichment job submitted |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/enrich
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Enrichment job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/metadata/external
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | External metadata |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---

42
docs/api/export.md Normal file
View file

@ -0,0 +1,42 @@
# Export
Media library export
## Endpoints
### POST /api/v1/export
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Export job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/export/options
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Export job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

63
docs/api/health.md Normal file
View file

@ -0,0 +1,63 @@
# Health
Server health checks
## Endpoints
### GET /api/v1/health
Comprehensive health check - includes database, filesystem, and cache status
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Health status |
---
### GET /api/v1/health/detailed
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Detailed health status |
---
### GET /api/v1/health/live
Liveness probe - just checks if the server is running
Returns 200 OK if the server process is alive
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Server is alive |
---
### GET /api/v1/health/ready
Readiness probe - checks if the server can serve requests
Returns 200 OK if database is accessible
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Server is ready |
| 503 | Server not ready |
---

99
docs/api/integrity.md Normal file
View file

@ -0,0 +1,99 @@
# Integrity
Library integrity checks and repairs
## Endpoints
### POST /api/v1/admin/integrity/orphans/detect
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Orphan detection job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/admin/integrity/orphans/resolve
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Orphans resolved |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/admin/integrity/thumbnails/cleanup
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Thumbnail cleanup job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/admin/integrity/thumbnails/generate
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Thumbnail generation job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/admin/integrity/verify
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Integrity verification job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---

62
docs/api/jobs.md Normal file
View file

@ -0,0 +1,62 @@
# Jobs
Background job management
## Endpoints
### GET /api/v1/jobs
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of jobs |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### GET /api/v1/jobs/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Job ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Job details |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/jobs/{id}/cancel
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Job ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Job cancelled |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---

640
docs/api/media.md Normal file
View file

@ -0,0 +1,640 @@
# Media
Media item management
## Endpoints
### GET /api/v1/media
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Page size |
| `sort` | query | No | Sort field |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of media items |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### DELETE /api/v1/media
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | All media deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/batch/collection
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch collection result |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/batch/delete
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch delete result |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/batch/move
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch move result |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/batch/tag
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch tag result |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/batch/update
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch update result |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/media/count
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media count |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/media/import
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media imported |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/import/batch
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Batch import results |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/import/directory
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Directory import results |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/import/options
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media imported |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### POST /api/v1/media/import/preview
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Directory preview |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/media/trash
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Page size |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Trashed media items |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### DELETE /api/v1/media/trash
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Trash emptied |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/media/trash/info
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Trash info |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media item |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### PATCH /api/v1/media/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Updated media item |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/media/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### PUT /api/v1/media/{id}/custom-fields
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Custom field set |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/media/{id}/custom-fields/{name}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
| `name` | path | Yes | Custom field name |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Custom field deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/move
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Moved media item |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/open
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media opened |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/media/{id}/permanent
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
| `permanent` | query | No | Set to 'true' for permanent deletion |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/rename
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Renamed media item |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/restore
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media restored |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/stream
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media stream |
| 206 | Partial content |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/thumbnail
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Thumbnail image |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/media/{id}/trash
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media moved to trash |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---

142
docs/api/notes.md Normal file
View file

@ -0,0 +1,142 @@
# Notes
Markdown notes link graph
## Endpoints
### GET /api/v1/media/{id}/backlinks
Get backlinks (incoming links) to a media item.
GET /api/v1/media/{id}/backlinks
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Backlinks |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/outgoing-links
Get outgoing links from a media item.
GET /api/v1/media/{id}/outgoing-links
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Outgoing links |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/reindex-links
Re-extract links from a media item.
POST /api/v1/media/{id}/reindex-links
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Links reindexed |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/notes/graph
Get graph data for visualization.
GET /api/v1/notes/graph?center={uuid}&depth={n}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `center` | query | No | Center node ID |
| `depth` | query | No | Traversal depth (max 5, default 2) |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Graph data |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/notes/resolve-links
Resolve all unresolved links in the database.
POST /api/v1/notes/resolve-links
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Links resolved |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/notes/unresolved-count
Get count of unresolved links.
GET /api/v1/notes/unresolved-count
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Unresolved link count |
| 401 | Unauthorized |
| 500 | Internal server error |
---

12810
docs/api/openapi.json Normal file

File diff suppressed because it is too large Load diff

57
docs/api/photos.md Normal file
View file

@ -0,0 +1,57 @@
# Photos
Photo timeline and map view
## Endpoints
### GET /api/v1/photos/map
Get photos in a bounding box for map view
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `lat1` | query | Yes | Bounding box latitude 1 |
| `lon1` | query | Yes | Bounding box longitude 1 |
| `lat2` | query | Yes | Bounding box latitude 2 |
| `lon2` | query | Yes | Bounding box longitude 2 |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Map markers |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/photos/timeline
Get timeline of photos grouped by date
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `group_by` | query | No | Grouping: day, month, year |
| `year` | query | No | Filter by year |
| `month` | query | No | Filter by month |
| `limit` | query | No | Max items (default 10000) |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Photo timeline groups |
| 401 | Unauthorized |
| 500 | Internal server error |
---

229
docs/api/playlists.md Normal file
View file

@ -0,0 +1,229 @@
# Playlists
Media playlists
## Endpoints
### GET /api/v1/playlists
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of playlists |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/playlists
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Playlist created |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/playlists/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Playlist details |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PATCH /api/v1/playlists/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Playlist updated |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### DELETE /api/v1/playlists/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Playlist deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### GET /api/v1/playlists/{id}/items
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Playlist items |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/playlists/{id}/items
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Item added |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PATCH /api/v1/playlists/{id}/items/reorder
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Item reordered |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### DELETE /api/v1/playlists/{id}/items/{media_id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
| `media_id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Item removed |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/playlists/{id}/shuffle
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Playlist ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Shuffled playlist items |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---

209
docs/api/plugins.md Normal file
View file

@ -0,0 +1,209 @@
# Plugins
Plugin management
## Endpoints
### GET /api/v1/plugins
List all installed plugins
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of plugins |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/plugins
Install a plugin from URL or file path
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin installed |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### POST /api/v1/plugins/events
Receive a plugin event emitted from the UI and dispatch it to interested
server-side event-handler plugins via the pipeline.
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Event received |
| 401 | Unauthorized |
---
### GET /api/v1/plugins/ui/pages
List all UI pages provided by loaded plugins
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin UI pages |
| 401 | Unauthorized |
---
### GET /api/v1/plugins/ui/theme
List merged CSS custom property overrides from all enabled plugins
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin UI theme extensions |
| 401 | Unauthorized |
---
### GET /api/v1/plugins/ui/widgets
List all UI widgets provided by loaded plugins
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin UI widgets |
| 401 | Unauthorized |
---
### GET /api/v1/plugins/{id}
Get a specific plugin by ID
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Plugin ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin details |
| 401 | Unauthorized |
| 404 | Not found |
---
### DELETE /api/v1/plugins/{id}
Uninstall a plugin
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Plugin ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin uninstalled |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/plugins/{id}/reload
Reload a plugin (for development)
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Plugin ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin reloaded |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PATCH /api/v1/plugins/{id}/toggle
Enable or disable a plugin
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Plugin ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Plugin toggled |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---

View file

@ -0,0 +1,62 @@
# Saved_searches
Saved search queries
## Endpoints
### GET /api/v1/searches
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of saved searches |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/searches
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Search saved |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### DELETE /api/v1/searches/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Saved search ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Saved search deleted |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---

42
docs/api/scan.md Normal file
View file

@ -0,0 +1,42 @@
# Scan
Directory scanning
## Endpoints
### POST /api/v1/scan
Trigger a scan as a background job. Returns the job ID immediately.
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Scan job submitted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/scan/status
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Scan status |
| 401 | Unauthorized |
---

View file

@ -0,0 +1,62 @@
# Scheduled_tasks
Scheduled background tasks
## Endpoints
### GET /api/v1/scheduled-tasks
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of scheduled tasks |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### POST /api/v1/scheduled-tasks/{id}/run
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Task ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Task triggered |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/scheduled-tasks/{id}/toggle
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Task ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Task toggled |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---

51
docs/api/search.md Normal file
View file

@ -0,0 +1,51 @@
# Search
Full-text media search
## Endpoints
### GET /api/v1/search
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `q` | query | Yes | Search query |
| `sort` | query | No | Sort order |
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Search results |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/search
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Search results |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---

282
docs/api/shares.md Normal file
View file

@ -0,0 +1,282 @@
# Shares
Media sharing and notifications
## Endpoints
### GET /api/v1/notifications/shares
Get unread share notifications
GET /api/notifications/shares
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Unread notifications |
| 401 | Unauthorized |
---
### POST /api/v1/notifications/shares/read-all
Mark all notifications as read
POST /api/notifications/shares/read-all
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | All notifications marked as read |
| 401 | Unauthorized |
---
### POST /api/v1/notifications/shares/{id}/read
Mark a notification as read
POST /api/notifications/shares/{id}/read
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Notification ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Notification marked as read |
| 401 | Unauthorized |
---
### GET /api/v1/shared/{token}
Access a public shared resource
GET /api/shared/{token}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `token` | path | Yes | Share token |
| `password` | query | No | Share password if required |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Shared content |
| 401 | Unauthorized |
| 404 | Not found |
---
### POST /api/v1/shares
Create a new share
POST /api/shares
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Share created |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/shares/batch/delete
Batch delete shares
POST /api/shares/batch/delete
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Shares deleted |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### GET /api/v1/shares/incoming
List incoming shares (shares shared with me)
GET /api/shares/incoming
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Incoming shares |
| 401 | Unauthorized |
---
### GET /api/v1/shares/outgoing
List outgoing shares (shares I created)
GET /api/shares/outgoing
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Outgoing shares |
| 401 | Unauthorized |
---
### GET /api/v1/shares/{id}
Get share details
GET /api/shares/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Share ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Share details |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PATCH /api/v1/shares/{id}
Update a share
PATCH /api/shares/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Share ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Share updated |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### DELETE /api/v1/shares/{id}
Delete (revoke) a share
DELETE /api/shares/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Share ID |
#### Responses
| Status | Description |
|--------|-------------|
| 204 | Share deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### GET /api/v1/shares/{id}/activity
Get share activity log
GET /api/shares/{id}/activity
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Share ID |
| `offset` | query | No | Pagination offset |
| `limit` | query | No | Pagination limit |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Share activity |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---

196
docs/api/social.md Normal file
View file

@ -0,0 +1,196 @@
# Social
Ratings, comments, favorites, and share links
## Endpoints
### GET /api/v1/favorites
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User favorites |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/favorites
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Added to favorites |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### DELETE /api/v1/favorites/{media_id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `media_id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Removed from favorites |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/media/share
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Share link created |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/comments
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media comments |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/comments
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Comment added |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/media/{id}/rate
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Rating saved |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/ratings
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media ratings |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/shared/media/{token}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `token` | path | Yes | Share token |
| `password` | query | No | Share password |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Shared media |
| 401 | Unauthorized |
| 404 | Not found |
---

20
docs/api/statistics.md Normal file
View file

@ -0,0 +1,20 @@
# Statistics
Library statistics
## Endpoints
### GET /api/v1/statistics
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Library statistics |
| 401 | Unauthorized |
| 500 | Internal server error |
---

115
docs/api/streaming.md Normal file
View file

@ -0,0 +1,115 @@
# Streaming
HLS and DASH adaptive streaming
## Endpoints
### GET /api/v1/media/{id}/stream/dash/manifest.mpd
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | DASH manifest |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
---
### GET /api/v1/media/{id}/stream/dash/{profile}/{segment}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
| `profile` | path | Yes | Transcode profile name |
| `segment` | path | Yes | Segment filename |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | DASH segment data |
| 202 | Segment not yet available |
| 400 | Bad request |
| 401 | Unauthorized |
---
### GET /api/v1/media/{id}/stream/hls/master.m3u8
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | HLS master playlist |
| 401 | Unauthorized |
| 404 | Not found |
---
### GET /api/v1/media/{id}/stream/hls/{profile}/playlist.m3u8
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
| `profile` | path | Yes | Transcode profile name |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | HLS variant playlist |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
---
### GET /api/v1/media/{id}/stream/hls/{profile}/{segment}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
| `profile` | path | Yes | Transcode profile name |
| `segment` | path | Yes | Segment filename |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | HLS segment data |
| 202 | Segment not yet available |
| 400 | Bad request |
| 401 | Unauthorized |
---

120
docs/api/subtitles.md Normal file
View file

@ -0,0 +1,120 @@
# Subtitles
Media subtitle management
## Endpoints
### GET /api/v1/media/{id}/subtitles
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Subtitles |
| 401 | Unauthorized |
| 404 | Not found |
---
### POST /api/v1/media/{id}/subtitles
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Subtitle added |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{media_id}/subtitles/{subtitle_id}/content
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `media_id` | path | Yes | Media item ID |
| `subtitle_id` | path | Yes | Subtitle ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Subtitle content |
| 401 | Unauthorized |
| 404 | Not found |
---
### DELETE /api/v1/subtitles/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Subtitle ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Subtitle deleted |
| 401 | Unauthorized |
| 404 | Not found |
---
### PATCH /api/v1/subtitles/{id}/offset
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Subtitle ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Offset updated |
| 401 | Unauthorized |
| 404 | Not found |
---

412
docs/api/sync.md Normal file
View file

@ -0,0 +1,412 @@
# Sync
Multi-device library synchronization
## Endpoints
### POST /api/v1/sync/ack
Acknowledge processed changes
POST /api/sync/ack
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Changes acknowledged |
| 400 | Bad request |
| 401 | Unauthorized |
---
### GET /api/v1/sync/changes
Get changes since cursor
GET /api/sync/changes
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `cursor` | query | No | Sync cursor |
| `limit` | query | No | Max changes (max 1000) |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Changes since cursor |
| 400 | Bad request |
| 401 | Unauthorized |
---
### GET /api/v1/sync/conflicts
List unresolved conflicts
GET /api/sync/conflicts
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Unresolved conflicts |
| 401 | Unauthorized |
---
### POST /api/v1/sync/conflicts/{id}/resolve
Resolve a sync conflict
POST /api/sync/conflicts/{id}/resolve
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Conflict ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Conflict resolved |
| 400 | Bad request |
| 401 | Unauthorized |
---
### GET /api/v1/sync/devices
List user's sync devices
GET /api/sync/devices
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of devices |
| 401 | Unauthorized |
---
### POST /api/v1/sync/devices
Register a new sync device
POST /api/sync/devices
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Device registered |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/sync/devices/{id}
Get device details
GET /api/sync/devices/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Device ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Device details |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PUT /api/v1/sync/devices/{id}
Update a device
PUT /api/sync/devices/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Device ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Device updated |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### DELETE /api/v1/sync/devices/{id}
Delete a device
DELETE /api/sync/devices/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Device ID |
#### Responses
| Status | Description |
|--------|-------------|
| 204 | Device deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### POST /api/v1/sync/devices/{id}/token
Regenerate device token
POST /api/sync/devices/{id}/token
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Device ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Token regenerated |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### GET /api/v1/sync/download/{path}
Download a file for sync (supports Range header)
GET /api/sync/download/{*path}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `path` | path | Yes | File path |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | File content |
| 206 | Partial content |
| 401 | Unauthorized |
| 404 | Not found |
---
### POST /api/v1/sync/report
Report local changes from client
POST /api/sync/report
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Changes processed |
| 400 | Bad request |
| 401 | Unauthorized |
---
### POST /api/v1/sync/upload
Create an upload session for chunked upload
POST /api/sync/upload
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Upload session created |
| 400 | Bad request |
| 401 | Unauthorized |
---
### GET /api/v1/sync/upload/{id}
Get upload session status
GET /api/sync/upload/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Upload session ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Upload session status |
| 401 | Unauthorized |
| 404 | Not found |
---
### DELETE /api/v1/sync/upload/{id}
Cancel an upload session
DELETE /api/sync/upload/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Upload session ID |
#### Responses
| Status | Description |
|--------|-------------|
| 204 | Upload cancelled |
| 401 | Unauthorized |
| 404 | Not found |
---
### PUT /api/v1/sync/upload/{id}/chunks/{index}
Upload a chunk
PUT /api/sync/upload/{id}/chunks/{index}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Upload session ID |
| `index` | path | Yes | Chunk index |
#### Request Body
Chunk binary data
`Content-Type: application/octet-stream`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Chunk received |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
---
### POST /api/v1/sync/upload/{id}/complete
Complete an upload session
POST /api/sync/upload/{id}/complete
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Upload session ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Upload completed |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
---

157
docs/api/tags.md Normal file
View file

@ -0,0 +1,157 @@
# Tags
Media tag management
## Endpoints
### GET /api/v1/media/{media_id}/tags
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `media_id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Media tags |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### POST /api/v1/media/{media_id}/tags
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `media_id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Tag applied |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/media/{media_id}/tags/{tag_id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `media_id` | path | Yes | Media item ID |
| `tag_id` | path | Yes | Tag ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Tag removed |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---
### GET /api/v1/tags
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of tags |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/tags
**Authentication:** Required (Bearer JWT)
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Tag created |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/tags/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Tag ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Tag |
| 401 | Unauthorized |
| 404 | Not found |
| 500 | Internal server error |
---
### DELETE /api/v1/tags/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Tag ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Tag deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
| 500 | Internal server error |
---

86
docs/api/transcode.md Normal file
View file

@ -0,0 +1,86 @@
# Transcode
Video transcoding sessions
## Endpoints
### POST /api/v1/media/{id}/transcode
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Transcode job submitted |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/transcode
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of transcode sessions |
| 401 | Unauthorized |
---
### GET /api/v1/transcode/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Transcode session ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Transcode session details |
| 401 | Unauthorized |
| 404 | Not found |
---
### DELETE /api/v1/transcode/{id}
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Transcode session ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Transcode session cancelled |
| 401 | Unauthorized |
| 404 | Not found |
---

89
docs/api/upload.md Normal file
View file

@ -0,0 +1,89 @@
# Upload
File upload and managed storage
## Endpoints
### GET /api/v1/managed/stats
Get managed storage statistics
GET /api/managed/stats
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Managed storage statistics |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### GET /api/v1/media/{id}/download
Download a managed file
GET /api/media/{id}/download
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | File content |
| 400 | Bad request |
| 401 | Unauthorized |
| 404 | Not found |
---
### POST /api/v1/media/{id}/move-to-managed
Migrate an external file to managed storage
POST /api/media/{id}/move-to-managed
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | Media item ID |
#### Responses
| Status | Description |
|--------|-------------|
| 204 | File migrated |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---
### POST /api/v1/upload
Upload a file to managed storage
POST /api/upload
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | File uploaded |
| 400 | Bad request |
| 401 | Unauthorized |
| 500 | Internal server error |
---

207
docs/api/users.md Normal file
View file

@ -0,0 +1,207 @@
# Users
User and library access management
## Endpoints
### GET /api/v1/admin/users
List all users (admin only)
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of users |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### POST /api/v1/admin/users
Create a new user (admin only)
**Authentication:** Required (Bearer JWT)
#### Request Body
username, password, role, and optional profile fields
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User created |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 500 | Internal server error |
---
### GET /api/v1/admin/users/{id}
Get a specific user by ID
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User details |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### PATCH /api/v1/admin/users/{id}
Update a user
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Request Body
Optional password, role, or profile fields to update
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User updated |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### DELETE /api/v1/admin/users/{id}
Delete a user (admin only)
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User deleted |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not found |
---
### GET /api/v1/admin/users/{id}/libraries
Get user's accessible libraries
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Responses
| Status | Description |
|--------|-------------|
| 200 | User libraries |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### POST /api/v1/admin/users/{id}/libraries
Grant library access to a user (admin only)
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Access granted |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### DELETE /api/v1/admin/users/{id}/libraries
Revoke library access from a user (admin only)
Uses a JSON body instead of a path parameter because `root_path` may contain
slashes that conflict with URL routing.
**Authentication:** Required (Bearer JWT)
#### Parameters
| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | Yes | User ID |
#### Request Body
`Content-Type: application/json`
See `docs/api/openapi.json` for the full schema.
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Access revoked |
| 400 | Bad request |
| 401 | Unauthorized |
| 403 | Forbidden |
---

34
docs/api/webhooks.md Normal file
View file

@ -0,0 +1,34 @@
# Webhooks
Webhook configuration
## Endpoints
### GET /api/v1/webhooks
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | List of configured webhooks |
| 401 | Unauthorized |
| 403 | Forbidden |
---
### POST /api/v1/webhooks/test
**Authentication:** Required (Bearer JWT)
#### Responses
| Status | Description |
|--------|-------------|
| 200 | Test webhook sent |
| 401 | Unauthorized |
| 403 | Forbidden |
---