meta { name: List Media Items with Sorting type: http seq: 1 } get { url: {{base_url}}/api/media-items?library_id={{library_id}}&sort=title+ASC&limit=10&offset=0 auth: inherit } headers { Content-Type: application/json } tests { test_list_media_items_sorted(status, headers, body) { if (status !== 200) { throw new Error("Expected status 200, got " + status); } const contentType = headers["content-type"]; if (!contentType || !contentType.includes("application/json")) { throw new Error("Expected content-type to contain application/json, got " + contentType); } let data; try { const parsed = JSON.parse(body); data = parsed.data; } catch (e) { throw new Error("Response body is not valid JSON: " + e.message); } if (!Array.isArray(data)) { throw new Error("Expected response data to be an array"); } // Verify items are sorted by title ascending for (let i = 1; i < data.length; i++) { const prevTitle = data[i - 1].title.toLowerCase(); const currTitle = data[i].title.toLowerCase(); if (prevTitle > currTitle) { throw new Error("Items not sorted by title ASC: " + prevTitle + " should come before " + currTitle); } } data.forEach((item, index) => { if (!item || typeof item !== "object") { throw new Error("Media item at index " + index + " is not an object"); } if (!item.id) { throw new Error("Media item at index " + index + " missing required field: id"); } if (!item.title) { throw new Error("Media item at index " + index + " missing required field: title"); } if (!item.library_id) { throw new Error("Media item at index " + index + " missing required field: library_id"); } if (!item.library_name) { throw new Error("Media item at index " + index + " missing required field: library_name"); } }); return true; } } vars:pre-request { sortBy: "title ASC" } settings { encodeUrl: true timeout: 0 } docs { ## List Media Items with Sorting **Method:** GET **Endpoint:** /api/media-items **Authentication:** Required (Bearer token) **Query Parameters:** - `library_id` (string, required): UUID of the library - `sort` (string, optional): Sort field and direction - Available options: - `created_at ASC` - Oldest added first - `created_at DESC` - Newest added first (default) - `title ASC` - Title A-Z - `title DESC` - Title Z-A - `author ASC` - Author A-Z - `author DESC` - Author Z-A - `series ASC` - Series order - `series DESC` - Series reverse order - `date_published ASC` - Oldest published first - `date_published DESC` - Newest published first - `copyright_year ASC` - Oldest copyright first - `copyright_year DESC` - Newest copyright first - `page_count ASC` - Shortest first - `page_count DESC` - Longest first - `genre ASC` - Genre A-Z - `genre DESC` - Genre Z-A - `limit` (integer, optional): Number of items to return (default: 50, max: 1000) - `offset` (integer, optional): Number of items to skip (default: 0) **Response:** Object containing array of media items **Status Codes:** - 200: Success - 400: Bad request (invalid parameters) - 401: Unauthorized - 500: Internal server error **Examples:** - Sort by title: `/api/media-items?library_id=xxx&sort=title+ASC` - Sort by author descending: `/api/media-items?library_id=xxx&sort=author+DESC` - Sort by page count: `/api/media-items?library_id=xxx&sort=page_count+ASC` **Sorting Behavior:** - All sorts are secondary-sorted by series_number then title for consistency - NULL values are sorted last for ascending, first for descending - Sorting is case-insensitive for text fields }