Files
bookhoard/docs/developer/api/media-items/create_media_item.md
T
John O'Keefe 8aa66a30fc docs(api): sync mirrors with the retired rules CRUD and the chain-order endpoint
Three mirrors had drifted:

- The rules-endpoint retirement (4f71eda6) deleted the routes but not
  their mirrors: removed docs/developer/api/collections/
  {add_auto_assign_rule,remove_auto_assign_rule,test_rule,update_rule}
  .md + their bruno twins, and pruned /api/collections/test-rules,
  /{id}/rules, /{id}/rules/{ruleId} from the generated openapi spec
  (hand-edited — regenerating with -update would wipe hand-authored
  bruno suites that predate the docs mirrors).
- New endpoint PUT /api/collections/:id/view-settings gets a doc page
  + schema-registry entry + bruno mirror (repo convention: the route
  and its docs land together).
- 54 pre-existing TestDocsMatchRoutes failures: the media-item
  endpoints emit the 16 episode/download fields (source_feed_id,
  feed_position, download_state, enclosure_url, hosts/guests, …) and
  libraries emit purpose/allow_member_feeds, but the doc examples
  were never extended — the package only runs on the host, so the
  container suite never caught it. Examples now carry every key the
  handlers emit; internal/docs is fully green.
2026-10-31 15:40:21 -04:00

6.5 KiB

method, path, auth, area
method path auth area
POST /api/media-items jwt+admin media-items

Create Media Item

Create a new media item (Admin only).

Endpoint: POST /api/media-items Auth: Required (Admin only) Content-Type: application/json

Prerequisites

Before creating media items, the library must have at least one folder configured:

  1. Create a library: POST /api/libraries
  2. Add folder(s) to the library: POST /api/libraries/{library_id}/folders
  3. Then create media items: POST /api/media-items

See Library API documentation for more details.

Request Body

Field Type Required Description
library_id string (UUID) Yes Library UUID to add the media item to
title string Yes Media item title (1-500 characters)
author string No Author name
isbn string No ISBN number
description string No Description or summary
file_path string Yes Path to the media file
file_size integer Yes Size of the file in bytes
mime_type string Yes MIME type of the file
cover_image_path string No Path to the cover image
series string No Series name
series_number integer No Number in the series
tags array of strings No Tags (auto-normalized)
asin string No Amazon ASIN
date_published string No Publication date
publisher string No Publisher name
contributors array of strings No Contributors (auto-normalized)

Tag/Contributor Normalization

Tags and contributors are automatically normalized:

  • Tags: Titlecased, punctuation preserved, case-insensitive deduplication
  • Contributors: Original casing and punctuation preserved, case-insensitive deduplication
  • Search fields: Auto-generated for case-insensitive search

Example Request

{
  "library_id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Example Book Title",
  "author": "Jane Doe",
  "isbn": "978-0-123456-78-9",
  "description": "A great book about technology",
  "file_path": "/library/books/example.epub",
  "file_size": 1048576,
  "mime_type": "application/epub+zip",
  "series": "Tech Series",
  "series_number": 1,
  "tags": ["science-fiction", "technology", "ACME CORP."],
  "publisher": "O'Reilly Media",
  "contributors": ["John Smith", "ACME CORP."]
}

Response (201 Created)

{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "library_id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Example Book Title",
  "author": "Jane Doe",
  "isbn": "978-0-123456-78-9",
  "description": "A great book about technology",
  "file_path": "/library/books/example.epub",
  "file_size": 1048576,
  "mime_type": "application/epub+zip",
  "series": "Tech Series",
  "series_number": 1,
  "tags": [
    "Science-Fiction",
    "Technology",
    "ACME CORP."
  ],
  "tags_search": [
    "science fiction",
    "technology",
    "acme corp"
  ],
  "publisher": "O'Reilly Media",
  "contributors": [
    "John Smith",
    "ACME CORP."
  ],
  "contributors_search": [
    "john smith",
    "acme corp"
  ],
  "created_at": "2026-01-31T10:00:00Z",
  "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,
  "copyright_year": null,
  "cover_image_path": null,
  "date_published": null,
  "edition": null,
  "entitlement_id": null,
  "explicit": null,
  "file_sha256": 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,
  "kobo_content_id": null,
  "kobo_metadata": null,
  "language": null,
  "library_type_name": null,
  "manga_type": null,
  "metadata_notes": null,
  "metadata_overrides": null,
  "missing_scan_count": null,
  "narrators": null,
  "narrators_search": null,
  "openlibrary_id": null,
  "opf_identifier": null,
  "opf_uuid": null,
  "page_count": 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,
  "total_characters": null,
  "volume": null,
  "web_url": null,
  "source": null,
  "source_feed_id": null,
  "feed_position": null,
  "episode_number": null,
  "season_number": null,
  "episode_guid": null,
  "enclosure_url": null,
  "chapters_url": null,
  "transcript_url": null,
  "hosts": null,
  "guests": null,
  "declared_duration_seconds": null,
  "download_state": null,
  "download_attempts": null,
  "download_queue_pos": null,
  "download_error": null
}

Error Responses

Code Description
400 Invalid request data OR library has no folders
401 Invalid or expired token
403 User is not an admin
404 Library not found

400 - Library Has No Folders

When attempting to create a media item in a library that has no folders configured:

{
  "error": "Cannot add media items to a library with no folders. Please add at least one folder to the library first."
}

Solution: Add a folder to the library first:

POST /api/libraries/{library_id}/folders
{
  "folder_path": "/path/to/library/folder"
}