refactor(bruno): reorganize file structure from bruno-yaml to flat bruno directory
- Move all files from bruno-yaml/* to bruno/* - Maintains existing directory structure within categories - Updates bruno/user/auth files with OAuth2 refresh token flow - Updates bruno/user/profile files for user profile management - Adds bruno/dashboard/ directory with dashboard API tests - Preserves all existing test scenarios and OpenCollection YAML format - No functional changes - file reorganization only
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
info:
|
||||
name: Bookhoard Device Management API
|
||||
type: collection
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '"http://localhost:8765/api"'
|
||||
@@ -0,0 +1,96 @@
|
||||
info:
|
||||
name: Get Analytics Tests
|
||||
type: http
|
||||
seq: 7
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/v1/analytics/gettests'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
platform: android
|
||||
firmware_version: 4.30.19023
|
||||
|
||||
docs: |-
|
||||
## Get Kobo Analytics Tests
|
||||
|
||||
Retrieves A/B testing configuration and feature flags for Kobo device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/v1/analytics/gettests
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `platform` (string): Device platform
|
||||
- `android`: Kobo Android app
|
||||
- `kobo`: Native Kobo firmware
|
||||
- `firmware_version` (string): Firmware version (e.g., "4.30.19023")
|
||||
- `device_model` (string, optional): Device model identifier
|
||||
- `locale` (string, optional): Device locale (e.g., "en_US")
|
||||
|
||||
**Response:**
|
||||
- `tests` (array): Active A/B tests
|
||||
- `test_name` (string): Test identifier
|
||||
- `variant` (string): Assigned variant (A, B, C, etc.)
|
||||
- `enabled` (boolean): Whether test is active
|
||||
- `parameters` (object): Test-specific parameters
|
||||
- `features` (object): Feature flags
|
||||
- `feature_name` (boolean/string): Feature state
|
||||
- `configuration` (object): Device configuration
|
||||
- `sync_interval_minutes` (integer): Recommended sync frequency
|
||||
- `batch_size` (integer): Max items per batch sync
|
||||
- `timeout_seconds` (integer): Request timeout
|
||||
- `version` (string): Configuration version
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid request parameters
|
||||
|
||||
**Analytics Testing Purpose:**
|
||||
- Kobo uses A/B testing for UX features
|
||||
- Feature flags for gradual rollout
|
||||
- Performance monitoring configuration
|
||||
- Sync behavior optimization
|
||||
- Device-specific tuning
|
||||
|
||||
**Common Tests:**
|
||||
- Sync frequency optimization
|
||||
- UI/UX variations
|
||||
- Network usage patterns
|
||||
- Battery life improvements
|
||||
- Feature set variations by model
|
||||
|
||||
**Feature Flags:**
|
||||
- New sync features
|
||||
- Beta functionality
|
||||
- Platform-specific capabilities
|
||||
- Experimental features
|
||||
|
||||
**Configuration Parameters:**
|
||||
- Optimal sync intervals for device
|
||||
- Batch size limits based on device capabilities
|
||||
- Timeout values for network conditions
|
||||
- Retry logic configuration
|
||||
- Cache policy settings
|
||||
|
||||
**Usage:**
|
||||
- Called during device initialization
|
||||
- Refreshed daily or weekly
|
||||
- Cached on device
|
||||
- Affects sync behavior
|
||||
- Can be overridden by server
|
||||
|
||||
**Use Cases:**
|
||||
- Device initialization
|
||||
- Feature rollout testing
|
||||
- Performance optimization
|
||||
- UX experiment participation
|
||||
- Configuration management
|
||||
@@ -0,0 +1,81 @@
|
||||
info:
|
||||
name: Get Kobo Library
|
||||
type: http
|
||||
seq: 6
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/kobo/library'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Get Kobo Library
|
||||
|
||||
Retrieves the user's Kobo library metadata for device sync.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/kobo/library
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Query Parameters:**
|
||||
None (returns entire library)
|
||||
|
||||
**Response:**
|
||||
- `books` (array): Library items
|
||||
- `ContentId` (string): Unique book identifier
|
||||
- `Title` (string): Book title
|
||||
- `Author` (string): Author name
|
||||
- `Publisher` (string): Publisher name
|
||||
- `Description` (string): Book description
|
||||
- `ISBN` (string, optional): ISBN-13
|
||||
- `PublicationDate` (string): Release date
|
||||
- `EntitlementId` (string): Kobo entitlement ID
|
||||
- `CrossRevisionId` (string): Revision identifier
|
||||
- `MimeType` (string): Content type (application/epub+zip)
|
||||
- `FileSize` (integer): File size in bytes
|
||||
- `CoverImageId` (string): Cover image identifier
|
||||
- `DownloadUrls` (object): Download URLs
|
||||
- `download_url` (string): Direct download link
|
||||
- `download_acquisition_url` (string): OPDS acquisition URL
|
||||
- `sync_metadata` (object):
|
||||
- `last_sync` (string): Last library sync timestamp
|
||||
- `total_books` (integer): Total book count
|
||||
- `has_updates` (boolean): Whether updates are available
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 403: Device not approved
|
||||
|
||||
**Library Sync Purpose:**
|
||||
- Kobo device needs to know available books
|
||||
- Enables download via device browser
|
||||
- Provides metadata for device display
|
||||
- Supports Kobo's "My Books" feature
|
||||
- Enables on-device purchasing integration
|
||||
|
||||
**Kobo Device Usage:**
|
||||
- Device fetches library on registration
|
||||
- Refreshed daily or on manual sync
|
||||
- User can browse library on device
|
||||
- Books downloaded wirelessly to device
|
||||
- Supports "Buy on Kobo, read on device" workflow
|
||||
|
||||
**Authentication Methods:**
|
||||
This endpoint uses **Bearer token authentication** (token in Authorization header).
|
||||
Alternative: Use `/sync/kobo/{token}/library` with token in URL path.
|
||||
|
||||
**Performance:**
|
||||
- Typical response: 50-200KB for 100 books
|
||||
- Processing time: 200-800ms
|
||||
- Cache duration: 5 minutes
|
||||
- Pagination available for large libraries (>500 books)
|
||||
|
||||
**Use Cases:**
|
||||
- Initial device registration
|
||||
- Library refresh on device
|
||||
- Book discovery on device
|
||||
- Download link generation
|
||||
- Metadata sync for OPDS
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Get Unlinked Book Suggestions
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/sync/unlinked-books/{{unlinkedBookId}}/suggestions'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{authToken
|
||||
|
||||
docs: |-
|
||||
## Get Unlinked Book Suggestions
|
||||
|
||||
Retrieves suggested media items from the library that match an unlinked book, enabling manual linking.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /sync/unlinked-books/{unlinkedBookId
|
||||
@@ -0,0 +1,7 @@
|
||||
info:
|
||||
name: Bookhoard Kobo Sync API
|
||||
type: collection
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '"http://localhost:8765/api"'
|
||||
@@ -0,0 +1,45 @@
|
||||
info:
|
||||
name: Auto-Link Unlinked Books
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/sync/auto-link-books'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"confidence_threshold\": 0.8,\n \"limit\": 50"
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: Authorization
|
||||
value: Bearer {{authToken
|
||||
|
||||
docs: |-
|
||||
## Auto-Link Unlinked Books
|
||||
|
||||
Automatically links unlinked books to media items based on title and author matching with a configurable confidence threshold.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /sync/auto-link-books
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `confidence_threshold` (number, optional): Minimum confidence score for auto-linking (0-1, default: 0.8)
|
||||
- `limit` (number, optional): Maximum number of books to auto-link (default: 50)
|
||||
|
||||
**Response:**
|
||||
- `results` (array): Results for each auto-link attempt
|
||||
- `total` (number): Total number of books processed
|
||||
- `success` (number): Number of successful links
|
||||
- `failed` (number): Number of failed links
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 400: Invalid request data
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
|
||||
**Note:** Higher confidence thresholds produce fewer but more accurate matches. Consider the tradeoff between automation and accuracy.
|
||||
@@ -0,0 +1,47 @@
|
||||
info:
|
||||
name: Bulk Link Unlinked Books
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/sync/bulk-link-books'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"links\": [\n {\n \"unlinked_book_id\": \"{{unlinkedBookId1"
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: Authorization
|
||||
value: Bearer {{authToken
|
||||
|
||||
docs: |-
|
||||
## Bulk Link Unlinked Books
|
||||
|
||||
Links multiple unlinked books to media items in a single request.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /sync/bulk-link-books
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `links` (array): Array of link objects
|
||||
- `unlinked_book_id` (string): Unlinked book UUID
|
||||
- `media_item_id` (string): Media item UUID to link to
|
||||
- `confidence_score` (number): Match confidence (0-1)
|
||||
|
||||
**Response:**
|
||||
- `results` (array): Results for each link attempt
|
||||
- `total` (number): Total number of links processed
|
||||
- `success` (number): Number of successful links
|
||||
- `failed` (number): Number of failed links
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 400: Invalid request data
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
|
||||
**Note:** Use this endpoint after reviewing suggestions from the Get Unlinked Book Suggestions endpoint.
|
||||
@@ -0,0 +1,98 @@
|
||||
info:
|
||||
name: Kobo Initialization
|
||||
type: http
|
||||
seq: 8
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/kobo/v1/initialization'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Kobo Device Initialization
|
||||
|
||||
Initializes Kobo device sync session and returns device configuration.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/kobo/v1/initialization
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Query Parameters:**
|
||||
- `Platform` (string, optional): Device platform (android, kobo)
|
||||
- `FirmwareVersion` (string, optional): Firmware version string
|
||||
- `Model` (string, optional): Device model name
|
||||
|
||||
**Response:**
|
||||
- `device` (object): Device information
|
||||
- `device_id` (string): Server device ID
|
||||
- `approved` (boolean): Whether device is approved
|
||||
- `sync_enabled` (boolean): Whether sync is active
|
||||
- `last_sync` (string): Last successful sync timestamp
|
||||
- `user` (object): User information
|
||||
- `user_id` (string): User identifier
|
||||
- `email` (string): User email (masked)
|
||||
- `library_size` (integer): Number of books in library
|
||||
- `sync_config` (object): Sync configuration
|
||||
- `sync_interval_minutes` (integer): Recommended sync frequency
|
||||
- `batch_size` (integer): Max items per batch
|
||||
- `timeout_seconds` (integer): Request timeout
|
||||
- `retry_count` (integer): Max retry attempts
|
||||
- `features` (object): Available features
|
||||
- `annotation_sync` (boolean): Annotation support
|
||||
- `bookmark_sync` (boolean): Bookmark support
|
||||
- `progress_sync` (boolean): Progress tracking
|
||||
- `library_download` (boolean): Library access
|
||||
- `endpoints` (object): API endpoint URLs
|
||||
- `markup_sync` (string): Progress/annotation sync URL
|
||||
- `bookmark_sync` (string): Bookmark sync URL
|
||||
- `library` (string): Library access URL
|
||||
- `sync_from_server` (string): Download sync URL
|
||||
- `server_time` (string): Current server timestamp
|
||||
- `version` (string): API version
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized (invalid token)
|
||||
- 403: Forbidden (device not approved)
|
||||
- 404: Device not found
|
||||
|
||||
**Initialization Flow:**
|
||||
1. Device powers on or connects to network
|
||||
2. Device calls initialization endpoint
|
||||
3. Server returns configuration and capabilities
|
||||
4. Device adjusts sync behavior based on config
|
||||
5. Device begins sync operations
|
||||
|
||||
**Authentication Methods:**
|
||||
This endpoint uses **Bearer token authentication** (token in Authorization header).
|
||||
Alternative: Use `/sync/kobo/{token}/v1/initialization` with token in URL path.
|
||||
|
||||
**Configuration Caching:**
|
||||
- Response cached on device for 24 hours
|
||||
- Refreshed on device reboot
|
||||
- Updated when sync settings change
|
||||
- Can be force-refreshed via device settings
|
||||
|
||||
**Device Approval:**
|
||||
- New devices: `approved: false`
|
||||
- Pending devices see limited functionality
|
||||
- Approval required for full sync
|
||||
- User approves via web interface
|
||||
- Re-initialization after approval
|
||||
|
||||
**Use Cases:**
|
||||
- Device registration
|
||||
- Daily device wakeup
|
||||
- Post-approval initialization
|
||||
- Configuration refresh
|
||||
- Feature capability check
|
||||
- Sync endpoint discovery
|
||||
|
||||
**Kobo Native Integration:**
|
||||
- Called by Kobo Nickel UI
|
||||
- Integrated with Kobo sync service
|
||||
- Part of Kobo account setup
|
||||
- Supports Kobo "Sync now" feature
|
||||
- Enables Kobo library browsing
|
||||
@@ -0,0 +1,53 @@
|
||||
info:
|
||||
name: Sync from Bookhoard to Kobo
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{baseURL}}/api/sync/kobo/sync-from-server'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "[\n {\n \"ContentId\": \"{{bookUUID"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{koboToken
|
||||
|
||||
docs: |-
|
||||
## Sync from Bookhoard to Kobo
|
||||
|
||||
Server-initiated sync pushing progress, bookmarks, and highlights from Bookhoard to Kobo device. Two-way sync endpoint.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/sync-from-server
|
||||
|
||||
**Authentication:** Bearer token with Kobo device identification
|
||||
|
||||
**Headers:**
|
||||
- `x-kobo-device` (string): JSON string containing Kobo device info
|
||||
- `DeviceId`: Kobo device ID
|
||||
- `Model`: Kobo device model
|
||||
- `SerialNumber`: Kobo device serial number
|
||||
|
||||
**Request Body:** Array of sync data objects
|
||||
- `ContentId` (string): Book UUID
|
||||
- `PercentRead` (number): Reading progress percentage (0-100)
|
||||
- `LastModified` (string): ISO 8601 timestamp
|
||||
- `Bookmarks` (array, optional): Array of bookmark objects
|
||||
- `BookmarkId`: Unique bookmark ID
|
||||
- `ContentId`: Book UUID
|
||||
- `BookmarkText`: Bookmark text/note
|
||||
- `BookmarkType`: Type (bookmark, annotation, etc.)
|
||||
- `BookmarkTitle`: Bookmark title
|
||||
- `Highlights` (array, optional): Array of highlight objects (same structure as bookmarks)
|
||||
|
||||
**Response:**
|
||||
- Sync result confirmation
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
|
||||
**Note:** Allows Bookhoard server to push updates to Kobo device, including reading progress, bookmarks, and highlights.
|
||||
@@ -0,0 +1,106 @@
|
||||
info:
|
||||
name: Sync Books from Server to Kobo
|
||||
type: http
|
||||
seq: 9
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/sync-from-server'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
force_sync: true
|
||||
books:
|
||||
- book-uuid-1
|
||||
- book-uuid-2
|
||||
|
||||
docs: |-
|
||||
## Sync Books from Server to Kobo
|
||||
|
||||
Pulls reading progress, annotations, and bookmarks from server to Kobo device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/sync-from-server
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `force_sync` (boolean): Force full sync (ignore last sync time)
|
||||
- `books` (array, optional): List of book UUIDs to sync
|
||||
- If empty, syncs all books with server data
|
||||
- If specified, only syncs listed books
|
||||
- `sync_options` (object, optional):
|
||||
- `since_date` (string): ISO 8601 timestamp for incremental sync
|
||||
- `include_annotations` (boolean): Include highlights/notes
|
||||
- `include_progress` (boolean): Include reading progress
|
||||
- `conflict_resolution` (string): `most_recent`, `server_wins`, `client_wins`
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Number of books synced
|
||||
- `skipped` (integer): Books with no server changes
|
||||
- `failed` (integer): Books that failed to sync
|
||||
- `results` (array): Per-book sync results
|
||||
- `book_id` (string): Book UUID
|
||||
- `status` (string): `synced`, `skipped`, `failed`
|
||||
- `progress_pulled` (boolean): Whether progress was downloaded
|
||||
- `annotations_pulled` (integer): Number of annotations downloaded
|
||||
- `error` (string, optional): Error message if failed
|
||||
- `server_timestamp` (string): Server timestamp of sync
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Sync completed
|
||||
- 207: Multi-status (some succeeded, some failed)
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid request
|
||||
|
||||
**Sync Direction:**
|
||||
- **Server → Device** (this endpoint)
|
||||
- Device → Server: Use `/sync/kobo/markup` endpoint
|
||||
- Bidirectional sync achieved by calling both
|
||||
|
||||
**Pull Sync Use Cases:**
|
||||
- New device setup (download all progress)
|
||||
- Device replacement (restore from server)
|
||||
- Multi-device sync (pull changes from other devices)
|
||||
- Conflict resolution (server wins)
|
||||
- Manual "Download from server" operation
|
||||
|
||||
**Conflict Resolution:**
|
||||
- `most_recent`: Latest timestamp wins (default)
|
||||
- `server_wins`: Server data always used
|
||||
- `client_wins`: Device data preserved
|
||||
- Applied per-book, per-item
|
||||
|
||||
**Sync Optimization:**
|
||||
- Incremental sync by default (since last sync)
|
||||
- Force sync does full comparison
|
||||
- Book-level batching (10 books per batch)
|
||||
- Delta transfer (only changed items)
|
||||
- Compression for large annotation sets
|
||||
|
||||
**Kobo Device Behavior:**
|
||||
- Device updates local database
|
||||
- Progress reflected in reading view
|
||||
- Annotations appear in Notebook
|
||||
- Bookmarks updated in navigation
|
||||
- Conflict warnings shown to user
|
||||
- Sync progress displayed on screen
|
||||
|
||||
**Performance:**
|
||||
- Small sync (1-10 books): 2-5 seconds
|
||||
- Medium sync (10-50 books): 5-15 seconds
|
||||
- Large sync (50-200 books): 15-45 seconds
|
||||
- Timeout: 120 seconds
|
||||
|
||||
**Use Cases:**
|
||||
- Initial device sync
|
||||
- After firmware update
|
||||
- From another device's changes
|
||||
- Manual sync request
|
||||
- Conflict recovery
|
||||
- Data restoration
|
||||
@@ -0,0 +1,91 @@
|
||||
info:
|
||||
name: Sync Multiple Books Progress
|
||||
type: http
|
||||
seq: 3
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/markup'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: x-kobo-device
|
||||
value: '{"DeviceId":"{{kobo_device_id}}","Model":"Kobo Aura"}'
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
ReadingSync:
|
||||
- ContentId: book-1-uuid
|
||||
PercentRead: 25.0
|
||||
EntitlementId: entitlement-1
|
||||
RemainingTimeMinutes: 240
|
||||
FirstReadTime: '2026-01-25T10:00:00Z'
|
||||
LastModified: '2026-01-30T18:00:00Z'
|
||||
- ContentId: book-2-uuid
|
||||
PercentRead: 78.5
|
||||
EntitlementId: entitlement-2
|
||||
RemainingTimeMinutes: 45
|
||||
FirstReadTime: '2026-01-25T14:00:00Z'
|
||||
LastModified: '2026-01-30T20:00:00Z'
|
||||
BookmarkSync: []
|
||||
|
||||
docs: |-
|
||||
## Sync Multiple Books Progress
|
||||
|
||||
Synchronizes reading progress for multiple books in a single request.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/markup
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Headers:**
|
||||
- `Authorization`: Bearer {{kobo_device_token}}
|
||||
- `x-kobo-device`: Device information (Model: "Kobo Aura")
|
||||
|
||||
**Request Body:**
|
||||
- `ReadingSync` (array): Multiple progress items
|
||||
- Each item contains: ContentId, PercentRead, EntitlementId, etc.
|
||||
- `BookmarkSync` (array): Empty for progress-only batch
|
||||
|
||||
**Response:**
|
||||
- `total` (integer): Total items in request
|
||||
- `synced` (integer): Successfully synced
|
||||
- `failed` (integer): Failed items
|
||||
- `results` (array): Per-item results
|
||||
- `ContentId` (string): Book UUID
|
||||
- `status` (string): `synced`, `failed`, `skipped`
|
||||
- `error` (string, optional): Error message if failed
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Batch sync completed
|
||||
- 207: Multi-status (some succeeded, some failed)
|
||||
- 401: Unauthorized
|
||||
- 413: Payload too large (>1MB)
|
||||
|
||||
**Batch Sync Advantages:**
|
||||
- Efficient sync of entire library
|
||||
- Reduces HTTP overhead
|
||||
- Faster for devices with many books
|
||||
- Atomic operation (all or nothing by default)
|
||||
|
||||
**Kobo Batch Sync Behavior:**
|
||||
- Triggered when device connects after being offline
|
||||
- Occurs during manual "Sync now" operation
|
||||
- Limited to 100 books per request
|
||||
- Progress updates shown on device
|
||||
- Failed items retried individually
|
||||
|
||||
**Performance:**
|
||||
- Typical batch: 10-50 books in 1-3 seconds
|
||||
- Large batch: 50-100 books in 3-8 seconds
|
||||
- Timeout: 30 seconds
|
||||
- Rate limit: 10 batches per minute per device
|
||||
|
||||
**Use Cases:**
|
||||
- Initial device sync after registration
|
||||
- Catch-up sync after extended offline period
|
||||
- Library-wide progress update
|
||||
- Pre-sync before device firmware update
|
||||
@@ -0,0 +1,84 @@
|
||||
info:
|
||||
name: Sync Progress with Bookmarks
|
||||
type: http
|
||||
seq: 2
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/markup'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: x-kobo-device
|
||||
value: '{"DeviceId":"{{kobo_device_id}}","Model":"Kobo Clara"}'
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
ReadingSync:
|
||||
- ContentId: book-uuid
|
||||
PercentRead: 42.3
|
||||
EntitlementId: entitlement-id
|
||||
RemainingTimeMinutes: 138
|
||||
FirstReadTime: '2026-01-25T10:00:00Z'
|
||||
LastModified: '2026-01-30T20:00:00Z'
|
||||
BookmarkSync:
|
||||
- ContentId: book-uuid
|
||||
BookmarkText: highlighted text passage
|
||||
BookmarkType: annotation
|
||||
BookmarkTitle: Chapter 3
|
||||
|
||||
docs: |-
|
||||
## Sync Progress with Bookmarks
|
||||
|
||||
Synchronizes reading progress and highlights/annotations from Kobo device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/markup
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Headers:**
|
||||
- `Authorization`: Bearer {{kobo_device_token}}
|
||||
- `x-kobo-device`: Device information JSON
|
||||
|
||||
**Request Body:**
|
||||
- `ReadingSync` (array): Progress items (see Sync Reading Progress)
|
||||
- `BookmarkSync` (array): Highlights and annotations
|
||||
- `ContentId` (string): Book UUID
|
||||
- `BookmarkText` (string): Highlighted text or note content
|
||||
- `BookmarkType` (string): Type of bookmark
|
||||
- `annotation`: Highlighted text
|
||||
- `note`: Personal note
|
||||
- `bookmark`: Location bookmark
|
||||
- `BookmarkTitle` (string): Reference (e.g., chapter name)
|
||||
- `ChapterID` (string, optional): Chapter identifier
|
||||
- `DateCreated` (string, optional): Creation timestamp
|
||||
|
||||
**Response:**
|
||||
- `progress_synced` (integer): Progress items synced
|
||||
- `bookmarks_synced` (integer): Bookmark items synced
|
||||
- `conflicts_resolved` (integer): Number of conflicts auto-resolved
|
||||
- `timestamp` (string): Sync timestamp
|
||||
- `details` (object): Sync breakdown by type
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Successful sync
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid data
|
||||
|
||||
**Kobo Highlight Features:**
|
||||
- 5 highlight colors (yellow, green, blue, pink, orange)
|
||||
- Chapter-based organization
|
||||
- Linked to reading progress
|
||||
- Appears in Kobo "Notebook" view
|
||||
- Can be exported from device
|
||||
- Syncs across all user devices
|
||||
|
||||
**Annotation Sync:**
|
||||
- Highlight text preserved exactly
|
||||
- Color mapped to system colors
|
||||
- Chapter reference maintained
|
||||
- Location data converted to standard format
|
||||
- Notes attached to highlights synced separately
|
||||
@@ -0,0 +1,84 @@
|
||||
info:
|
||||
name: Sync Reading Progress
|
||||
type: http
|
||||
seq: 1
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/markup'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: x-kobo-device
|
||||
value: '{"DeviceId":"{{kobo_device_id}}","Model":"Kobo Clara"}'
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
ReadingSync:
|
||||
- ContentId: book-uuid-here
|
||||
PercentRead: 45.6
|
||||
EntitlementId: entitlement-id-here
|
||||
RemainingTimeMinutes: 120
|
||||
FirstReadTime: '2026-01-25T10:00:00Z'
|
||||
LastModified: '2026-01-30T20:00:00Z'
|
||||
BookmarkSync: []
|
||||
|
||||
docs: |-
|
||||
## Sync Kobo Reading Progress
|
||||
|
||||
Synchronizes reading progress from a Kobo device to the server using Bearer token authentication.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/markup
|
||||
|
||||
**Authentication:** Bearer token (in Authorization header)
|
||||
|
||||
**Headers:**
|
||||
- `Authorization`: Bearer {{kobo_device_token}}
|
||||
- `x-kobo-device`: JSON-encoded device info
|
||||
- `DeviceId`: Kobo device identifier
|
||||
- `Model`: Device model (e.g., "Kobo Clara", "Kobo Libra", "Kobo Aura")
|
||||
|
||||
**Request Body:**
|
||||
- `ReadingSync` (array): Reading progress items
|
||||
- `ContentId` (string): Book/Content UUID
|
||||
- `PercentRead` (number): Reading progress 0-100
|
||||
- `EntitlementId` (string): Kobo entitlement ID
|
||||
- `RemainingTimeMinutes` (integer): Estimated reading time remaining
|
||||
- `FirstReadTime` (string): ISO 8601 timestamp when first opened
|
||||
- `LastModified` (string): ISO 8601 timestamp of last progress update
|
||||
- `BookmarkSync` (array): Empty array for progress-only sync
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Number of items synced
|
||||
- `failed` (integer): Number of items that failed to sync
|
||||
- `timestamp` (string): Server timestamp of sync
|
||||
- `books` (array): Synced book data
|
||||
- `ContentId` (string): Book UUID
|
||||
- `status` (string): `synced`, `failed`, `skipped`
|
||||
- `server_percent` (number): Server-side progress (for conflict detection)
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Sync successful
|
||||
- 401: Invalid device token
|
||||
- 403: Device not approved
|
||||
- 400: Invalid request format
|
||||
|
||||
**Authentication Methods:**
|
||||
This endpoint uses **Bearer token authentication** (token in Authorization header).
|
||||
Alternative: Use `/sync/kobo/{token}/markup` with token in URL path.
|
||||
|
||||
**Kobo Sync Features:**
|
||||
- Native Kobo sync protocol
|
||||
- Supports Kobo Clara, Libra, Aura, Forma, Sage, Elipsa
|
||||
- Progress percentage tracking
|
||||
- Reading time estimation
|
||||
- Cross-device synchronization
|
||||
- Automatic conflict resolution (most recent wins)
|
||||
|
||||
**Sync Frequency:**
|
||||
- Kobo devices auto-sync every 15-30 minutes when connected to WiFi
|
||||
- Manual sync available from device settings
|
||||
- Sync triggers on: device wake, book close, WiFi connection
|
||||
@@ -0,0 +1,92 @@
|
||||
info:
|
||||
name: Sync Single Bookmark
|
||||
type: http
|
||||
seq: 5
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/bookmark'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: x-kobo-device
|
||||
value: '{"DeviceId":"{{kobo_device_id}}","Model":"Kobo Clara"}'
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
ContentId: book-uuid
|
||||
BookmarkText: Bookmarked passage
|
||||
BookmarkType: annotation
|
||||
BookmarkTitle: Chapter 3
|
||||
|
||||
docs: |-
|
||||
## Sync Single Bookmark
|
||||
|
||||
Synchronizes an individual bookmark/highlight from Kobo device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/bookmark
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Headers:**
|
||||
- `Authorization`: Bearer {{kobo_device_token}}
|
||||
- `x-kobo-device`: Device information JSON
|
||||
|
||||
**Request Body:**
|
||||
- `ContentId` (string): Book UUID
|
||||
- `BookmarkText` (string): Highlighted text or bookmark description
|
||||
- `BookmarkType` (string): Type of bookmark
|
||||
- `annotation`: Highlighted text passage
|
||||
- `note`: Personal note
|
||||
- `bookmark`: Location marker
|
||||
- `BookmarkTitle` (string): Reference title (e.g., chapter name)
|
||||
- `ChapterID` (string, optional): Chapter identifier
|
||||
- `DateCreated` (string, optional): ISO 8601 timestamp
|
||||
- `highlight_color` (string, optional): Color name (yellow, green, blue, pink, orange)
|
||||
|
||||
**Response:**
|
||||
- `id` (string): Server bookmark ID
|
||||
- `ContentId` (string): Associated book UUID
|
||||
- `status` (string): `created`, `updated`, `skipped` (duplicate)
|
||||
- `timestamp` (string): Server timestamp
|
||||
- `url` (string): API URL to retrieve bookmark
|
||||
|
||||
**Status Codes:**
|
||||
- 201: Bookmark created
|
||||
- 200: Bookmark updated (duplicate found)
|
||||
- 409: Duplicate bookmark (unchanged)
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid bookmark data
|
||||
|
||||
**Single Bookmark Sync vs Batch:**
|
||||
- **Single bookmark endpoint:** Real-time, immediate sync
|
||||
- **Batch markup endpoint:** Deferred, periodic sync
|
||||
- Use single when user explicitly creates highlight
|
||||
- Use batch for periodic background sync
|
||||
|
||||
**Kobo Trigger:**
|
||||
- User highlights text → immediate single sync
|
||||
- User adds note → immediate single sync
|
||||
- Device goes online → batch sync of all changes
|
||||
|
||||
**Duplicate Detection:**
|
||||
- Same ContentId + similar BookmarkText + same location
|
||||
- Updates existing if text modified
|
||||
- Skips if identical bookmark exists
|
||||
- Preserves creation date of original
|
||||
|
||||
**Use Cases:**
|
||||
- Real-time highlight sync
|
||||
- Instant note backup
|
||||
- Immediate annotation sharing
|
||||
- Quick single annotation update
|
||||
- Testing annotation sync
|
||||
|
||||
**Notes:**
|
||||
- Much faster than full markup sync
|
||||
- Lower bandwidth usage
|
||||
- Ideal for intermittent connectivity
|
||||
- Can be called multiple times safely
|
||||
@@ -0,0 +1,106 @@
|
||||
info:
|
||||
name: Sync with Annotations
|
||||
type: http
|
||||
seq: 4
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/kobo/markup'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
- key: x-kobo-device
|
||||
value: '{"DeviceId":"{{kobo_device_id}}","Model":"Kobo Libra"}'
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
ReadingSync:
|
||||
- ContentId: book-uuid
|
||||
PercentRead: 55.0
|
||||
EntitlementId: entitlement-id
|
||||
RemainingTimeMinutes: 120
|
||||
FirstReadTime: '2026-01-25T10:00:00Z'
|
||||
LastModified: '2026-01-30T20:00:00Z'
|
||||
BookmarkSync:
|
||||
- ContentId: book-uuid
|
||||
BookmarkText: Important quote
|
||||
BookmarkType: annotation
|
||||
BookmarkTitle: Chapter 4 - The Truth
|
||||
- ContentId: book-uuid
|
||||
BookmarkText: Another quote
|
||||
BookmarkType: annotation
|
||||
BookmarkTitle: Chapter 5
|
||||
- ContentId: book-uuid
|
||||
BookmarkText: Note to myself
|
||||
BookmarkType: note
|
||||
BookmarkTitle: Personal note
|
||||
|
||||
docs: |-
|
||||
## Sync with Multiple Annotations
|
||||
|
||||
Synchronizes reading progress with multiple highlights and notes.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/kobo/markup
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Headers:**
|
||||
- `Authorization`: Bearer {{kobo_device_token}}
|
||||
- `x-kobo-device`: Device info (Model: "Kobo Libra")
|
||||
|
||||
**Request Body:**
|
||||
- `ReadingSync` (array): Single book progress
|
||||
- `BookmarkSync` (array): Multiple annotations
|
||||
- Can include highlights (annotation type)
|
||||
- Can include notes (note type)
|
||||
- Each has: ContentId, BookmarkText, BookmarkType, BookmarkTitle
|
||||
|
||||
**Response:**
|
||||
- `progress_synced` (boolean): Progress update status
|
||||
- `annotations_synced` (integer): Number of annotations synced
|
||||
- `highlights_count` (integer): Highlights synced
|
||||
- `notes_count` (integer): Notes synced
|
||||
- `conflicts` (array): Any annotation conflicts resolved
|
||||
- `timestamp` (string): Sync completion time
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Successful sync
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid annotation data
|
||||
|
||||
**Kobo Annotation Types:**
|
||||
- **Highlights:** Selected text passages
|
||||
- 5 preset colors available
|
||||
- Can have chapter titles
|
||||
- Exportable to PDF/Mobile
|
||||
- **Notes:** Personal annotations
|
||||
- Free-form text
|
||||
- Can be attached to highlights
|
||||
- Separate from highlights
|
||||
- **Bookmarks:** Location markers
|
||||
- Chapter positions
|
||||
- Quick navigation
|
||||
|
||||
**Sync Behavior:**
|
||||
- Duplicates detected by content matching
|
||||
- Most recent edit wins conflicts
|
||||
- Annotations linked to book content
|
||||
- Chapter references preserved
|
||||
- Order maintained from device
|
||||
|
||||
**Kobo Notebook Export:**
|
||||
- All annotations appear in Kobo "Notebook"
|
||||
- Can be exported to PDF
|
||||
- Can be exported to Mobile (text)
|
||||
- Organized by book
|
||||
- Shows highlight context
|
||||
|
||||
**Use Cases:**
|
||||
- Study and research
|
||||
- Book club discussion prep
|
||||
- Content review
|
||||
- Sharing insights
|
||||
- Personal learning archive
|
||||
@@ -0,0 +1,45 @@
|
||||
info:
|
||||
name: Kobo Bookmark Sync
|
||||
type: http
|
||||
seq: 3
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/kobo/bookmark'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"BookmarkSync\": [\n {\n \"BookmarkId\": \"bookmark_2\"\
|
||||
,\n \"ContentId\": \"kobo_xyz789\",\n \"BookmarkText\": \"Important\
|
||||
\ note\",\n \"BookmarkType\": \"bookmark\",\n \"DateCreated\"\
|
||||
: \"2026-01-31T12:00:00Z\""
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{device_token
|
||||
|
||||
docs: |-
|
||||
## Kobo Bookmark Sync
|
||||
|
||||
Synchronizes bookmarks from a Kobo device to the Bookhoard server.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/kobo/bookmark
|
||||
|
||||
**Authentication:** Bearer token (device token)
|
||||
|
||||
**Request Body:**
|
||||
- `BookmarkSync` (array): Array of bookmark objects
|
||||
- `BookmarkId` (string): Unique bookmark ID
|
||||
- `ContentId` (string): Book/content ID
|
||||
- `BookmarkText` (string): Bookmark text or note
|
||||
- `BookmarkType` (string): Type (bookmark, highlight, note)
|
||||
- `DateCreated` (string): ISO 8601 timestamp
|
||||
|
||||
**Response:**
|
||||
- `Status` (string): Sync status (Success, Partial)
|
||||
- `BookmarksSynced` (number): Number of bookmarks synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,19 @@
|
||||
info:
|
||||
name: Kobo Initialization - URL Path Token
|
||||
type: http
|
||||
seq: 4
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/v1/initialization'
|
||||
auth: none
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Kobo Initialization - URL Path Token
|
||||
|
||||
Returns initialization data for Kobo device using token in URL path.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /sync/kobo/{kobo_device_token
|
||||
@@ -0,0 +1,19 @@
|
||||
info:
|
||||
name: Get Library - URL Path Token
|
||||
type: http
|
||||
seq: 3
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/library'
|
||||
auth: none
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Get Kobo Library - URL Path Token
|
||||
|
||||
Retrieves library metadata for Kobo device using token in URL path.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /sync/kobo/{kobo_device_token
|
||||
@@ -0,0 +1,39 @@
|
||||
info:
|
||||
name: Get Unlinked Books - User View
|
||||
type: http
|
||||
seq: 4
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/unlinked-books'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{user_token
|
||||
|
||||
docs: |-
|
||||
## Get Unlinked Books - User View
|
||||
|
||||
Retrieves all unlinked books for the authenticated user that need manual linking.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/unlinked-books
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Response:**
|
||||
- `unlinked` (array): Array of unlinked book objects
|
||||
- `id` (string): Unlinked book UUID
|
||||
- `title` (string): Book title
|
||||
- `author` (string): Book author
|
||||
- `device_id` (string): Source device ID
|
||||
- `device_name` (string): Source device name
|
||||
- `detected_at` (string): Detection timestamp
|
||||
- `total` (number): Total count of unlinked books
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,34 @@
|
||||
info:
|
||||
name: Kobo Initialization
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/v1/kobo/initialization'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{device_token
|
||||
|
||||
docs: |-
|
||||
## Kobo Initialization
|
||||
|
||||
Initializes Kobo device sync, returning device resources and account information.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/v1/kobo/initialization
|
||||
|
||||
**Authentication:** Bearer token (device token)
|
||||
|
||||
**Response:**
|
||||
- `ContentId` (string): Device content ID
|
||||
- `Categories` (array): Available categories/collections
|
||||
- `BookhoardUUID` (string): Bookhoard instance UUID
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,43 @@
|
||||
info:
|
||||
name: Link Unlinked Book - Manual Resolution
|
||||
type: http
|
||||
seq: 5
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/link-book'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"unlinked_book_id\": \"{{unlinked_book_id"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{user_token
|
||||
|
||||
docs: |-
|
||||
## Link Unlinked Book - Manual Resolution
|
||||
|
||||
Manually links an unlinked book to a media item in the library.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/link-book
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `unlinked_book_id` (string): Unlinked book UUID
|
||||
- `media_item_id` (string): Media item UUID to link to
|
||||
- `confidence_score` (number): Match confidence (0-1, 1.0 for manual)
|
||||
|
||||
**Response:**
|
||||
- `status` (string): Link status (linked)
|
||||
- `unlinked_book_id` (string): Unlinked book UUID
|
||||
- `media_item_id` (string): Media item UUID
|
||||
- `message` (string): Success message
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success - book linked
|
||||
- 400: Invalid request
|
||||
- 401: Unauthorized
|
||||
- 404: Book or media item not found
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,52 @@
|
||||
info:
|
||||
name: Kobo Markup Sync
|
||||
type: http
|
||||
seq: 2
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/kobo/markup'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"ReadingSync\": [\n {\n \"ContentId\": \"kobo_abc123def456\"\
|
||||
,\n \"PercentRead\": 60.0,\n \"RemainingTimeMin\": 120,\n \
|
||||
\ \"ReadingEvent\": \"BookRead\",\n \"LastModified\": \"2026-01-31T12:00:00Z\""
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{device_token
|
||||
|
||||
docs: |-
|
||||
## Kobo Markup Sync
|
||||
|
||||
Synchronizes reading progress and markup (highlights, bookmarks) from a Kobo device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/kobo/markup
|
||||
|
||||
**Authentication:** Bearer token (device token)
|
||||
|
||||
**Request Body:**
|
||||
- `ReadingSync` (array, optional): Reading progress data
|
||||
- `ContentId` (string): Book/content ID
|
||||
- `PercentRead` (number): Percentage read (0-100)
|
||||
- `RemainingTimeMin` (number): Remaining time in minutes
|
||||
- `ReadingEvent` (string): Event type (BookRead, etc.)
|
||||
- `LastModified` (string): ISO 8601 timestamp
|
||||
- `BookmarkSync` (array, optional): Bookmark/highlight data
|
||||
- `BookmarkId` (string): Unique bookmark ID
|
||||
- `ContentId` (string): Book/content ID
|
||||
- `BookmarkText` (string): Highlighted/bookmarked text
|
||||
- `BookmarkType` (string): Type (annotation, bookmark)
|
||||
- `DateCreated` (string): ISO 8601 timestamp
|
||||
- `Metadata` (boolean): Whether to include metadata
|
||||
|
||||
**Response:**
|
||||
- `Status` (string): Sync status (Success, Partial)
|
||||
- `MarkupsSynced` (number): Number of markups synced
|
||||
- `BookmarksSynced` (number): Number of bookmarks synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,25 @@
|
||||
info:
|
||||
name: Sync Bookmark - URL Path Token
|
||||
type: http
|
||||
seq: 2
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/bookmark'
|
||||
auth: none
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"ContentId\": \"book-uuid\",\n \"BookmarkText\": \"Highlighted\
|
||||
\ text\",\n \"BookmarkType\": \"annotation\",\n \"BookmarkTitle\": \"\
|
||||
Chapter 3\""
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
|
||||
docs: |-
|
||||
## Sync Bookmark - URL Path Token
|
||||
|
||||
Synchronizes bookmarks and annotations from Kobo device using token in URL path.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /sync/kobo/{kobo_device_token
|
||||
@@ -0,0 +1,26 @@
|
||||
info:
|
||||
name: Sync Markup - URL Path Token
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/markup'
|
||||
auth: none
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"ReadingSync\": [\n {\n \"ContentId\": \"book-uuid\"\
|
||||
,\n \"PercentRead\": 45.6,\n \"EntitlementId\": \"entitlement-id\"\
|
||||
,\n \"RemainingTimeMinutes\": 120,\n \"FirstReadTime\": \"2026-01-25T10:00:00Z\"\
|
||||
,\n \"LastModified\": \"2026-01-30T20:00:00Z\""
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
|
||||
docs: |-
|
||||
## Sync Reading Progress - URL Path Token
|
||||
|
||||
Synchronizes reading progress from Kobo device using token in URL path.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /sync/kobo/{kobo_device_token
|
||||
@@ -0,0 +1,92 @@
|
||||
info:
|
||||
name: Get Book Metadata
|
||||
type: http
|
||||
seq: 8
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/koreader/metadata/{{book_uuid}}'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Get KOReader Book Metadata
|
||||
|
||||
Retrieves metadata for a specific book from the server.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/koreader/metadata/:book_uuid
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Path Parameters:**
|
||||
- `book_uuid` (string): SHA-256 based book identifier
|
||||
|
||||
**Response:**
|
||||
- `uuid` (string): Book UUID (SHA-256)
|
||||
- `title` (string): Book title
|
||||
- `authors` (array): Author names
|
||||
- `series` (string, optional): Series name
|
||||
- `series_index` (number, optional): Position in series
|
||||
- `publisher` (string, optional): Publisher name
|
||||
- `publication_date` (string, optional): Release date
|
||||
- `language` (string, optional): ISO 639-1 language code
|
||||
- `description` (string, optional): Book description
|
||||
- `cover_url` (string, optional): Cover image URL
|
||||
- `cover_thumbnail_url` (string, optional): Thumbnail URL
|
||||
- `identifiers` (object): Various identifiers
|
||||
- `isbn` (string, optional): ISBN-13
|
||||
- `asin` (string, optional): Amazon ASIN
|
||||
- `goodreads` (string, optional): Goodreads ID
|
||||
- `google_books` (string, optional): Google Books ID
|
||||
- `metadata_sources` (array): Sources metadata was pulled from
|
||||
- `last_synced` (string): Last metadata sync timestamp
|
||||
- `file_metadata` (object):
|
||||
- `file_size` (integer): File size in bytes
|
||||
- `format` (string): File format (epub, pdf, mobi, etc.)
|
||||
- `pages` (integer, optional): Page count
|
||||
- `word_count` (integer, optional): Estimated words
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 404: Book not found
|
||||
|
||||
**Metadata Purpose:**
|
||||
- Enrich book information on device
|
||||
- Improve book organization
|
||||
- Enable better search
|
||||
- Support series sorting
|
||||
- Provide cover images
|
||||
- Link to external sources
|
||||
|
||||
**KOReader Usage:**
|
||||
- Display in book info dialog
|
||||
- Used for library sorting
|
||||
- Shown in file browser
|
||||
- Series grouping
|
||||
- Cover display
|
||||
- Search optimization
|
||||
|
||||
**SHA-256 Book ID:**
|
||||
- Primary identifier in KOReader
|
||||
- Universal across devices
|
||||
- Format-independent
|
||||
- Generated from file content
|
||||
- Survives metadata changes
|
||||
|
||||
**Metadata Sources:**
|
||||
- Google Books API
|
||||
- Open Library
|
||||
- Goodreads API
|
||||
- ISBN database lookup
|
||||
- Publisher metadata
|
||||
- User-provided metadata
|
||||
|
||||
**Use Cases:**
|
||||
- Initial book import
|
||||
- Metadata refresh
|
||||
- Cover image download
|
||||
- Series organization
|
||||
- Duplicate detection
|
||||
- Library management
|
||||
@@ -0,0 +1,34 @@
|
||||
info:
|
||||
name: KOReader Get Library
|
||||
type: http
|
||||
seq: 3
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/koreader/library'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Get Library
|
||||
|
||||
Retrieves the user's library for KOReader sync operations.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/koreader/library
|
||||
|
||||
**Authentication:** Bearer token (device token)
|
||||
|
||||
**Response:**
|
||||
- `library_sync` (object): Library sync data
|
||||
- `total_books` (number): Total number of books
|
||||
- `books` (array): Array of book objects
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,103 @@
|
||||
info:
|
||||
name: Get User Library for KOReader
|
||||
type: http
|
||||
seq: 9
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/sync/koreader/library'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Get KOReader User Library
|
||||
|
||||
Retrieves the user's book library for KOReader device sync.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/sync/koreader/library
|
||||
|
||||
**Authentication:** Bearer token (koreader_device_token)
|
||||
|
||||
**Query Parameters:**
|
||||
None (returns entire library)
|
||||
|
||||
**Response:**
|
||||
- `books` (array): Library items
|
||||
- `uuid` (string): SHA-256 based book identifier
|
||||
- `title` (string): Book title
|
||||
- `authors` (array): Author names
|
||||
- `series` (string, optional): Series name
|
||||
- `series_index` (number, optional): Series position
|
||||
- `publisher` (string, optional): Publisher
|
||||
- `publication_date` (string, optional): Release date
|
||||
- `language` (string, optional): Language code
|
||||
- `description` (string, optional): Description
|
||||
- `cover_url` (string, optional): Cover image URL
|
||||
- `cover_thumbnail_url` (string, optional): Thumbnail URL
|
||||
- `file_metadata` (object):
|
||||
- `format` (string): File format
|
||||
- `file_size` (integer): Size in bytes
|
||||
- `pages` (integer, optional): Page count
|
||||
- `progress` (object, optional): Reading progress
|
||||
- `percentage` (number): Progress 0-100
|
||||
- `last_read` (string): Last read timestamp
|
||||
- `epubcfi` (string): Current position
|
||||
- `annotations_count` (object, optional): Annotation stats
|
||||
- `highlights` (integer): Highlight count
|
||||
- `notes` (integer): Note count
|
||||
- `bookmarks` (integer): Bookmark count
|
||||
- `library_info` (object):
|
||||
- `total_books` (integer): Total book count
|
||||
- `last_sync` (string): Last library sync timestamp
|
||||
- `has_updates` (boolean): Updates available
|
||||
- `user_info` (object):
|
||||
- `user_id` (string): User identifier
|
||||
- `email` (string): Email (masked)
|
||||
- `libraries` (array): Available library IDs
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 403: Device not approved
|
||||
|
||||
**Library Purpose for KOReader:**
|
||||
- Discover books available for download
|
||||
- Browse catalog on device
|
||||
- Sync reading progress across books
|
||||
- Download covers/metadata
|
||||
- Series-based organization
|
||||
- Cloud library access
|
||||
|
||||
**KOReader Device Features:**
|
||||
- **OPDS catalog**: Native OPDS client
|
||||
- **File browser**: See server books
|
||||
- **Cloud download**: Download books on-demand
|
||||
- **Metadata sync**: Automatic metadata fetching
|
||||
- **Cover images**: Display in library view
|
||||
- **Progress sync**: See progress across all books
|
||||
- **Search**: Search library by title/author
|
||||
|
||||
**KOReader-Specific Features:**
|
||||
- SHA-256 based book IDs
|
||||
- Multi-format support (EPUB, FB2, PDF, DJVU, MOBI, etc.)
|
||||
- Series sorting and grouping
|
||||
- Language filtering
|
||||
- Cover image caching
|
||||
- Metadata for file browser enhancement
|
||||
- Integration with KOReader's OPDS client
|
||||
|
||||
**Performance:**
|
||||
- Typical response: 100-500KB for 100 books
|
||||
- Processing time: 300ms-1s
|
||||
- Cache duration: 5 minutes
|
||||
- Pagination support for libraries >500 books
|
||||
|
||||
**Use Cases:**
|
||||
- Initial device setup
|
||||
- Library browsing on device
|
||||
- Book download
|
||||
- Metadata refresh
|
||||
- Cover image sync
|
||||
- Progress overview
|
||||
- Series-based reading
|
||||
@@ -0,0 +1,7 @@
|
||||
info:
|
||||
name: Bookhoard KOReader Sync API
|
||||
type: collection
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '"http://localhost:8765/api"'
|
||||
@@ -0,0 +1,123 @@
|
||||
info:
|
||||
name: Checkpoint Sync
|
||||
type: http
|
||||
seq: 11
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
sync_mode: checkpoint
|
||||
checkpoint_id: checkpoint-uuid
|
||||
since_timestamp: '2026-01-30T19:00:00Z'
|
||||
books:
|
||||
- uuid: book-uuid-1
|
||||
percentage: 0.45
|
||||
chapter: 3
|
||||
- uuid: book-uuid-2
|
||||
percentage: 0.75
|
||||
chapter: 8
|
||||
|
||||
docs: |-
|
||||
## Checkpoint Sync
|
||||
|
||||
Incremental sync using checkpoint-based change tracking.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `sync_mode` (string): Must be `checkpoint`
|
||||
- `checkpoint_id` (string): Unique checkpoint identifier
|
||||
- `since_timestamp` (string): ISO 8601 timestamp for incremental sync
|
||||
- `books` (array): Book progress items
|
||||
- `uuid` (string): Book UUID
|
||||
- `percentage` (number): Progress 0.0-1.0
|
||||
- `chapter` (integer): Current chapter
|
||||
- `epubcfi` (string, optional): Current position
|
||||
- `modified_since` (boolean, optional): Whether modified since checkpoint
|
||||
|
||||
**Response:**
|
||||
- `checkpoint_id` (string): Server checkpoint ID
|
||||
- `checkpoint_timestamp` (string): Checkpoint creation time
|
||||
- `processed` (integer): Books processed
|
||||
- `changes_only` (boolean): Whether only changed items synced
|
||||
- `next_checkpoint_id` (string): ID for next checkpoint sync
|
||||
- `results` (array): Per-book results
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Checkpoint sync completed
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid checkpoint or timestamp
|
||||
|
||||
**Checkpoint Sync Benefits:**
|
||||
- **Incremental**: Only sync changed items
|
||||
- **Efficient**: Smaller payloads
|
||||
- **Fast**: Reduced processing time
|
||||
- **Reliable**: Checkpoint-based tracking
|
||||
- **Resumable**: Can continue from last checkpoint
|
||||
|
||||
**Checkpoint Mechanism:**
|
||||
- Server tracks changes since checkpoint
|
||||
- Client provides checkpoint ID or timestamp
|
||||
- Only modified books returned/processed
|
||||
- Checkpoint ID advances on each sync
|
||||
- Supports large libraries efficiently
|
||||
|
||||
**Use Cases:**
|
||||
- Large libraries (100+ books)
|
||||
- Intermittent connectivity
|
||||
- Bandwidth optimization
|
||||
- Battery conservation
|
||||
- Background sync
|
||||
- Periodic sync (every 5-15 minutes)
|
||||
|
||||
**Checkpoint Lifecycle:**
|
||||
1. Initial sync: No checkpoint (full sync)
|
||||
2. Server returns checkpoint_id
|
||||
3. Next sync: Client sends checkpoint_id
|
||||
4. Server processes only changes
|
||||
5. New checkpoint_id returned
|
||||
6. Repeat from step 3
|
||||
|
||||
**Sync Optimization:**
|
||||
- Only books with progress changes
|
||||
- Skips unmodified books
|
||||
- Delta transfer
|
||||
- Compression for large payloads
|
||||
- Batch processing
|
||||
|
||||
**Failure Handling:**
|
||||
- Checkpoint ID preserved on failure
|
||||
- Retry with same checkpoint
|
||||
- Full sync if checkpoint expired
|
||||
- Checkpoint validity: 24 hours
|
||||
- Auto-fallback to full sync
|
||||
|
||||
**Performance:**
|
||||
- Small changes (1-10 books): 100-300ms
|
||||
- Medium changes (10-50 books): 300ms-1s
|
||||
- Large changes (50-100 books): 1-3s
|
||||
- Typical: 5-10x faster than full sync
|
||||
|
||||
**When to Use:**
|
||||
- Default sync mode for most users
|
||||
- Periodic background sync
|
||||
- Large library management
|
||||
- Mobile/network-constrained environments
|
||||
- Battery-powered devices
|
||||
|
||||
**Configuration:**
|
||||
- Checkpoint expiration: 24 hours
|
||||
- Max history: 100 checkpoints
|
||||
- Auto-cleanup of old checkpoints
|
||||
- Configurable sync interval
|
||||
@@ -0,0 +1,105 @@
|
||||
info:
|
||||
name: Immediate Sync - Page Turn
|
||||
type: http
|
||||
seq: 10
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
sync_mode: immediate
|
||||
books:
|
||||
- uuid: book-uuid
|
||||
percentage: 0.45678
|
||||
chapter: 3
|
||||
timestamp: '2026-01-30T20:00:00Z'
|
||||
|
||||
docs: |-
|
||||
## Immediate Sync - Page Turn
|
||||
|
||||
Real-time progress sync triggered immediately on page turn.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `sync_mode` (string): Must be `immediate`
|
||||
- `books` (array): Current book progress
|
||||
- `uuid` (string): Book UUID
|
||||
- `percentage` (number): Precise progress (0.45678 = 45.678%)
|
||||
- `chapter` (integer): Current chapter
|
||||
- `timestamp` (string): ISO 8601 timestamp
|
||||
- `epubcfi` (string, optional): Current position
|
||||
- `page` (integer, optional): Current page
|
||||
|
||||
**Response:**
|
||||
- `synced` (boolean): Immediate sync status
|
||||
- `timestamp` (string): Server timestamp
|
||||
- `next_sync_suggested` (string): Suggested next sync time
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Sync queued
|
||||
- 202: Accepted for processing
|
||||
- 401: Unauthorized
|
||||
- 429: Too many immediate sync requests (rate limited)
|
||||
|
||||
**Immediate Sync Mode:**
|
||||
- **Purpose**: Real-time progress updates
|
||||
- **Trigger**: Every page turn (configurable)
|
||||
- **Priority**: High priority processing
|
||||
- **Latency**: <100ms typical
|
||||
- **Best effort**: May be queued under load
|
||||
|
||||
**Rate Limiting:**
|
||||
- Max 60 requests per minute per device
|
||||
- Throttled after limit reached
|
||||
- Suggests switching to periodic sync
|
||||
- Prevents server overload
|
||||
|
||||
**Use Cases:**
|
||||
- Real-time multi-device reading
|
||||
- Live progress sharing
|
||||
- Instant position backup
|
||||
- Critical reading points
|
||||
- Test/profiling mode
|
||||
|
||||
**Performance:**
|
||||
- Ultra-fast sync
|
||||
- Minimal payload
|
||||
- Optimized for speed
|
||||
- Async processing
|
||||
- No confirmation wait
|
||||
|
||||
**Battery Considerations:**
|
||||
- More frequent network use
|
||||
- Higher battery consumption
|
||||
- WiFi recommended
|
||||
- Can reduce sync frequency in settings
|
||||
|
||||
**Configuration:**
|
||||
- Can enable/disable per device
|
||||
- Adjustable frequency (every page, every N pages)
|
||||
- Automatic fallback to periodic sync on error
|
||||
- Respects device power-save mode
|
||||
|
||||
**When to Use:**
|
||||
- Critical reading sessions
|
||||
- Multi-device concurrent reading
|
||||
- Research and study
|
||||
- Testing sync functionality
|
||||
- When power source available
|
||||
|
||||
**When NOT to Use:**
|
||||
- Battery conservation needed
|
||||
- Unstable network
|
||||
- Extended reading sessions
|
||||
- Background sync preferred
|
||||
@@ -0,0 +1,44 @@
|
||||
info:
|
||||
name: KOReader Sync Annotations - Per-Book SHA-256
|
||||
type: http
|
||||
seq: 4
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/koreader/sync/bookmarks'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"book_uuid\": \"{{book_uuid"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{koreader_device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Sync Annotations - Per-Book SHA-256
|
||||
|
||||
Synchronizes annotations (highlights) from KOReader with per-annotation SHA-256 hashes for multi-book sync.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/koreader/sync/bookmarks
|
||||
|
||||
**Authentication:** Bearer token (KOReader device token)
|
||||
|
||||
**Request Body:**
|
||||
- `book_uuid` (string): Primary book UUID
|
||||
- `highlights` (array): Array of highlight objects
|
||||
- `text` (string): Highlighted text
|
||||
- `pos0`, `pos1` (string): EPUB CFI positions
|
||||
- `color` (string): Highlight color (hex)
|
||||
- `page` (number): Page number
|
||||
- `book_sha256` (string): SHA-256 hash for this specific book
|
||||
|
||||
**Response:**
|
||||
- `highlights_synced` (number): Number of highlights synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
|
||||
**Note:** Each highlight can include its own book_sha256, allowing annotations from multiple books in a single request.
|
||||
@@ -0,0 +1,40 @@
|
||||
info:
|
||||
name: KOReader Sync Bookmarks - SHA-256
|
||||
type: http
|
||||
seq: 3
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/koreader/sync/bookmarks'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"book_sha256\": \"{{book_sha256"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{koreader_device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Sync Bookmarks - SHA-256
|
||||
|
||||
Synchronizes bookmarks, notes, and highlights from KOReader using SHA-256 hash for book identification.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/koreader/sync/bookmarks
|
||||
|
||||
**Authentication:** Bearer token (KOReader device token)
|
||||
|
||||
**Request Body:**
|
||||
- `book_sha256` (string): SHA-256 hash of book file
|
||||
- `bookmarks` (array): Array of bookmarks
|
||||
- `notes` (array): Array of notes
|
||||
- `highlights` (array): Array of highlights
|
||||
|
||||
**Response:**
|
||||
- `sync_status` (string): Sync status
|
||||
- `total_synced` (number): Total items synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,105 @@
|
||||
info:
|
||||
name: Sync Bookmarks
|
||||
type: http
|
||||
seq: 5
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/bookmarks'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid
|
||||
bookmarks:
|
||||
- chapter: 3
|
||||
datetime: '2026-01-30T19:55:00Z'
|
||||
notes: Marked this chapter as important
|
||||
pos0: 'epubcfi(/6/4/2:15)'
|
||||
pos1: 'epubcfi(/6/4/2:20)'
|
||||
page: 45
|
||||
text: Important passage
|
||||
type: bookmark
|
||||
|
||||
docs: |-
|
||||
## Sync KOReader Bookmarks
|
||||
|
||||
Synchronizes bookmarks separately from progress for KOReader.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/bookmarks
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Books with bookmarks
|
||||
- `uuid` (string): Book UUID
|
||||
- `bookmarks` (array): Bookmark items
|
||||
- `chapter` (integer): Chapter number
|
||||
- `datetime` (string): ISO 8601 timestamp
|
||||
- `notes` (string): Bookmark description
|
||||
- `pos0` (string): EPUB CFI start position
|
||||
- `pos1` (string): EPUB CFI end position
|
||||
- `page` (integer): Page number
|
||||
- `text` (string): Displayed text
|
||||
- `type` (string): `bookmark`, `highlight`, or `note`
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Number of bookmarks synced
|
||||
- `duplicates_skipped` (integer): Duplicate bookmarks skipped
|
||||
- `results` (array): Per-bookmark results
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid data
|
||||
|
||||
**Dedicated Bookmark Endpoint:**
|
||||
- **Purpose**: Sync bookmarks independently
|
||||
- **Use case**: More frequent bookmark updates
|
||||
- **Advantage**: Separate from progress sync
|
||||
- **Efficiency**: Smaller payloads
|
||||
|
||||
**KOReader Bookmark Features:**
|
||||
- Chapter-based organization
|
||||
- Quick navigation markers
|
||||
- Hierarchical bookmarks (via plugins)
|
||||
- Custom bookmark titles
|
||||
- Date/time tracking
|
||||
- EPUB CFI precision
|
||||
|
||||
**Bookmark Types in KOReader:**
|
||||
- **Location bookmarks**: Quick navigation points
|
||||
- **Chapter marks**: Auto-generated chapter markers
|
||||
- **Progress bookmarks**: Last read positions
|
||||
- **Custom bookmarks**: User-created markers
|
||||
- **Search bookmarks**: Saved search results
|
||||
|
||||
**Sync Behavior:**
|
||||
- Duplicate detection by position + text
|
||||
- Most recent wins on conflicts
|
||||
- Chapter order preserved
|
||||
- Auto-generated vs manual bookmarks differentiated
|
||||
- Merge with existing bookmarks
|
||||
|
||||
**KOReader Device Integration:**
|
||||
- Created via "Add bookmark" menu
|
||||
- Shown in "Bookmarks" panel
|
||||
- Quick access via "Go to bookmark"
|
||||
- Exportable to JSON
|
||||
- Can be edited/deleted
|
||||
|
||||
**Use Cases:**
|
||||
- Quick navigation aids
|
||||
- Chapter markers
|
||||
- Important passages
|
||||
- Reading progress points
|
||||
- Study session markers
|
||||
@@ -0,0 +1,110 @@
|
||||
info:
|
||||
name: Sync Highlights
|
||||
type: http
|
||||
seq: 6
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/highlights'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid
|
||||
highlights:
|
||||
- datetime: '2026-01-30T19:50:00Z'
|
||||
text: Important quote from book
|
||||
chapter: 4
|
||||
pos0: 'epubcfi(/6/4/2:20)'
|
||||
pos1: 'epubcfi(/6/4/2:30)'
|
||||
page_start: 78
|
||||
page_end: 79
|
||||
|
||||
docs: |-
|
||||
## Sync KOReader Highlights
|
||||
|
||||
Synchronizes text highlights separately from other annotations.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/highlights
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Books with highlights
|
||||
- `uuid` (string): Book UUID
|
||||
- `highlights` (array): Highlight items
|
||||
- `datetime` (string): Creation timestamp
|
||||
- `text` (string): Highlighted text content
|
||||
- `chapter` (integer): Chapter number
|
||||
- `pos0` (string): EPUB CFI start position
|
||||
- `pos1` (string): EPUB CFI end position
|
||||
- `page_start` (integer): Start page
|
||||
- `page_end` (integer): End page
|
||||
- `color` (string, optional): Color name or hex
|
||||
- `note` (string, optional): Attached note
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Highlights synced
|
||||
- `duplicates_skipped` (integer): Duplicates found
|
||||
- `with_notes` (integer): Highlights that have notes attached
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**KOReader Highlight Features:**
|
||||
- Precise text selection (EPUB CFI)
|
||||
- Custom color support (via plugins)
|
||||
- Multi-page highlights
|
||||
- Chapter references
|
||||
- Timestamps for sorting
|
||||
- Attached notes support
|
||||
- Full text preservation
|
||||
|
||||
**Highlight Colors (via plugins):**
|
||||
- Yellow (default): General highlighting
|
||||
- Green: Important concepts
|
||||
- Blue: Key information
|
||||
- Red/pink: Critical content
|
||||
- Orange: Interesting quotes
|
||||
- Custom RGB colors available
|
||||
|
||||
**EPUB CFI Advantages:**
|
||||
- Precise start/end positions
|
||||
- Works across font size changes
|
||||
- Survives text reflow
|
||||
- Device-independent
|
||||
- Standardized format
|
||||
|
||||
**Dedicated Highlight Endpoint:**
|
||||
- **Separate from progress**: Sync highlights independently
|
||||
- **Smaller payload**: Just highlights, no progress
|
||||
- **More frequent**: Can sync highlights immediately
|
||||
- **Focused**: Single-purpose endpoint
|
||||
|
||||
**Sync Behavior:**
|
||||
- Exact text matching for duplicates
|
||||
- Position-based conflict resolution
|
||||
- Color preservation across devices
|
||||
- Note attachments preserved
|
||||
- Order maintained by position
|
||||
|
||||
**KOReader Device Features:**
|
||||
- Created via long-press or selection
|
||||
- Color picker available
|
||||
- Can add notes immediately
|
||||
- Shows in "Highlights" panel
|
||||
- Exportable to Evernote, etc.
|
||||
- Searchable by content
|
||||
|
||||
**Use Cases:**
|
||||
- Study and research
|
||||
- Content curation
|
||||
- Quote collection
|
||||
- Academic work
|
||||
- Sharing insights
|
||||
@@ -0,0 +1,108 @@
|
||||
info:
|
||||
name: Sync Notes
|
||||
type: http
|
||||
seq: 7
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/notes'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid
|
||||
notes:
|
||||
- datetime: '2026-01-30T19:52:00Z'
|
||||
text: My personal note about this chapter
|
||||
chapter: 4
|
||||
|
||||
docs: |-
|
||||
## Sync KOReader Notes
|
||||
|
||||
Synchronizes user notes separately from highlights and bookmarks.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/notes
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Books with notes
|
||||
- `uuid` (string): Book UUID
|
||||
- `notes` (array): Note items
|
||||
- `datetime` (string): Creation/modification timestamp
|
||||
- `text` (string): Note content
|
||||
- `chapter` (integer): Chapter number
|
||||
- `pos0` (string, optional): Related EPUB CFI position
|
||||
- `page` (integer, optional): Page number
|
||||
- `highlighted_text` (string, optional): Related highlight
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Notes synced
|
||||
- `duplicates_skipped` (integer): Duplicate notes found
|
||||
- `attached_to_highlights` (integer): Notes linked to highlights
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**KOReader Note Features:**
|
||||
- Free-form text notes
|
||||
- Can be standalone or attached to highlights
|
||||
- Chapter-based organization
|
||||
- Timestamped for sorting
|
||||
- Markdown support (some versions)
|
||||
- Longer form content
|
||||
- No character limit
|
||||
|
||||
**Note Types:**
|
||||
- **Standalone notes**: Independent notes about chapter/section
|
||||
- **Attached notes**: Notes attached to specific highlights
|
||||
- **Chapter notes**: Notes about entire chapter
|
||||
- **Book notes**: General notes about the book
|
||||
|
||||
**Dedicated Notes Endpoint:**
|
||||
- **Separate sync**: Notes sync independently
|
||||
- **Flexible**: Not tied to highlights
|
||||
- **Efficient**: Smaller, focused payload
|
||||
- **Immediate**: Can sync right after note creation
|
||||
|
||||
**Attached Notes:**
|
||||
- Linked to specific highlight
|
||||
- Shares highlight's position
|
||||
- Shown together with highlight
|
||||
- Deleted when highlight deleted (optional)
|
||||
- Color matches highlight
|
||||
|
||||
**Sync Behavior:**
|
||||
- Text-based duplicate detection
|
||||
- Time-based conflict resolution
|
||||
- Chapter organization preserved
|
||||
- Markdown formatting preserved
|
||||
- Attachment links maintained
|
||||
|
||||
**KOReader Device Integration:**
|
||||
- Created via "Add note" option
|
||||
- Edited in note editor
|
||||
- Shown in "Notes" panel
|
||||
- Can be organized by chapter
|
||||
- Export functionality available
|
||||
- Search support
|
||||
|
||||
**Advanced Features:**
|
||||
- **Markdown**: Bold, italic, lists (some versions)
|
||||
- **Tags**: User-defined tags (via plugins)
|
||||
- **Links**: Internal/external links
|
||||
- **Formatting**: Rich text in newer versions
|
||||
|
||||
**Use Cases:**
|
||||
- Study notes
|
||||
- Personal reflections
|
||||
- Academic annotations
|
||||
- Research insights
|
||||
- Book club discussion prep
|
||||
- Knowledge management
|
||||
@@ -0,0 +1,47 @@
|
||||
info:
|
||||
name: KOReader Sync Progress - SHA-256 Only
|
||||
type: http
|
||||
seq: 2
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/koreader/sync/progress'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"sync_mode\": \"immediate\",\n \"books\": [\n {\n \
|
||||
\ \"sha256\": \"{{book_sha256"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{koreader_device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Sync Progress - SHA-256 Only
|
||||
|
||||
Synchronizes reading progress using only SHA-256 hash for book identification (when UUID is not available).
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/koreader/sync/progress
|
||||
|
||||
**Authentication:** Bearer token (KOReader device token)
|
||||
|
||||
**Request Body:**
|
||||
- `sync_mode` (string): Sync mode (immediate, deferred)
|
||||
- `books` (array): Array of book progress objects
|
||||
- `sha256` (string): SHA-256 hash of book file
|
||||
- `file_path` (string): Path to book file
|
||||
- `percentage` (number): Progress percentage
|
||||
- `page` (number): Current page
|
||||
- `total_pages` (number): Total pages
|
||||
|
||||
**Response:**
|
||||
- `sync_status` (string): Sync status
|
||||
- `books_synced` (number): Number of books synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 202: Accepted
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
|
||||
**Note:** Use this when book UUID is not available, falling back to SHA-256 hash for identification.
|
||||
@@ -0,0 +1,51 @@
|
||||
info:
|
||||
name: KOReader Sync Progress - SHA-256
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/v1/koreader/sync/progress'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"sync_mode\": \"immediate\",\n \"books\": [\n {\n \
|
||||
\ \"uuid\": \"{{book_uuid"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{koreader_device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Sync Progress - SHA-256
|
||||
|
||||
Synchronizes reading progress from a KOReader device using SHA-256 book hash for identification.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/v1/koreader/sync/progress
|
||||
|
||||
**Authentication:** Bearer token (KOReader device token)
|
||||
|
||||
**Request Body:**
|
||||
- `sync_mode` (string): Sync mode (immediate, deferred)
|
||||
- `books` (array): Array of book progress objects
|
||||
- `uuid` (string): Book UUID
|
||||
- `sha256` (string): SHA-256 hash of book file for identification
|
||||
- `file_path` (string): Path to book file on device
|
||||
- `percentage` (number): Progress percentage (0-1)
|
||||
- `chapter` (number): Current chapter
|
||||
- `page` (number): Current page
|
||||
- `total_pages` (number): Total pages
|
||||
- `epubcfi` (string): EPUB location
|
||||
- `last_read` (string): ISO 8601 timestamp
|
||||
- `title` (string): Book title
|
||||
- `authors` (array): List of authors
|
||||
|
||||
**Response:**
|
||||
- `sync_status` (string): Sync status
|
||||
- `books_synced` (number): Number of books synced
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 202: Accepted - processing
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,90 @@
|
||||
info:
|
||||
name: Sync Progress - Multiple Books
|
||||
type: http
|
||||
seq: 2
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-1-uuid
|
||||
title: Book One
|
||||
authors:
|
||||
- Author One
|
||||
progress: 0.25
|
||||
percentage: 0.25
|
||||
last_read: '2026-01-30T19:00:00Z'
|
||||
chapter: 1
|
||||
epubcfi: 'epubcfi(/6/4/2:10)'
|
||||
- uuid: book-2-uuid
|
||||
title: Book Two
|
||||
authors:
|
||||
- Author Two
|
||||
progress: 0.75
|
||||
percentage: 0.75
|
||||
last_read: '2026-01-30T20:00:00Z'
|
||||
chapter: 8
|
||||
epubcfi: 'epubcfi(/6/4/2:50)'
|
||||
|
||||
docs: |-
|
||||
## Sync KOReader Progress - Multiple Books
|
||||
|
||||
Synchronizes reading progress for multiple books in a single request.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Multiple book progress items
|
||||
- Each item contains: uuid, title, authors, progress, percentage, last_read, chapter, epubcfi
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Number of books successfully synced
|
||||
- `failed` (integer): Number of books that failed
|
||||
- `results` (array): Per-book sync results
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Batch sync completed
|
||||
- 207: Multi-status (partial success)
|
||||
- 401: Unauthorized
|
||||
- 413: Payload too large
|
||||
|
||||
**Batch Sync Advantages:**
|
||||
- Efficient sync of entire library
|
||||
- Single HTTP request for multiple books
|
||||
- Faster periodic sync
|
||||
- Reduced battery usage vs individual syncs
|
||||
- Better for batch processing
|
||||
|
||||
**KOReader Batch Behavior:**
|
||||
- Triggered on device wake from sleep
|
||||
- Occurs during "Sync now" operation
|
||||
- Runs on WiFi connection
|
||||
- Limited to 100 books per request
|
||||
- Automatic retry on failed books
|
||||
|
||||
**Performance:**
|
||||
- Small batch (2-10 books): 200-500ms
|
||||
- Medium batch (10-50 books): 500ms-2s
|
||||
- Large batch (50-100 books): 2-5s
|
||||
- Timeout: 30 seconds
|
||||
|
||||
**Use Cases:**
|
||||
- Device initialization sync
|
||||
- Periodic background sync
|
||||
- Post-offline catch-up sync
|
||||
- Library-wide progress update
|
||||
- Before firmware update
|
||||
@@ -0,0 +1,92 @@
|
||||
info:
|
||||
name: Sync Progress - Single Book
|
||||
type: http
|
||||
seq: 1
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid-here
|
||||
title: Book Title
|
||||
authors:
|
||||
- Author Name
|
||||
progress: 0.45
|
||||
percentage: 0.45
|
||||
last_read: '2026-01-30T20:00:00Z'
|
||||
chapter: 3
|
||||
epubcfi: 'epubcfi(/6/4/2:15)'
|
||||
character: 15432
|
||||
|
||||
docs: |-
|
||||
## Sync KOReader Progress - Single Book
|
||||
|
||||
Synchronizes reading progress for a single book from KOReader device.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token (koreader_device_token)
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID for multi-library setups
|
||||
- `books` (array): Array with single book progress
|
||||
- `uuid` (string): Unique book identifier (often SHA-256 hash)
|
||||
- `title` (string): Book title
|
||||
- `authors` (array): List of authors
|
||||
- `progress` (number): Progress decimal (0.0 to 1.0)
|
||||
- `percentage` (number): Progress percentage (0.45 = 45%)
|
||||
- `last_read` (string): ISO 8601 timestamp of last read
|
||||
- `chapter` (integer): Current chapter number
|
||||
- `epubcfi` (string): EPUB Canonical Fragment Identifier
|
||||
- `character` (integer): Character position in book
|
||||
- `page` (integer, optional): Current page number
|
||||
|
||||
**Response:**
|
||||
- `synced` (integer): Number of books synced
|
||||
- `timestamp` (string): Server sync timestamp
|
||||
- `books` (array): Sync results
|
||||
- `uuid` (string): Book UUID
|
||||
- `status` (string): `synced`, `updated`, `skipped`
|
||||
- `server_progress` (object): Server-side progress data
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 400: Invalid request format
|
||||
|
||||
**KOReader Progress Tracking:**
|
||||
- SHA-256 based book identification (universal across devices)
|
||||
- EPUB CFI for precise location (standard format)
|
||||
- Chapter-based navigation
|
||||
- Character-level precision
|
||||
- Supports EPUB, FB2, PDF, DJVU, MOBI formats
|
||||
|
||||
**EPUB CFI Format:**
|
||||
- Standardized location format for EPUBs
|
||||
- Example: `epubcfi(/6/4/2:15)`
|
||||
- Identifies exact position even after reflow
|
||||
- Works across different devices/apps
|
||||
- Preserved after file modifications
|
||||
|
||||
**Book Identification:**
|
||||
- Primary: SHA-256 hash of book file
|
||||
- Universal: Same book = same UUID across devices
|
||||
- Format-agnostic: Works for any supported format
|
||||
- Case-sensitive: Hash must match exactly
|
||||
|
||||
**Use Cases:**
|
||||
- Real-time page turn sync
|
||||
- Progress backup
|
||||
- Cross-device continuity
|
||||
- Reading time tracking
|
||||
- Chapter completion detection
|
||||
@@ -0,0 +1,106 @@
|
||||
info:
|
||||
name: Sync Progress - With Bookmarks
|
||||
type: http
|
||||
seq: 3
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid-here
|
||||
title: Book Title
|
||||
authors:
|
||||
- Author Name
|
||||
progress: 0.45
|
||||
percentage: 0.45
|
||||
last_read: '2026-01-30T20:00:00Z'
|
||||
bookmarks:
|
||||
- chapter: 3
|
||||
datetime: '2026-01-30T19:55:00Z'
|
||||
notes: highlighted text
|
||||
pos0: 'epubcfi(/6/4/2:15)'
|
||||
pos1: 'epubcfi(/6/4/2:20)'
|
||||
page: 45
|
||||
text: highlighted text excerpt
|
||||
type: highlight
|
||||
|
||||
docs: |-
|
||||
## Sync Progress with Bookmarks
|
||||
|
||||
Synchronizes reading progress with bookmarks/highlights from KOReader.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Books with progress and bookmarks
|
||||
- `uuid`, `title`, `authors`, `progress`, etc.
|
||||
- `bookmarks` (array): Bookmark items
|
||||
- `chapter` (integer): Chapter number
|
||||
- `datetime` (string): ISO 8601 timestamp
|
||||
- `notes` (string): Note content or highlighted text
|
||||
- `pos0` (string): EPUB CFI start position
|
||||
- `pos1` (string): EPUB CFI end position
|
||||
- `page` (integer): Page number
|
||||
- `text` (string): Displayed text excerpt
|
||||
- `type` (string): `highlight`, `bookmark`, or `note`
|
||||
|
||||
**Response:**
|
||||
- `progress_synced` (integer): Progress items synced
|
||||
- `bookmarks_synced` (integer): Bookmark items synced
|
||||
- `highlights_synced` (integer): Highlight count
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**KOReader Bookmark Types:**
|
||||
- **highlight**: Selected text passages
|
||||
- **bookmark**: Location markers
|
||||
- **note**: Text annotations (can be attached to highlights)
|
||||
|
||||
**KOReader Highlight Features:**
|
||||
- Custom colors (via color extensions)
|
||||
- Multi-color support
|
||||
- Precise EPUB CFI positioning
|
||||
- Chapter-based organization
|
||||
- Text excerpts preserved
|
||||
- Date/time stamped
|
||||
- Page number tracking
|
||||
|
||||
**EPUB CFI in Bookmarks:**
|
||||
- `pos0`: Start position (highlight start)
|
||||
- `pos1`: End position (highlight end)
|
||||
- Exact text selection boundaries
|
||||
- Survives text reflow
|
||||
- Works across different font sizes
|
||||
|
||||
**Sync Behavior:**
|
||||
- Duplicate detection by text + position
|
||||
- Most recent edit wins
|
||||
- Chapter references maintained
|
||||
- Order preserved from device
|
||||
- Merges with existing server bookmarks
|
||||
|
||||
**KOReader Device Integration:**
|
||||
- Created in KOReader highlight interface
|
||||
- Shows in "Bookmarks" menu
|
||||
- Can be edited/deleted on device
|
||||
- Exportable to JSON/XML
|
||||
- Searchable by content
|
||||
|
||||
**Use Cases:**
|
||||
- Study and research
|
||||
- Content review
|
||||
- Passage tracking
|
||||
- Quick navigation
|
||||
- Cross-device bookmark access
|
||||
@@ -0,0 +1,117 @@
|
||||
info:
|
||||
name: Sync Progress - With Highlights and Notes
|
||||
type: http
|
||||
seq: 4
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
library_id: optional-library-uuid
|
||||
books:
|
||||
- uuid: book-uuid-here
|
||||
title: Book Title
|
||||
authors:
|
||||
- Author Name
|
||||
progress: 0.6
|
||||
percentage: 0.6
|
||||
last_read: '2026-01-30T20:00:00Z'
|
||||
highlights:
|
||||
- datetime: '2026-01-30T19:50:00Z'
|
||||
text: Important passage
|
||||
chapter: 4
|
||||
pos0: 'epubcfi(/6/4/2:20)'
|
||||
pos1: 'epubcfi(/6/4/2:30)'
|
||||
page_start: 78
|
||||
page_end: 79
|
||||
notes:
|
||||
- datetime: '2026-01-30T19:52:00Z'
|
||||
text: My note about this chapter
|
||||
chapter: 4
|
||||
|
||||
docs: |-
|
||||
## Sync Progress with Highlights and Notes
|
||||
|
||||
Synchronizes reading progress with separate highlights and notes arrays.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Books with progress and annotations
|
||||
- `uuid`, `title`, `authors`, `progress`, `percentage`, `last_read`
|
||||
- `highlights` (array): Text highlights
|
||||
- `datetime` (string): Creation timestamp
|
||||
- `text` (string): Highlighted text content
|
||||
- `chapter` (integer): Chapter number
|
||||
- `pos0` (string): EPUB CFI start
|
||||
- `pos1` (string): EPUB CFI end
|
||||
- `page_start` (integer): Start page
|
||||
- `page_end` (integer): End page
|
||||
- `color` (string, optional): Highlight color
|
||||
- `notes` (array): Notes
|
||||
- `datetime` (string): Creation timestamp
|
||||
- `text` (string): Note content
|
||||
- `chapter` (integer): Chapter number
|
||||
- `pos0` (string, optional): Related position
|
||||
|
||||
**Response:**
|
||||
- `progress_synced` (boolean): Progress sync status
|
||||
- `highlights_synced` (integer): Highlights synced
|
||||
- `notes_synced` (integer): Notes synced
|
||||
- `conflicts_resolved` (integer): Conflict count
|
||||
- `timestamp` (string): Sync timestamp
|
||||
|
||||
**KOReader Annotation Model:**
|
||||
- **Separate arrays**: Highlights and notes stored separately
|
||||
- **Linked**: Notes can reference highlights
|
||||
- **Rich metadata**: Timestamps, positions, page numbers
|
||||
- **Flexible**: Supports complex annotations
|
||||
|
||||
**Highlight Features:**
|
||||
- Multi-color highlighting (via plugins)
|
||||
- Precise text selection with EPUB CFI
|
||||
- Page range tracking
|
||||
- Chapter references
|
||||
- Timestamps for sorting
|
||||
- Full text preserved
|
||||
|
||||
**Note Features:**
|
||||
- Free-form text notes
|
||||
- Can be standalone or attached
|
||||
- Chapter-based organization
|
||||
- Timestamped
|
||||
- Longer form than highlights
|
||||
- Support for markdown (some versions)
|
||||
|
||||
**Color Support (via plugins):**
|
||||
- Yellow: Default highlight
|
||||
- Green: Important passages
|
||||
- Blue: Key concepts
|
||||
- Red: Critical information
|
||||
- Orange: Interesting quotes
|
||||
- Custom colors available
|
||||
|
||||
**Sync Advantages:**
|
||||
- Separation allows granular control
|
||||
- Highlights sync without notes
|
||||
- Notes sync independently
|
||||
- Better conflict resolution
|
||||
- Efficient for large annotation sets
|
||||
|
||||
**Use Cases:**
|
||||
- Academic research
|
||||
- Study groups
|
||||
- Content analysis
|
||||
- Personal knowledge management
|
||||
- Sharing insights
|
||||
@@ -0,0 +1,53 @@
|
||||
info:
|
||||
name: KOReader Sync Progress
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/sync/koreader/progress'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"library_id\": null,\n \"books\": [\n {\n \"\
|
||||
uuid\": \"{{book_uuid"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{device_token
|
||||
|
||||
docs: |-
|
||||
## KOReader Sync Progress
|
||||
|
||||
Synchronizes reading progress from a KOReader device to the Bookhoard server.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/sync/koreader/progress
|
||||
|
||||
**Authentication:** Bearer token (device token)
|
||||
|
||||
**Request Body:**
|
||||
- `library_id` (string, optional): Library UUID
|
||||
- `books` (array): Array of book progress objects
|
||||
- `uuid` (string): Book UUID
|
||||
- `title` (string): Book title
|
||||
- `authors` (array): List of authors
|
||||
- `progress` (number): Progress value
|
||||
- `percentage` (number): Percentage complete (0-1)
|
||||
- `last_read` (string): ISO 8601 timestamp
|
||||
- `chapter` (number): Current chapter
|
||||
- `epubcfi` (string): EPUB Canonical Fragment Identifier
|
||||
- `page` (number): Current page
|
||||
- `total_pages` (number): Total pages
|
||||
- `sync_mode` (string): Sync mode (immediate, deferred)
|
||||
- `device_info` (object): Device information
|
||||
- `koreader_version` (string): KOReader version
|
||||
- `device_model` (string): Device model identifier
|
||||
|
||||
**Response:**
|
||||
- `sync_status` (string): Sync status (accepted, processing)
|
||||
- `books_synced` (number): Number of books synced
|
||||
|
||||
**Status Codes:**
|
||||
- 202: Accepted - sync queued
|
||||
- 401: Unauthorized
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,23 @@
|
||||
info:
|
||||
name: Add Books to Kobo Shelf
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{baseURL}}/api/devices/{{deviceID}}/shelves'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"media_item_ids\": [\n \"{{bookUUID1"
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{userToken
|
||||
|
||||
docs: |-
|
||||
## Add Books to Kobo Shelf
|
||||
|
||||
Add one or more books to a Kobo device shelf. Manages which books should be synced to a specific Kobo device. Supports multiple shelves for organization.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/{deviceID
|
||||
@@ -0,0 +1,40 @@
|
||||
info:
|
||||
name: Approve Device Registration
|
||||
type: http
|
||||
seq: 6
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/approve/{{registration_id}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Approve Device Registration
|
||||
|
||||
Approves a pending device registration request.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/approve/:registration_id
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Registration request UUID
|
||||
|
||||
**Response:**
|
||||
- Success message with approved device details
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 404: Registration not found
|
||||
- 400: Invalid registration status
|
||||
|
||||
**Example Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Device registration approved",
|
||||
"device_id": "uuid",
|
||||
"device_name": "My Kobo"
|
||||
@@ -0,0 +1,55 @@
|
||||
info:
|
||||
name: Approve Registration - KOReader
|
||||
type: http
|
||||
seq: 13
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/approve/reg-uuid-123'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Approve KOReader Device Registration
|
||||
|
||||
Approves a pending KOReader device registration.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/approve/:registration_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Example: `reg-uuid-123`
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): Approved registration UUID
|
||||
- `device_id` (string): Generated device UUID
|
||||
- `device_name` (string): KOReader device name
|
||||
- `device_type` (string): `koreader`
|
||||
- `status` (string): `approved`
|
||||
- `access_token` (string): Device access token
|
||||
- `sync_endpoints` (object):
|
||||
- `bookmarks` (string): Bookmarks sync endpoint
|
||||
- `progress` (string): Progress sync endpoint
|
||||
- `highlights` (string): Highlights sync endpoint
|
||||
- `annotations` (string): Annotations sync endpoint
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Approved successfully
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Registration not found
|
||||
|
||||
**KOReader-Specific Features:**
|
||||
- Supports per-book SHA-256 based progress tracking
|
||||
- Syncs highlights with color and notes
|
||||
- Syncs bookmarks with locations and timestamps
|
||||
- Supports dictionary annotations
|
||||
- Can sync custom highlight colors
|
||||
|
||||
**After Approval:**
|
||||
- KOReader device can immediately sync
|
||||
- Device shows up in device list as "KOReader"
|
||||
- Access token is stored in device settings
|
||||
- Initial sync pulls down existing user data
|
||||
@@ -0,0 +1,60 @@
|
||||
info:
|
||||
name: Approve Registration - Kobo
|
||||
type: http
|
||||
seq: 14
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/approve/reg-uuid-456'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Approve Kobo Device Registration
|
||||
|
||||
Approves a pending Kobo e-reader device registration.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/approve/:registration_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Example: `reg-uuid-456`
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): Approved registration UUID
|
||||
- `device_id` (string): Generated device UUID
|
||||
- `device_name` (string): Kobo device name
|
||||
- `device_type` (string): `kobo`
|
||||
- `status` (string): `approved`
|
||||
- `access_token` (string): Device access token
|
||||
- `sync_endpoints` (object):
|
||||
- `bookmark_sync` (string): Bookmark sync URL
|
||||
- `markup_sync` (string): Markup/highlight sync URL
|
||||
- `metadata_sync` (string): Metadata sync URL
|
||||
- `kobo_features` (object):
|
||||
- `supports_shelves` (boolean): Kobo shelf support
|
||||
- `supports_dictionary` (boolean): Dictionary annotation support
|
||||
- `supports_statistics` (boolean): Reading statistics support
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Approved successfully
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Registration not found
|
||||
|
||||
**Kobo-Specific Features:**
|
||||
- Native Kobo sync protocol support
|
||||
- Shelves/collections sync
|
||||
- Reading statistics sync
|
||||
- Dictionary lookups with annotations
|
||||
- Book metadata sync
|
||||
- Pocket articles integration
|
||||
|
||||
**After Approval:**
|
||||
- Kobo device can use native sync feature
|
||||
- Device appears in Nickel (Kobo UI)
|
||||
- Sync runs automatically when connected
|
||||
- Shelves sync with collections
|
||||
- Reading progress syncs across devices
|
||||
@@ -0,0 +1,52 @@
|
||||
info:
|
||||
name: Check Pending Registration
|
||||
type: http
|
||||
seq: 4
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register/status'
|
||||
auth: none
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
registration_id: registration-uuid-here
|
||||
|
||||
docs: |-
|
||||
## Check Registration Status
|
||||
|
||||
Checks the current status of a device registration request.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/register/status
|
||||
|
||||
**Authentication:** None
|
||||
|
||||
**Request Body:**
|
||||
- `registration_id` (string): UUID received from registration request
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): The registration UUID
|
||||
- `status` (string): Current status
|
||||
- `pending`: Awaiting user approval
|
||||
- `approved`: Registration approved, device ready
|
||||
- `rejected`: Registration rejected by user
|
||||
- `expired`: Registration expired (not approved in time)
|
||||
- `device_name` (string): Name of the device
|
||||
- `device_type` (string): Type of device
|
||||
- `created_at` (string): Registration timestamp
|
||||
- `updated_at` (string): Last status update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Status retrieved successfully
|
||||
- 404: Registration ID not found
|
||||
- 400: Invalid registration ID format
|
||||
|
||||
**Polling Recommendations:**
|
||||
- Poll every 5-10 seconds while status is `pending`
|
||||
- Stop polling when status changes to `approved`, `rejected`, or `expired`
|
||||
- Use exponential backoff for mobile devices to save battery
|
||||
@@ -0,0 +1,11 @@
|
||||
info:
|
||||
name: Check Registration Status
|
||||
type: http
|
||||
seq: 2
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register/status'
|
||||
auth: none
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"registration_id\": \"{{registrationId"
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Clear Kobo Shelf
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: DELETE
|
||||
url: '{{baseURL}}/api/devices/{{deviceID}}/shelves/clear?shelf={{shelfName}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{userToken
|
||||
|
||||
docs: |-
|
||||
## Clear Kobo Shelf
|
||||
|
||||
Clear all books from a Kobo device shelf, or all shelves if no shelf name is specified.
|
||||
|
||||
**Method:** DELETE
|
||||
|
||||
**Endpoint:** /api/devices/{deviceID
|
||||
@@ -0,0 +1,55 @@
|
||||
info:
|
||||
name: Create Device File Alias
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/{{device_id}}/file-aliases'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"file_path\": \"/mnt/sd/books/my-book.kepub.epub\",\n \"\
|
||||
media_item_id\": \"{{media_item_id"
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
runtime:
|
||||
scripts:
|
||||
- type: tests
|
||||
code: "test_create_device_file_alias_success(status, headers, body) {\n if\
|
||||
\ (status !== 201 && status !== 200) {\n throw new Error(\"Expected status\
|
||||
\ 201 or 200, got \" + status);"
|
||||
|
||||
docs: |-
|
||||
## Create Device File Alias
|
||||
|
||||
Creates a new file alias for a device. File aliases map device-specific file paths to media items.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/:id/file-aliases
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `id` (string, required): Device UUID
|
||||
|
||||
**Request Body:**
|
||||
- `file_path` (string, required): Device-specific file path
|
||||
- `media_item_id` (string, required): Media item UUID to link to
|
||||
|
||||
**Response:** Created file alias object
|
||||
- `id` (string): Alias UUID
|
||||
- `device_id` (string): Device UUID
|
||||
- `file_path` (string): Device-specific file path
|
||||
- `media_item_id` (string): Associated media item UUID
|
||||
- `created_at` (string): Creation timestamp
|
||||
- `updated_at` (string): Last update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 201: Created
|
||||
- 200: Success
|
||||
- 400: Invalid request body
|
||||
- 401: Unauthorized
|
||||
- 404: Device not found
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Delete Device
|
||||
type: http
|
||||
seq: 6
|
||||
http:
|
||||
method: DELETE
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{token
|
||||
|
||||
docs: |-
|
||||
## Delete Device
|
||||
|
||||
Deletes a device and unregisters it from the user's account.
|
||||
|
||||
**Method:** DELETE
|
||||
|
||||
**Endpoint:** /api/devices/{deviceId
|
||||
@@ -0,0 +1,58 @@
|
||||
info:
|
||||
name: Disable Device Sync
|
||||
type: http
|
||||
seq: 8
|
||||
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: My Kobo Clara
|
||||
sync_enabled: false
|
||||
auto_sync: false
|
||||
sync_frequency_minutes: 30
|
||||
|
||||
docs: |-
|
||||
## Disable Device Sync
|
||||
|
||||
Disables synchronization for a specific device.
|
||||
|
||||
**Method:** PUT
|
||||
|
||||
**Endpoint:** /api/devices/:device_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `device_id` (string): UUID of the device
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string, optional): Device name
|
||||
- `sync_enabled` (boolean): Must be `false`
|
||||
- `auto_sync` (boolean): Should be `false`
|
||||
- `sync_frequency_minutes` (integer, optional): Any value (sync disabled)
|
||||
|
||||
**Response:**
|
||||
- `id` (string): Device UUID
|
||||
- `device_name` (string): Device name
|
||||
- `sync_enabled` (boolean): `false`
|
||||
- `auto_sync` (boolean): `false`
|
||||
- `message` (string): Confirmation message
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Sync disabled successfully
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Device not found
|
||||
|
||||
**Use Cases:**
|
||||
- Temporarily disable sync for troubleshooting
|
||||
- Stop sync for a lost or stolen device
|
||||
- Disable sync before selling or giving away device
|
||||
- Prevent data usage on limited connections
|
||||
@@ -0,0 +1,44 @@
|
||||
info:
|
||||
name: Get Device File Aliases
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/{{device_id}}/file-aliases'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
runtime:
|
||||
scripts:
|
||||
- type: tests
|
||||
code: "test_get_device_file_aliases_success(status, headers, body) {\n if (status\
|
||||
\ !== 200) {\n throw new Error(\"Expected status 200, got \" + status);"
|
||||
|
||||
docs: |-
|
||||
## Get Device File Aliases
|
||||
|
||||
Retrieves all file aliases for a specific device. File aliases are used to map device-specific file paths to media items.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/:id/file-aliases
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `id` (string, required): Device UUID
|
||||
|
||||
**Response:** Array of file alias objects
|
||||
- `id` (string): Alias UUID
|
||||
- `device_id` (string): Device UUID
|
||||
- `file_path` (string): Device-specific file path
|
||||
- `media_item_id` (string): Associated media item UUID
|
||||
- `created_at` (string): Creation timestamp
|
||||
- `updated_at` (string): Last update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 404: Device not found
|
||||
- 500: Internal server error
|
||||
@@ -0,0 +1,45 @@
|
||||
info:
|
||||
name: Get Device Details
|
||||
type: http
|
||||
seq: 6
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Get Device Details
|
||||
|
||||
Retrieves detailed information about a specific device.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/:device_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `device_id` (string): UUID of the device
|
||||
|
||||
**Response:**
|
||||
- `id` (string): Device UUID
|
||||
- `device_name` (string): Device name
|
||||
- `device_type` (string): `kobo`, `koreader`, or `web`
|
||||
- `device_identifier` (string): Unique identifier
|
||||
- `sync_enabled` (boolean): Sync status
|
||||
- `auto_sync` (boolean): Auto-sync setting
|
||||
- `sync_frequency_minutes` (integer): Sync interval
|
||||
- `last_synced_at` (string): Last sync timestamp
|
||||
- `sync_stats` (object): Sync statistics
|
||||
- `total_syncs` (integer): Number of successful syncs
|
||||
- `last_sync_status` (string): Status of last sync
|
||||
- `bytes_synced` (integer): Total data transferred
|
||||
- `created_at` (string): Registration timestamp
|
||||
- `updated_at` (string): Last update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden (device belongs to different user)
|
||||
- 404: Device not found
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Get Kobo Shelf Books
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: GET
|
||||
url: '{{baseURL}}/api/devices/{{deviceID}}/shelves?shelf={{shelfName}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{userToken
|
||||
|
||||
docs: |-
|
||||
## Get Kobo Shelf Books
|
||||
|
||||
Get all books on a Kobo device shelf, optionally filter by shelf name.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/{deviceID
|
||||
@@ -0,0 +1,12 @@
|
||||
info:
|
||||
name: Initiate Device Registration
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register'
|
||||
auth: none
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"device_name\": \"My Kindle Paperwhite\",\n \"device_type\"\
|
||||
: \"koreader\",\n \"device_identifier\": \"kindle-pw5-hardware-id-12345\""
|
||||
@@ -0,0 +1,41 @@
|
||||
info:
|
||||
name: List User Devices
|
||||
type: http
|
||||
seq: 5
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## List User Devices
|
||||
|
||||
Retrieves all registered devices for the authenticated user.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Response:**
|
||||
- Array of device objects:
|
||||
- `id` (string): Device UUID
|
||||
- `device_name` (string): Human-readable device name
|
||||
- `device_type` (string): `kobo`, `koreader`, or `web`
|
||||
- `device_identifier` (string): Unique device identifier
|
||||
- `sync_enabled` (boolean): Whether sync is active
|
||||
- `auto_sync` (boolean): Whether automatic sync is enabled
|
||||
- `sync_frequency_minutes` (integer): Sync interval in minutes
|
||||
- `last_synced_at` (string): Last successful sync timestamp
|
||||
- `created_at` (string): Registration timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
|
||||
**Usage:**
|
||||
- Display user's devices in account settings
|
||||
- Allow users to manage sync settings per device
|
||||
- Show last sync time for each device
|
||||
@@ -0,0 +1,46 @@
|
||||
info:
|
||||
name: Get Pending Registrations
|
||||
type: http
|
||||
seq: 11
|
||||
|
||||
http:
|
||||
method: GET
|
||||
url: '{{base_url}}/api/devices/pending'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Get Pending Registrations
|
||||
|
||||
Retrieves all pending device registration requests awaiting approval.
|
||||
|
||||
**Method:** GET
|
||||
|
||||
**Endpoint:** /api/devices/pending
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Response:**
|
||||
- Array of pending registration objects:
|
||||
- `registration_id` (string): Registration UUID
|
||||
- `device_name` (string): Name of the device
|
||||
- `device_type` (string): `kobo`, `koreader`, or `web`
|
||||
- `device_identifier` (string): Device ID (may be masked)
|
||||
- `created_at` (string): Request timestamp
|
||||
- `expires_at` (string): Expiration timestamp
|
||||
- `status` (string): Always `pending`
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
|
||||
**Use Cases:**
|
||||
- Show pending registrations in user settings
|
||||
- Allow users to review devices before approval
|
||||
- Display registration request details
|
||||
- Provide approve/reject actions
|
||||
|
||||
**Security Notes:**
|
||||
- Full device identifier may be partially masked
|
||||
- Only shows registrations for authenticated user
|
||||
- Expired registrations are automatically removed
|
||||
- Users can only see their own pending registrations
|
||||
@@ -0,0 +1,49 @@
|
||||
info:
|
||||
name: Register Device
|
||||
type: http
|
||||
seq: 1
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register'
|
||||
auth: none
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: My Kobo Clara
|
||||
device_type: kobo
|
||||
device_identifier: N1234567890123
|
||||
|
||||
docs: |-
|
||||
## Register Device
|
||||
|
||||
Initiates device registration by sending device information to the server.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/register
|
||||
|
||||
**Authentication:** None (public endpoint)
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string): Human-readable name for the device
|
||||
- `device_type` (string): Type of device - `kobo`, `koreader`, or `web`
|
||||
- `device_identifier` (string): Unique device identifier (serial number or other ID)
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): UUID for tracking registration status
|
||||
- `status` (string): Registration status - `pending`, `approved`, or `rejected`
|
||||
- `message` (string): Status message
|
||||
|
||||
**Status Codes:**
|
||||
- 201: Registration initiated successfully
|
||||
- 400: Invalid request data
|
||||
- 409: Device already registered
|
||||
|
||||
**Notes:**
|
||||
- Device registration requires user approval before activation
|
||||
- Registration ID should be stored for status checking
|
||||
- Device identifier must be unique per device
|
||||
@@ -0,0 +1,48 @@
|
||||
info:
|
||||
name: Register KOReader Device
|
||||
type: http
|
||||
seq: 2
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register'
|
||||
auth: none
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: My Kindle Paperwhite
|
||||
device_type: koreader
|
||||
device_identifier: G090GP123456789
|
||||
|
||||
docs: |-
|
||||
## Register KOReader Device
|
||||
|
||||
Registers a KOReader device (typically Kindle devices running KOReader software).
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/register
|
||||
|
||||
**Authentication:** None (public endpoint)
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string): Human-readable name for the device
|
||||
- `device_type` (string): Must be `koreader`
|
||||
- `device_identifier` (string): Kindle serial number or unique device ID
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): UUID for tracking registration status
|
||||
- `status` (string): Registration status - `pending`
|
||||
- `message` (string): Confirmation message
|
||||
|
||||
**Status Codes:**
|
||||
- 201: Registration initiated
|
||||
- 400: Invalid device type or data
|
||||
|
||||
**KOReader Notes:**
|
||||
- KOReader runs on Kindle, Kobo, PocketBook, and Android devices
|
||||
- Device identifier is typically the device serial number
|
||||
- Supports bookmarks, progress, highlights, and annotations sync
|
||||
@@ -0,0 +1,49 @@
|
||||
info:
|
||||
name: Register Web Device
|
||||
type: http
|
||||
seq: 3
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/register'
|
||||
auth: none
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: Chrome Browser
|
||||
device_type: web
|
||||
device_identifier: web-client-abc123
|
||||
|
||||
docs: |-
|
||||
## Register Web Device
|
||||
|
||||
Registers a web browser client for reading progress sync.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/register
|
||||
|
||||
**Authentication:** None (public endpoint)
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string): Browser identification (e.g., "Chrome Browser")
|
||||
- `device_type` (string): Must be `web`
|
||||
- `device_identifier` (string): Unique browser/client identifier
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): UUID for tracking
|
||||
- `status` (string): `pending` or `auto-approved`
|
||||
- `message` (string): Status message
|
||||
|
||||
**Status Codes:**
|
||||
- 201: Registration successful
|
||||
- 400: Invalid request
|
||||
|
||||
**Web Device Notes:**
|
||||
- Web devices use localStorage for device identification
|
||||
- May be auto-approved without admin intervention
|
||||
- Used for browser-based reading progress tracking
|
||||
- Supports manual progress updates, highlights, and notes
|
||||
@@ -0,0 +1,38 @@
|
||||
info:
|
||||
name: Reject Device Registration
|
||||
type: http
|
||||
seq: 7
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/reject/{{registration_id}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Reject Device Registration
|
||||
|
||||
Rejects a pending device registration request.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/reject/:registration_id
|
||||
|
||||
**Authentication:** Bearer token
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Registration request UUID
|
||||
|
||||
**Response:**
|
||||
- Success message confirming rejection
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Success
|
||||
- 401: Unauthorized
|
||||
- 404: Registration not found
|
||||
- 400: Invalid registration status
|
||||
|
||||
**Example Response:**
|
||||
```json
|
||||
{
|
||||
"message": "device registration rejected"
|
||||
@@ -0,0 +1,56 @@
|
||||
info:
|
||||
name: Reject Registration - KOReader
|
||||
type: http
|
||||
seq: 16
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/reject/reg-uuid-123'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Reject KOReader Registration
|
||||
|
||||
Rejects a pending KOReader device registration.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/reject/:registration_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Example: `reg-uuid-123`
|
||||
|
||||
**Request Body:**
|
||||
Optional rejection reason:
|
||||
```json
|
||||
{
|
||||
"reason": "Device not recognized or user cancelled"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): Rejected registration UUID
|
||||
- `device_name` (string): KOReader device name
|
||||
- `device_type` (string): `koreader`
|
||||
- `status` (string): `rejected`
|
||||
- `rejected_at` (string): Rejection timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Rejected successfully
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Registration not found
|
||||
|
||||
**KOReader Rejection Handling:**
|
||||
- KOReader app displays rejection message
|
||||
- User can initiate new registration
|
||||
- Previous device identifier can be reused
|
||||
- No data is lost on the device
|
||||
|
||||
**Common Reasons:**
|
||||
- User didn't initiate registration
|
||||
- Wrong device type selected
|
||||
- Testing/sample registration
|
||||
- Security concerns
|
||||
@@ -0,0 +1,64 @@
|
||||
info:
|
||||
name: Reject Registration - Kobo
|
||||
type: http
|
||||
seq: 17
|
||||
|
||||
http:
|
||||
method: POST
|
||||
url: '{{base_url}}/api/devices/reject/reg-uuid-456'
|
||||
auth: inherit
|
||||
|
||||
docs: |-
|
||||
## Reject Kobo Registration
|
||||
|
||||
Rejects a pending Kobo e-reader device registration.
|
||||
|
||||
**Method:** POST
|
||||
|
||||
**Endpoint:** /api/devices/reject/:registration_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `registration_id` (string): Example: `reg-uuid-456`
|
||||
|
||||
**Request Body:**
|
||||
Optional rejection reason:
|
||||
```json
|
||||
{
|
||||
"reason": "Unrecognized device or user cancelled"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
- `registration_id` (string): Rejected registration UUID
|
||||
- `device_name` (string): Kobo device name
|
||||
- `device_type` (string): `kobo`
|
||||
- `status` (string): `rejected`
|
||||
- `rejected_at` (string): Rejection timestamp
|
||||
- `message` (string): User-friendly message
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Rejected successfully
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Registration not found
|
||||
|
||||
**Kobo Rejection Handling:**
|
||||
- Kobo sync service shows rejection on device
|
||||
- Device remains unregistered
|
||||
- User must retry registration process
|
||||
- Device serial number can be reused
|
||||
|
||||
**Common Reasons:**
|
||||
- Unrecognized Kobo device
|
||||
- User didn't initiate sync
|
||||
- Wrong account selected on device
|
||||
- Security precaution
|
||||
- Device sold/given away (prevent old owner access)
|
||||
|
||||
**Kobo-Specific Notes:**
|
||||
- Kobo devices display rejection in sync settings
|
||||
- Device may need to be rebooted to clear pending state
|
||||
- No data is removed from the device
|
||||
- Re-registration requires going through Kobo's sync setup again
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Remove Book from Kobo Shelf
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: DELETE
|
||||
url: '{{baseURL}}/api/devices/{{deviceID}}/shelves?media_item_id={{bookUUID}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
headers:
|
||||
- key: Authorization
|
||||
value: Bearer {{userToken
|
||||
|
||||
docs: |-
|
||||
## Remove Book from Kobo Shelf
|
||||
|
||||
Remove a specific book from a Kobo device shelf, preventing it from syncing to that device.
|
||||
|
||||
**Method:** DELETE
|
||||
|
||||
**Endpoint:** /api/devices/{deviceID
|
||||
@@ -0,0 +1,61 @@
|
||||
info:
|
||||
name: Update Device Settings
|
||||
type: http
|
||||
seq: 7
|
||||
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: Updated Device Name
|
||||
sync_enabled: true
|
||||
auto_sync: true
|
||||
sync_frequency_minutes: 10
|
||||
|
||||
docs: |-
|
||||
## Update Device Settings
|
||||
|
||||
Updates device configuration and sync settings.
|
||||
|
||||
**Method:** PUT
|
||||
|
||||
**Endpoint:** /api/devices/:device_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `device_id` (string): UUID of the device
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string, optional): New device name
|
||||
- `sync_enabled` (boolean, optional): Enable/disable sync
|
||||
- `auto_sync` (boolean, optional): Enable automatic sync
|
||||
- `sync_frequency_minutes` (integer, optional): Sync interval (5-1440 minutes)
|
||||
|
||||
**Response:**
|
||||
- `id` (string): Device UUID
|
||||
- `device_name` (string): Updated device name
|
||||
- `sync_enabled` (boolean): Updated sync status
|
||||
- `auto_sync` (boolean): Updated auto-sync setting
|
||||
- `sync_frequency_minutes` (integer): Updated sync interval
|
||||
- `updated_at` (string): Update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Settings updated successfully
|
||||
- 400: Invalid sync frequency or data
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden (device belongs to different user)
|
||||
- 404: Device not found
|
||||
|
||||
**Sync Frequency Guidelines:**
|
||||
- Mobile devices: 10-30 minutes
|
||||
- E-readers on WiFi: 15-60 minutes
|
||||
- Web clients: 5-15 minutes
|
||||
- Minimum: 5 minutes
|
||||
- Maximum: 1440 minutes (24 hours)
|
||||
@@ -0,0 +1,12 @@
|
||||
info:
|
||||
name: Update Device
|
||||
type: http
|
||||
seq: 5
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
body:
|
||||
type: json
|
||||
jsonBody: "{\n \"device_name\": \"My Updated Kindle\",\n \"sync_enabled\"\
|
||||
: true,\n \"auto_sync\": true,\n \"sync_frequency_minutes\": 10"
|
||||
@@ -0,0 +1,66 @@
|
||||
info:
|
||||
name: Update Sync Frequency
|
||||
type: http
|
||||
seq: 9
|
||||
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}'
|
||||
auth: inherit
|
||||
headers:
|
||||
- key: Content-Type
|
||||
value: application/json
|
||||
body:
|
||||
type: json
|
||||
json:
|
||||
device_name: My Kobo Clara
|
||||
sync_enabled: true
|
||||
auto_sync: true
|
||||
sync_frequency_minutes: 15
|
||||
|
||||
docs: |-
|
||||
## Update Sync Frequency
|
||||
|
||||
Changes how often the device automatically syncs with the server.
|
||||
|
||||
**Method:** PUT
|
||||
|
||||
**Endpoint:** /api/devices/:device_id
|
||||
|
||||
**Authentication:** Required (Bearer token)
|
||||
|
||||
**Path Parameters:**
|
||||
- `device_id` (string): UUID of the device
|
||||
|
||||
**Request Body:**
|
||||
- `device_name` (string, optional): Device name
|
||||
- `sync_enabled` (boolean): Must be `true` for auto-sync
|
||||
- `auto_sync` (boolean): Must be `true`
|
||||
- `sync_frequency_minutes` (integer): New sync interval (5-1440)
|
||||
|
||||
**Response:**
|
||||
- `id` (string): Device UUID
|
||||
- `sync_enabled` (boolean): `true`
|
||||
- `auto_sync` (boolean): `true`
|
||||
- `sync_frequency_minutes` (integer): Updated interval
|
||||
- `next_sync_at` (string): Estimated next sync time
|
||||
- `updated_at` (string): Update timestamp
|
||||
|
||||
**Status Codes:**
|
||||
- 200: Frequency updated successfully
|
||||
- 400: Invalid frequency value
|
||||
- 401: Unauthorized
|
||||
- 403: Forbidden
|
||||
- 404: Device not found
|
||||
|
||||
**Recommended Frequencies:**
|
||||
- **Active reading:** 5-10 minutes
|
||||
- **Normal usage:** 15-30 minutes
|
||||
- **Occasional reading:** 30-60 minutes
|
||||
- **Battery saving:** 60+ minutes
|
||||
- **WiFi only (3G):** 30-60 minutes
|
||||
|
||||
**Notes:**
|
||||
- More frequent sync = more battery usage
|
||||
- Sync only occurs when device is online
|
||||
- Manual sync can be triggered anytime regardless of frequency
|
||||
@@ -0,0 +1,24 @@
|
||||
info:
|
||||
name: Regenerate Device Token - Forbidden
|
||||
type: http
|
||||
seq: 3
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{other_device_id}}/regenerate-token'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Regenerate Device Token - Forbidden
|
||||
|
||||
Tests that users cannot regenerate tokens for devices belonging to other users.
|
||||
|
||||
**Expected Behavior:** Returns 403 Forbidden when trying to regenerate token for another user's device
|
||||
|
||||
**Status Codes:**
|
||||
- 403: Forbidden (device belongs to different user)
|
||||
|
||||
**Use Case:** Verify authorization - users can only manage their own devices
|
||||
|
||||
**Setup:** Use Bearer token from user A, try to regenerate token for user B's device
|
||||
@@ -0,0 +1,24 @@
|
||||
info:
|
||||
name: Regenerate Device Token - Not Found
|
||||
type: http
|
||||
seq: 4
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/00000000-0000-0000-0000-000000000000/regenerate-token'
|
||||
auth: bearer
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Regenerate Device Token - Not Found
|
||||
|
||||
Tests that token regeneration returns 404 for non-existent devices.
|
||||
|
||||
**Expected Behavior:** Returns 404 Not Found when device UUID doesn't exist
|
||||
|
||||
**Status Codes:**
|
||||
- 404: Device not found
|
||||
|
||||
**Use Case:** Verify proper error handling for invalid device IDs
|
||||
|
||||
**Setup:** Use all-zero UUID (guaranteed to not exist in database)
|
||||
@@ -0,0 +1,22 @@
|
||||
info:
|
||||
name: Regenerate Device Token - Unauthorized
|
||||
type: http
|
||||
seq: 2
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}/regenerate-token'
|
||||
auth: none
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Regenerate Device Token - Unauthorized
|
||||
|
||||
Tests that token regeneration requires authentication.
|
||||
|
||||
**Expected Behavior:** Returns 401 Unauthorized when no Bearer token is provided
|
||||
|
||||
**Status Codes:**
|
||||
- 401: Unauthorized (missing or invalid token)
|
||||
|
||||
**Use Case:** Verify authentication is required for token regeneration
|
||||
@@ -0,0 +1,19 @@
|
||||
info:
|
||||
name: Regenerate Device Token
|
||||
type: http
|
||||
seq: 1
|
||||
http:
|
||||
method: PUT
|
||||
url: '{{base_url}}/api/devices/{{device_id}}/regenerate-token'
|
||||
auth: inherit
|
||||
body:
|
||||
type: none
|
||||
|
||||
docs: |-
|
||||
## Regenerate Device Token
|
||||
|
||||
Regenerates auth token for a device, invalidating old token immediately.
|
||||
|
||||
**Method:** PUT
|
||||
|
||||
**Endpoint:** /api/devices/{device_id
|
||||
Reference in New Issue
Block a user