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
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 descriptioncolor(optional): Hex color code (e.g., "#FF5733")icon(optional): Emoji icon (e.g., "🚀", "📖")auto_assign_rules(optional): Array of rule objectsview_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 againstpriority: 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 UUIDbookId: 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 genreauthor: Book authorseries: Book series namelanguage: Book languagepublisher: Publisher namecopyright_year: Publication year (numeric comparison)tags: Book tags
Supported Operators:
equals: Exact matchnot_equals: Not equalcontains: Contains substring (case-insensitive)not_contains: Does not containstarts_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 devicebook_to_hoard: Bookhoard → Device onlydevice_to_hoard: Device → Bookhoard onlynone: 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 UUIDcollectionId: 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 UUIDcollectionId: 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.ymlCreate Collection.ymlGet Collection.ymlUpdate Collection.ymlDelete Collection.ymlAdd Books to Collection.ymlRemove Book from Collection.ymlGet Book Collections.ymlTest Collection Rules.ymlBulk Remove Books.yml
Run tests:
bruno run bruno/collections/
Last Updated: 2026-02-01
Version: 1.0