Files
bookhoard/docs/developer/api/media-items/list_media_items.md
T
john-okeefe f65db5ab4f docs(api): align auth/devices/libraries/media-items docs with handlers
Verified against the Echo routes and handler structs, fixing drift that
would break API clients:

- login: response field is access_token, not token (AuthResponse struct)
- register status: status is only pending|approved; expiry is HTTP 410
  (not a status value), approved responses are single-use, and pending
  registrations do not survive server restarts
- visible libraries: endpoint is GET /api/libraries/visibility and
  returns a top-level array of full library rows, not a wrapped object
- media items list: response is {"data": [...]}, library_id is optional,
  limit defaults to 50 (max 1000), no total field; document the sort
  parameter, the two response shapes, and raw-vs-resolved file paths

refresh and device-registration docs verified accurate; no changes.
2026-08-28 22:15:42 -04:00

4.5 KiB

List Media Items

Retrieve a paginated list of media items, scoped to a library or across all libraries.

Endpoint: GET /api/media-items Auth: Required

Query Parameters

Parameter Type Required Description
library_id string No Library UUID. If omitted, items from all libraries are returned
limit int No Items to return (default 50, max 1000)
offset int No Items to skip (must be >= 0)
sort string No Sort expression, default created_at DESC

Allowed sort expressions

created_at, title, author, series, date_published, copyright_year, page_count, genre — each with ASC or DESC (e.g. title ASC). Any other value silently falls back to created_at DESC.

Request Headers

Header Type Required Description
Authorization string Yes Bearer token

Example Request

GET /api/media-items?library_id=uuid&limit=20&offset=0&sort=title%20ASC
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response (200 OK)

The response body is {"data": [...]} in both modes. The item shape differs by mode.

No total is returned — page until fewer items than limit come back.

With library_id — full database rows

Nullable columns serialize as null.

{
  "data": [
    {
      "id": "uuid",
      "library_id": "uuid",
      "title": "Book Title",
      "author": "Author Name",
      "isbn": "978-...",
      "description": "Book description",
      "file_path": "relative/path/book.epub",
      "file_size": 1024000,
      "mime_type": "application/epub+zip",
      "cover_image_path": "relative/path/cover.jpg",
      "series": "Series Name",
      "series_number": 1,
      "tags": ["sci-fi"],
      "asin": null,
      "date_published": "2023-06-01",
      "publisher": null,
      "contributors": ["Author Name"],
      "language": "en",
      "edition": null,
      "page_count": 350,
      "genre": "Science Fiction",
      "copyright_year": 2023,
      "goodreads_id": null,
      "openlibrary_id": null,
      "google_books_id": null,
      "added_by_admin_id": "uuid",
      "created_at": "2026-01-31T10:00:00Z",
      "imported_at": "2026-01-31T10:00:00Z",
      "updated_at": "2026-01-31T10:00:00Z",
      "format_group": "epub",
      "format_mimetype": "application/epub+zip",
      "is_reflowable": true,
      "has_fixed_layout": false,
      "total_characters": 480000,
      "chapter_count": 24
    }
  ]
}

Note: in this mode file_path and cover_image_path are the raw relative storage paths, not URLs.

Without library_id — curated items with resolved URLs

Across all libraries; file and cover paths are resolved to fetchable URL paths (/uploads/... or library-scoped paths):

{
  "data": [
    {
      "id": "uuid",
      "library_id": "uuid",
      "title": "Book Title",
      "author": "Author Name",
      "isbn": "978-...",
      "description": "Book description",
      "file_path": "/api/libraries/<uuid>/files/...",
      "file_size": 1024000,
      "mime_type": "application/epub+zip",
      "cover_image_path": "/api/libraries/<uuid>/files/.../cover.jpg",
      "series": "Series Name",
      "series_number": 1,
      "tags": ["sci-fi"],
      "asin": null,
      "date_published": "2023-06-01",
      "publisher": null,
      "contributors": ["Author Name"],
      "language": "en",
      "edition": null,
      "page_count": 350,
      "genre": "Science Fiction",
      "created_at": "2026-01-31T10:00:00Z",
      "updated_at": "2026-01-31T10:00:00Z",
      "format_group": "epub",
      "manga_type": null,
      "reading_direction": null,
      "series_count": null,
      "volume": null,
      "imprint": null,
      "age_rating": null,
      "web_url": null,
      "metadata_notes": null,
      "community_rating": null,
      "story_arc": null,
      "is_black_and_white": false,
      "alternate_info": null,
      "scan_information": null,
      "summary": null
    }
  ]
}

Error Responses

Code Description
400 Invalid library_id, offset < 0
401 Invalid or expired token
500 Query failure (returned as {"error": …})