Files
bookhoard/docs/developer/collections-api.md
T
john-okeefe 4d321528b2 docs: update comprehensive API documentation and project guides
This commit updates all documentation files throughout the project:

- Updated IMPLEMENTATION_PLAN.md with new implementation details
- Updated PROJECT_GUIDELINES.md with coding standards and practices
- Updated README.md with current project information
- Updated SCREENSHOT_AUTOMATION.md with new automation details
- Added TEST_DATA.md with test fixtures data
- Updated cover_image_serving_plan.md with static URL patterns

Documentation API updates:
- Updated API reference documentation for all endpoints including:
  - Authentication (login, logout, register, refresh_token)
  - Book matching (auto_link, bulk_link, link_book, search)
  - Collections (CRUD operations, shelf mappings, auto-assign rules)
  - Conflicts (bulk operations, resolve/dismiss)
  - Devices (registration, approval, shelf management)
  - Highlights (create, update, delete, get)
  - Kobo sync (bookmark, markup, initialization, sync)
  - KOReader sync (library, metadata, bookmarks, progress)
  - Libraries (CRUD, folders, media items, stats)
  - Media items (bulk operations, CRUD)
  - Notes (CRUD operations)
  - OPDS (acquisition, feeds, publication)
  - Progress (reading progress tracking)
  - Queue (device queue management)
  - Ratings (star ratings)
  - Scanner (watch mode, scan operations)
  - Sync protocols (Kobo, KOReader)
  - Users (profile, password, admin operations)
  - WebSocket protocols

- Updated user guides (admin, dashboard, settings, sync)
- Updated device setup guides (Kobo, KOReader)
- Updated developer guides (testing, contributing, operations)
- Updated scripts/README.md
2026-02-27 17:06:22 -05:00

10 KiB

Collections API Documentation

Complete API reference for collection management endpoints.

Base Path: /api/collections


Overview

Collections allow you to organize your books into custom categories with:

  • Auto-assignment rules: Automatically add books matching criteria
  • View settings: Per-device display preferences
  • Shelf mappings: Sync to device-specific shelves (Kobo, KOReader)

Endpoints

List All Collections

Endpoint: GET /api/collections
Authentication: Required
Description: Get all collections for the authenticated user

Response (200 OK):

{
  "collections": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Science Fiction",
      "description": "My sci-fi collection",
      "color": "#FF5733",
      "icon": "🚀",
      "auto_assign_rules": [
        {
          "field": "genre",
          "operator": "equals",
          "value": "Science Fiction",
          "priority": 1,
          "enabled": true
        }
      ],
      "view_settings": {
        "kobo": {
          "view_mode": "grid",
          "sort_order": "name",
          "items_per_page": 24
        }
      },
      "created_at": "2026-02-01T10:00:00Z"
    }
  ],
  "total": 1
}

Create Collection

Endpoint: POST /api/collections
Authentication: Required
Description: Create a new collection

Request Body:

{
  "name": "To Read",
  "description": "Books I want to read soon",
  "color": "#00FF00",
  "icon": "📖",
  "auto_assign_rules": [
    {
      "field": "tags",
      "operator": "contains",
      "value": "to-read",
      "priority": 1,
      "enabled": true
    }
  ],
  "view_settings": {
    "kobo": {
      "view_mode": "grid"
    },
    "koreader": {
      "view_mode": "list"
    }
  }
}

Fields:

  • name (required): Collection name (max 255 chars)
  • description (optional): Collection description
  • color (optional): Hex color code (e.g., "#FF5733")
  • icon (optional): Emoji icon (e.g., "🚀", "📖")
  • auto_assign_rules (optional): Array of rule objects
  • view_settings (optional): Per-device display preferences

Rule Object:

  • field: Field to match on (genre, author, series, language, publisher, copyright_year, tags)
  • operator: Comparison operator (equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, less_than)
  • value: Value to compare against
  • priority: Rule priority (1 = highest)
  • enabled: Whether rule is active

Response (201 Created): Collection object

Get Collection Details

Endpoint: GET /api/collections/{id}
Authentication: Required
Description: Get single collection with all books

Path Parameters:

  • id: Collection UUID

Response (200 OK):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Science Fiction",
  "description": "My sci-fi collection",
  "color": "#FF5733",
  "icon": "🚀",
  "books": [
    {
      "media_item_id": "660e8400-e29b-41d4-a716-446655440000",
      "title": "Foundation",
      "author": "Isaac Asimov",
      "cover_image_path": "/covers/foundation.jpg"
    }
  ],
  "auto_assign_rules": [],
  "view_settings": {},
  "created_at": "2026-02-01T10:00:00Z"
}

Update Collection

Endpoint: PUT /api/collections/{id}
Authentication: Required
Description: Update collection details

Path Parameters:

  • id: Collection UUID

Request Body: All fields are optional

{
  "name": "Sci-Fi Favorites",
  "description": "Updated description",
  "color": "#BLUE",
  "icon": "🌟"
}

Response (200 OK): Updated collection object

Delete Collection

Endpoint: DELETE /api/collections/{id}
Authentication: Required
Description: Delete a collection (books are NOT deleted)

Path Parameters:

  • id: Collection UUID

Response (204 No Content)


Collection Books

Add Books to Collection

Endpoint: POST /api/collections/{id}/books
Authentication: Required
Description: Add one or more books to a collection

Path Parameters:

  • id: Collection UUID

Request Body:

{
  "book_ids": [
    "660e8400-e29b-41d4-a716-446655440000",
    "770e8400-e29b-41d4-a716-446655440000",
    "880e8400-e29b-41d4-a716-446655440000"
  ]
}

Response (204 No Content)

