--- method: PUT path: /api/media-items/:id auth: jwt+admin area: media-items --- # Update Media Item Update media item metadata (Admin only). **Endpoint**: `PUT /api/media-items/{media_id}` **Auth**: Required (Admin only) **Content-Type**: `application/json` ## Path Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------- | | media_id | string | Yes | Media item UUID | ## Request Body | Field | Type | Required | Description | | ------------- | --------------- | -------- | -------------------------------------- | | title | string | No | Updated title | | author | string | No | Updated author | | description | string | No | Updated description | | series | string | No | Series name | | series_number | integer | No | Number in series | | tags | array of string | No | Updated tags (auto-normalized) | | contributors | array of string | No | Updated contributors (auto-normalized) | **Tag/Contributor Normalization:** - Tags are titlecased and deduplicated (case-insensitive) - Contributors preserve original casing and punctuation - Punctuation-preferred deduplication (keeps "ACME CORP." over "acme corp") - Search fields auto-generated for case-insensitive search ### Example Request ```json example-request { "title": "Updated Title", "author": "Updated Author", "description": "Updated description", "series": "Series", "series_number": 2 } ``` ## Response (200 OK) ```json example-response { "id": "uuid", "title": "Updated Title", "author": "Updated Author", "description": "Updated description", "series": "Series", "series_number": 2, "updated_at": "2026-01-31T10:00:00Z", "abridged": null, "added_by_admin_id": null, "age_rating": null, "alternate_info": null, "archived_at": null, "asin": null, "audio_metadata": null, "authors": null, "authors_search": null, "chapter_count": null, "chapter_metadata": null, "community_rating": null, "contributors": null, "contributors_search": null, "copyright_year": null, "cover_image_path": null, "created_at": null, "date_published": null, "edition": null, "entitlement_id": null, "explicit": null, "file_path": null, "file_sha256": null, "file_size": null, "format_group": null, "format_mimetype": null, "genre": null, "goodreads_id": null, "google_books_id": null, "has_fixed_layout": null, "hash_confidence": null, "imported_at": null, "imprint": null, "is_black_and_white": null, "is_reflowable": null, "isbn": null, "kobo_content_id": null, "kobo_metadata": null, "language": null, "library_id": null, "library_type_name": null, "manga_type": null, "metadata_notes": null, "metadata_overrides": null, "mime_type": null, "missing_scan_count": null, "narrators": null, "narrators_search": null, "openlibrary_id": null, "opf_identifier": null, "opf_uuid": null, "page_count": null, "publisher": null, "publishers": null, "publishers_search": null, "reading_direction": null, "revision_number": null, "scan_information": null, "series_count": null, "story_arc": null, "subtitle": null, "summary": null, "tags": null, "tags_search": null, "total_characters": null, "volume": null, "web_url": null } ``` ## Error Responses | Code | Description | | ---- | ------------------------ | | 400 | Invalid input data | | 401 | Invalid or expired token | | 403 | User is not an admin | | 404 | Media item not found |