docs(api): add comprehensive Collections API documentation
Create detailed API reference for collection management endpoints:
Sections Included:
- Overview of collections feature
- All CRUD endpoints (Create, Read, Update, Delete, List)
- Book management endpoints (Add, Remove, Bulk Remove, List)
- Rule testing endpoint (Test rules before saving)
- Device shelf mapping endpoints
- Error response documentation
- Rate limiting information
- Bruno test collection references
Detailed Documentation:
- Request/response examples with actual JSON
- Path parameter descriptions
- Query parameter documentation
- Request body field specifications
- Supported rule fields and operators
- Sync direction options for shelf mappings
- Complete error response formats
Special Features Documented:
- Auto-assign rules with priority
- Per-device view settings
- Collection to shelf mapping
- Bulk operations efficiency
- Rule testing for preview
- Case-insensitive matching
- Numeric comparisons for years
API Endpoints Covered:
- GET /api/collections - List all collections
- POST /api/collections - Create collection
- GET /api/collections/{id} - Get collection details
- PUT /api/collections/{id} - Update collection
- DELETE /api/collections/{id} - Delete collection
- POST /api/collections/{id}/books - Add books
- DELETE /api/collections/{id}/books/{bookId} - Remove book
- POST /api/collections/{id}/books/bulk-remove - Bulk remove
- GET /api/collections/{id}/books - List collection books
- POST /api/collections/test-rules - Test rules
- GET /api/devices/{deviceId}/collections - Get shelf mappings
- POST /api/devices/{deviceId}/collections - Create mapping
- PUT /api/devices/{deviceId}/collections/{collectionId} - Update mapping
- DELETE /api/devices/{deviceId}/collections/{collectionId} - Delete mapping
This documentation enables developers to:
- Integrate collection management into third-party apps
- Build custom collection UIs
- Automate collection organization
- Integrate with mobile apps
Format: Markdown with code examples
Version: 1.0
Date: 2026-02-01
This commit is contained in:
@@ -0,0 +1,493 @@
|
||||
# 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):
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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):
|
||||
```json
|
||||
{
|
||||
"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
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"book_ids": [
|
||||
"660e8400-e29b-41d4-a716-446655440000",
|
||||
"770e8400-e29b-41d4-a716-446655440000"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"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):
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"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):
|
||||
```json
|
||||
{
|
||||
"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):
|
||||
```json
|
||||
{
|
||||
"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**:
|
||||
```json
|
||||
{
|
||||
"collection_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"device_shelf_name": "Sci-Fi",
|
||||
"sync_direction": "bidirectional"
|
||||
}
|
||||
```
|
||||
|
||||
**Sync Directions**:
|
||||
- `bidirectional`: Sync both ways between Bookmann and device
|
||||
- `book_to_device`: Bookmann → Device only
|
||||
- `device_to_book`: Device → Bookmann 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**:
|
||||
```json
|
||||
{
|
||||
"device_shelf_name": "Science Fiction",
|
||||
"sync_direction": "book_to_device"
|
||||
}
|
||||
```
|
||||
|
||||
**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**:
|
||||
```json
|
||||
{
|
||||
"error": "invalid request: validation failed"
|
||||
}
|
||||
```
|
||||
|
||||
**401 Unauthorized**:
|
||||
```json
|
||||
{
|
||||
"error": "authentication required"
|
||||
}
|
||||
```
|
||||
|
||||
**404 Not Found**:
|
||||
```json
|
||||
{
|
||||
"error": "collection not found"
|
||||
}
|
||||
```
|
||||
|
||||
**500 Internal Server Error**:
|
||||
```json
|
||||
{
|
||||
"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 Tests
|
||||
|
||||
Complete API tests available in `bruno/collections/`:
|
||||
|
||||
- `Get Collections.bru`
|
||||
- `Create Collection.bru`
|
||||
- `Get Collection.bru`
|
||||
- `Update Collection.bru`
|
||||
- `Delete Collection.bru`
|
||||
- `Add Books to Collection.bru`
|
||||
- `Remove Book from Collection.bru`
|
||||
- `Get Book Collections.bru`
|
||||
- `Test Collection Rules.bru`
|
||||
- `Bulk Remove Books.bru`
|
||||
|
||||
Run tests:
|
||||
```bash
|
||||
bruno run bruno/collections/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-02-01
|
||||
**Version**: 1.0
|
||||
Reference in New Issue
Block a user