Remove Book from Collection

Endpoint: DELETE /api/collections/{id}/books/{bookId}
Authentication: Required
Description: Remove a single book from a collection

Path Parameters:

  • id: Collection UUID
  • bookId: Media Item UUID

Response (204 No Content)

Bulk Remove Books

Endpoint: POST /api/collections/{id}/books/bulk-remove
Authentication: Required
Description: Remove multiple books at once (efficient)

Path Parameters:

  • id: Collection UUID

Request Body:

{
  "book_ids": [
    "660e8400-e29b-41d4-a716-446655440000",
    "770e8400-e29b-41d4-a716-446655440000"
  ]
}

Response (200 OK):

{
  "removed": 2,
  "total": 2
}

Example: Removing 2 books, both successfully removed

Get Collection Books

Endpoint: GET /api/collections/{id}/books
Authentication: Required
Description: Get all books in a collection

Path Parameters:

  • id: Collection UUID

Query Parameters:

  • limit (optional): Number of books to return (default: 50)
  • offset (optional): Number of books to skip (default: 0)

Response (200 OK):

{
  "books": [
    {
      "media_item_id": "660e8400-e29b-41d4-a716-446655440000",
      "title": "Foundation",
      "author": "Isaac Asimov",
      "cover_image_path": "/covers/foundation.jpg",
      "added_at": "2026-02-01T10:00:00Z"
    }
  ],
  "total": 1
}

Collection Rules

Test Collection Rules

Endpoint: POST /api/collections/test-rules
Authentication: Required
Description: Test which books would match given rules (without saving)

Request Body:

{
  "rules": [
    {
      "field": "genre",
      "operator": "equals",
      "value": "Science Fiction"
    },
    {
      "field": "author",
      "operator": "contains",
      "value": "Asimov"
    }
  ]
}

Supported Fields:

  • genre: Book genre
  • author: Book author
  • series: Book series name
  • language: Book language
  • publisher: Publisher name
  • copyright_year: Publication year (numeric comparison)
  • tags: Book tags

Supported Operators:

  • equals: Exact match
  • not_equals: Not equal
  • contains: Contains substring (case-insensitive)
  • not_contains: Does not contain
  • starts_with: Starts with (case-insensitive)
  • ends_with: Ends with (case-insensitive)
  • greater_than: Greater than (numeric)
  • less_than: Less than (numeric)

Response (200 OK):

{
  "matches": [
    {
      "media_item_id": "660e8400-e29b-41d4-a716-446655440000",
      "title": "Foundation",
      "author": "Isaac Asimov",
      "cover_image_path": "/covers/foundation.jpg",
      "match_reason": "Matched rule: genre equals Science Fiction"
    }
  ],
  "total": 42
}

Use Case: Test rules before creating collection to verify correct book matching


Device Shelf Mappings

Get Device Shelf Mappings

Endpoint: GET /api/devices/{deviceId}/collections
Authentication: Required
Description: Get all collection-to-shelf mappings for a device

Path Parameters:

  • deviceId: Device UUID

Response (200 OK):

{
  "mappings": [
    {
      "id": "990e8400-e29b-41d4-a716-446655440000",
      "collection_id": "550e8400-e29b-41d4-a716-446655440000",
      "collection_name": "Science Fiction",
      "device_shelf_name": "Sci-Fi",
      "sync_direction": "bidirectional",
      "created_at": "2026-02-01T10:00:00Z"
    }
  ]
}

Create Shelf Mapping

Endpoint: POST /api/devices/{deviceId}/collections
Authentication: Required
Description: Map a collection to a device shelf

Path Parameters:

  • deviceId: Device UUID

Request Body:

{
  "collection_id": "550e8400-e29b-41d4-a716-446655440000",
  "device_shelf_name": "Sci-Fi",
  "sync_direction": "bidirectional"
}

Sync Directions:

  • bidirectional: Sync both ways between Bookhoard and device
  • book_to_hoard: Bookhoard → Device only
  • device_to_hoard: Device → Bookhoard only
  • none: No sync (mapping only)

Response (201 Created): Mapping object

Update Shelf Mapping

Endpoint: PUT /api/devices/{deviceId}/collections/{collectionId}
Authentication: Required
Description: Update existing shelf mapping

Path Parameters:

  • deviceId: Device UUID
  • collectionId: Collection UUID

Request Body:

{
  "device_shelf_name": "Science Fiction",
  "sync_direction": "book_to_hoard"
}

Response (200 OK): Updated mapping object

Delete Shelf Mapping

Endpoint: DELETE /api/devices/{deviceId}/collections/{collectionId}
Authentication: Required
Description: Remove shelf mapping

Path Parameters:

  • deviceId: Device UUID
  • collectionId: Collection UUID

Response (204 No Content)


Error Responses

All endpoints may return these errors:

400 Bad Request:

{
  "error": "invalid request: validation failed"
}

401 Unauthorized:

{
  "error": "authentication required"
}

404 Not Found:

{
  "error": "collection not found"
}

500 Internal Server Error:

{
  "error": "internal server error"
}

Rate Limiting

  • Authenticated: 100 requests per minute
  • Unauthenticated: 10 requests per minute

Headers included:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1643723400

Bruno OpenCollection YAML Tests

Complete API tests available in bruno/collections/:

  • Get Collections.yml
  • Create Collection.yml
  • Get Collection.yml
  • Update Collection.yml
  • Delete Collection.yml
  • Add Books to Collection.yml
  • Remove Book from Collection.yml
  • Get Book Collections.yml
  • Test Collection Rules.yml
  • Bulk Remove Books.yml

Run tests:

bruno run bruno/collections/

Last Updated: 2026-02-01
Version: 1.0