test(bruno): sweep the collection against the actual route table

Audited every request (247 .yml files) against the routes the server
actually registers (extracted from internal/router, group prefixes
resolved). Results:

- 44 stale requests: deleted where the endpoint no longer exists
  (universal-progress GET/PUT /api/progress/:id — routes never existed,
  the handlers were deleted in H1; queue stats/clear-failed/process;
  admin profile page; auth/account) and FIXED where the endpoint exists
  under a different path (kobo token-in-path scheme: every
  /api/sync/kobo/<seg> and /api/v1/kobo/<seg> URL now carries
  {{kobo_device_token}}; /sync/* missing their /api prefix; koreader
  /api/v1/koreader/sync/* -> /api/sync/koreader/*; link-book and
  unlinked-books moved to /api/devices/:id/sync/*).
- koreader Sync Highlights/Sync Notes pointed at endpoints that never
  existed with a body shape to match — rewritten against POST
  /api/sync/koreader/bookmarks (the annotations funnel carries
  highlights and notes arrays).
- 9 files the GUI refused to load: 4 had bruno-invalid script type
  "tests" (converted to after-response), 4 were info/type:collection
  doc files with bogus http blocks (converted to folder.yml folder
  docs), 1 had a dead pre-YAML schema and no route (deleted).
- devices/koreader requests now carry request-level bearer auth
  ({{koreader_device_token}}) — they inherited the collection's user-JWT
  bearer, which device endpoints rightly reject — and their bodies
  reference {{media_item_id}} instead of dead placeholder uuids.
- environments: opds_base_url was empty (every OPDS request missed the
  /opds prefix); set to http://localhost:8765/opds and un-doubled the
  prefix in opds/scenarios.

Known limitation, for the handoff: bru CLI cannot execute .yml request
bodies (the collection is GUI OpenCollection format; the CLI runner
reads bodies from .bru files only). A .bru migration is the remaining
bruno work if CLI runs are wanted.
This commit is contained in:
John O'Keefe committed 2026-10-17 11:49:28 -04:00
1 parent 6808c1babb
commit a85bc8af9b
65 files changed
+409 -2127

No files matched your search

-39
View File
@@ -1,39 +0,0 @@
info:
name: Get Admin Profile
type: http
seq: 4
http:
method: GET
url: '{{base_url}}/admin/profile'
auth: inherit
body:
type: none
docs: |-
## Get Admin Profile
Retrieves the admin profile information for administrative access.
**Method:** GET
**Endpoint:** /admin/profile
**Authentication:** Required (Bearer token)
**Response:**
- JSON object containing admin profile details
- `id` (string): Admin user ID
- `email` (string): Admin email
- `username` (string): Admin username
- `theme` (string): Theme preference
- `first_name` (string): First name
- `last_name` (string): Last name
- `is_admin` (boolean): Admin status
- `created_at` (string): Account creation timestamp
- `updated_at` (string): Last update timestamp
**Status Codes:**
- 200: Success
- 401: Unauthorized
- 403: Forbidden (non-admin users)
- 404: Profile not found
@@ -8,40 +8,9 @@ http:
auth: inherit
body:
type: json
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"name\": \"My Favorites\"\
,\n \"icon\": \"⭐\",\n \"description\": \"My favorite books\",\n \"show_on_dashboard\"\
: true,\n \"auto_assign_rules\": \"\",\n \"manual_book_ids\": [\"{{media_item_id}}\"\
],\n \"match_type\": \"all\"\n}"
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"name\": \"My Favorites\",\n \"icon\": \"⭐\",\n \"description\": \"My favorite books\",\n \"show_on_dashboard\": true,\n \"auto_assign_rules\": \"\",\n \"manual_book_ids\": [\"{{media_item_id}}\"],\n \"match_type\": \"all\"\n}"
runtime:
scripts:
- type: tests
code: "test(\"status must be 201 with valid request\", function() {\n expect(res.status).to.eql(201);\n\
});\n\ntest(\"response contains collection id\", function() {\n expect(res.body.id).to.exist;\n\
expect(res.body.id).to.be.a('string');\n });\n\ntest(\"response contains\
\ collection name\", function() {\n expect(res.body.name).to.eql(\"My Favorites\"\
);\n });"
docs: |-
Create a custom collection with manually selected books.
**Endpoint**: POST /api/collections
**Auth**: Required (Bearer token)
## Example Request
```json
{
"library_id": "cc23c3a7-f8fb-451a-a78d-2a16df1b725a",
"name": "My Favorites",
"icon": "⭐",
"description": "My favorite books",
"show_on_dashboard": true,
"auto_assign_rules": "",
"manual_book_ids": ["book-id-1", "book-id-2"],
"match_type": "all"
}
```
## Response
Returns the created collection with generated ID.
- type: after-response
code: "function onResponse(res) {\ntest(\"status must be 201 with valid request\", function() {\n expect(res.status).to.eql(201);\n});\n\ntest(\"response contains collection id\", function() {\n expect(res.body.id).to.exist;\nexpect(res.body.id).to.be.a('string');\n });\n\ntest(\"response contains collection name\", function() {\n expect(res.body.name).to.eql(\"My Favorites\");\n });\n}"
docs: "Create a custom collection with manually selected books.\n\n**Endpoint**: POST /api/collections\n**Auth**: Required (Bearer token)\n\n## Example Request\n\n```json\n{\n \"library_id\": \"cc23c3a7-f8fb-451a-a78d-2a16df1b725a\",\n \"name\": \"My Favorites\",\n \"icon\": \"⭐\",\n \"description\": \"My favorite books\",\n \"show_on_dashboard\": true,\n \"auto_assign_rules\": \"\",\n \"manual_book_ids\": [\"book-id-1\", \"book-id-2\"],\n \"match_type\": \"all\"\n}\n```\n\n## Response\n\nReturns the created collection with generated ID."
@@ -8,16 +8,12 @@ http:
auth: inherit
body:
type: json
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"icon\": \"📚\"\
\n}"
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"icon\": \"\U0001F4DA\"\n}"
runtime:
scripts:
- type: tests
code: "test(\"status must be 400 with missing name\", function() {\n expect(res.status).to.eql(400);\n\
});\n\ntest(\"response contains error message\", function() {\n expect(res.body.error).to.exist;\n\
\ });"
- type: after-response
code: "function onResponse(res) {\ntest(\"status must be 400 with missing name\", function() {\n expect(res.status).to.eql(400);\n});\n\ntest(\"response contains error message\", function() {\n expect(res.body.error).to.exist;\n });\n}"
docs: 'Test error handling when creating a collection without required fields.
docs: |-
Test error handling when creating a collection without required fields.
**Expected Response**: 400 Bad Request with error message.
**Expected Response**: 400 Bad Request with error message.'
@@ -8,57 +8,10 @@ http:
auth: inherit
body:
type: json
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"name\": \"Science Fiction\
\ Books\",\n \"icon\": \"🚀\",\n \"description\": \"All my sci-fi books\",\n\
\ \"show_on_dashboard\": true,\n \"auto_assign_rules\": \"{\\\"rules\\\":[{\\\
\"id\\\":\\\"rule1\\\",\\\"field\\\":\\\"genre\\\",\\\"operator\\\":\\\"equals\\\"\
,\\\"value\\\":\\\"Sci-Fi\\\",\\\"priority\\\":1}]}\",\n \"manual_book_ids\"\
: [],\n \"match_type\": \"all\"\n}"
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"name\": \"Science Fiction Books\",\n \"icon\": \"\U0001F680\",\n \"description\": \"All my sci-fi books\",\n \"show_on_dashboard\": true,\n \"auto_assign_rules\": \"{\\\"rules\\\":[{\\\"id\\\":\\\"rule1\\\",\\\"field\\\":\\\"genre\\\",\\\"operator\\\":\\\"equals\\\",\\\"value\\\":\\\"Sci-Fi\\\",\\\"priority\\\":1}]}\",\n \"manual_book_ids\": [],\n \"match_type\": \"all\"\n}"
runtime:
scripts:
- type: tests
code: "test(\"status must be 201 with valid request\", function() {\n expect(res.status).to.eql(201);\n\
});\n\ntest(\"response contains collection id\", function() {\n expect(res.body.id).to.exist;\n\
expect(res.body.id).to.be.a('string');\n });\n\ntest(\"response contains\
\ collection name\", function() {\n expect(res.body.name).to.eql(\"Science\
\ Fiction Books\");\n });\n\ntest(\"response contains is_system false\", function()\
\ {\n expect(res.body.is_system).to.exist;\n expect(res.body.is_system).to.eql(false);\n\
\ });"
docs: |-
Create a custom collection with filter rules.
**Endpoint**: POST /api/collections
**Auth**: Required (Bearer token)
## Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| library_id | string | Yes | Library UUID |
| name | string | Yes | Collection name |
| icon | string | No | Emoji icon |
| description | string | No | Collection description |
| show_on_dashboard | boolean | No | Show on dashboard (default: true) |
| auto_assign_rules | string | No | JSON string of filter rules |
| manual_book_ids | array | No | Array of book IDs |
| match_type | string | No | "all" (AND) or "any" (OR) |
## Example Request
```json
{
"library_id": "cc23c3a7-f8fb-451a-a78d-2a16df1b725a",
"name": "Science Fiction Books",
"icon": "🚀",
"description": "All my sci-fi books",
"show_on_dashboard": true,
"auto_assign_rules": "{\"rules\":[{\"id\":\"rule1\",\"field\":\"genre\",\"operator\":\"equals\",\"value\":\"Sci-Fi\",\"priority\":1}]}",
"manual_book_ids": [],
"match_type": "all"
}
```
## Response
Returns the created collection with generated ID.
- type: after-response
code: "function onResponse(res) {\ntest(\"status must be 201 with valid request\", function() {\n expect(res.status).to.eql(201);\n});\n\ntest(\"response contains collection id\", function() {\n expect(res.body.id).to.exist;\nexpect(res.body.id).to.be.a('string');\n });\n\ntest(\"response contains collection name\", function() {\n expect(res.body.name).to.eql(\"Science Fiction Books\");\n });\n\ntest(\"response contains is_system false\", function() {\n expect(res.body.is_system).to.exist;\n expect(res.body.is_system).to.eql(false);\n });\n}"
docs: "Create a custom collection with filter rules.\n\n**Endpoint**: POST /api/collections\n**Auth**: Required (Bearer token)\n\n## Request Body\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| library_id | string | Yes | Library UUID |\n| name | string | Yes | Collection name |\n| icon | string | No | Emoji icon |\n| description | string | No | Collection description |\n| show_on_dashboard | boolean | No | Show on dashboard (default: true) |\n| auto_assign_rules | string | No | JSON string of filter rules |\n| manual_book_ids | array | No | Array of book IDs |\n| match_type | string | No | \"all\" (AND) or \"any\" (OR) |\n\n## Example Request\n\n```json\n{\n \"library_id\": \"cc23c3a7-f8fb-451a-a78d-2a16df1b725a\",\n \"name\": \"Science Fiction Books\",\n \"icon\": \"\U0001F680\",\n \"description\": \"All my sci-fi books\",\n \"show_on_dashboard\": true,\n \"auto_assign_rules\": \"{\\\"rules\\\":[{\\\"id\\\":\\\"rule1\\\",\\\"field\\\":\\\
\"genre\\\",\\\"operator\\\":\\\"equals\\\",\\\"value\\\":\\\"Sci-Fi\\\",\\\"priority\\\":1}]}\",\n \"manual_book_ids\": [],\n \"match_type\": \"all\"\n}\n```\n\n## Response\n\nReturns the created collection with generated ID."
+4 -48
View File
@@ -8,53 +8,9 @@ http:
auth: inherit
body:
type: json
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"rules\": [\n\
{\n \"id\": \"rule1\",\n \"field\": \"genre\",\n\
\"operator\": \"equals\",\n \"value\": \"Fiction\",\n\
\"priority\": 1\n }\n ],\n \"manual_book_ids\": [],\n \"limit\": 20\n}"
jsonBody: "{\n \"library_id\": \"{{library_id}}\",\n \"rules\": [\n{\n \"id\": \"rule1\",\n \"field\": \"genre\",\n\"operator\": \"equals\",\n \"value\": \"Fiction\",\n\"priority\": 1\n }\n ],\n \"manual_book_ids\": [],\n \"limit\": 20\n}"
runtime:
scripts:
- type: tests
code: "test(\"status must be 200 with valid request\", function() {\n expect(res.status).to.eql(200);\n\
});\n\ntest(\"response contains items array\", function() {\n expect(res.body.items).to.exist;\n\
expect(res.body.items).to.be.an('array');\n });"
docs: |-
Preview collection with filter rules before saving.
**Endpoint**: POST /api/collections/preview
**Auth**: Required (Bearer token)
## Request Body
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| library_id | string | Yes | Library UUID |
| rules | array | No | Filter rules to evaluate |
| manual_book_ids | array | No | Manually selected book IDs |
| limit | int | No | Max items to return (default: 20, max: 100) |
## Example Request
```json
{
"library_id": "cc23c3a7-f8fb-451a-a78d-2a16df1b725a",
"rules": [
{
"id": "rule1",
"field": "genre",
"operator": "equals",
"value": "Fiction",
"priority": 1
}
],
"manual_book_ids": [],
"limit": 20
}
```
## Response
Returns array of matching book items.
This endpoint is used by the Custom Section Builder to show users what books will match their filter rules before they save the collection.
- type: after-response
code: "function onResponse(res) {\ntest(\"status must be 200 with valid request\", function() {\n expect(res.status).to.eql(200);\n});\n\ntest(\"response contains items array\", function() {\n expect(res.body.items).to.exist;\nexpect(res.body.items).to.be.an('array');\n });\n}"
docs: "Preview collection with filter rules before saving.\n\n**Endpoint**: POST /api/collections/preview\n**Auth**: Required (Bearer token)\n\n## Request Body\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| library_id | string | Yes | Library UUID |\n| rules | array | No | Filter rules to evaluate |\n| manual_book_ids | array | No | Manually selected book IDs |\n| limit | int | No | Max items to return (default: 20, max: 100) |\n\n## Example Request\n\n```json\n{\n \"library_id\": \"cc23c3a7-f8fb-451a-a78d-2a16df1b725a\",\n \"rules\": [\n {\n \"id\": \"rule1\",\n \"field\": \"genre\",\n \"operator\": \"equals\",\n \"value\": \"Fiction\",\n \"priority\": 1\n }\n ],\n \"manual_book_ids\": [],\n \"limit\": 20\n}\n```\n\n## Response\n\nReturns array of matching book items.\n\nThis endpoint is used by the Custom Section Builder to show users what books will match their filter rules before they save the collection."
-22
View File
@@ -1,22 +0,0 @@
info:
name: Bookhoard Device Management API
type: collection
seq: 1
http:
method: POST
url: '"http://localhost:8765/api"'
docs: |-
## Bookhoard Device Management API
Collection of endpoints for managing e-reader devices and their synchronization settings.
**Base URL:** http://localhost:8765/api
**Authentication:** Most endpoints require Bearer token authentication
**Endpoints:**
- Device registration and management
- Device authentication tokens
- Sync configuration
- Device-to-collection mappings
+7
View File
@@ -0,0 +1,7 @@
info:
name: Bookhoard Device Management API
type: folder
seq: 1
request:
auth: inherit
docs: "## Bookhoard Device Management API\n\n Collection of endpoints for managing e-reader devices and their synchronization settings.\n\n **Base URL:** http://localhost:8765/api\n\n **Authentication:** Most endpoints require Bearer token authentication\n\n **Endpoints:**\n - Device registration and management\n - Device authentication tokens\n - Sync configuration\n - Device-to-collection mappings"
+1 -1
View File
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/v1/analytics/gettests'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/v1/analytics/gettests'
auth: inherit
headers:
- key: Content-Type
+1 -1
View File
@@ -5,7 +5,7 @@ info:
http:
method: GET
url: '{{base_url}}/api/sync/kobo/library'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/v1/initialization'
auth: inherit
docs: |-
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: GET
url: '{{base_url}}/sync/unlinked-books/{{unlinkedBookId}}/suggestions'
url: '{{base_url}}/api/sync/unlinked-books/{{unlinkedBookId}}/suggestions'
auth: inherit
body:
type: none
-22
View File
@@ -1,22 +0,0 @@
info:
name: Bookhoard Kobo Sync API
type: collection
seq: 1
http:
method: POST
url: '"http://localhost:8765/api"'
docs: |-
## Bookhoard Kobo Sync API
Collection of endpoints specifically for Kobo e-reader device synchronization.
**Base URL:** http://localhost:8765/api
**Authentication:** Device token or Bearer token required
**Endpoints:**
- Kobo-specific sync protocols
- Kobo store integration
- Metadata synchronization
- Reading progress sync
+7
View File
@@ -0,0 +1,7 @@
info:
name: Bookhoard Kobo Sync API
type: folder
seq: 1
request:
auth: inherit
docs: "## Bookhoard Kobo Sync API\n\n Collection of endpoints specifically for Kobo e-reader device synchronization.\n\n **Base URL:** http://localhost:8765/api\n\n **Authentication:** Device token or Bearer token required\n\n **Endpoints:**\n - Kobo-specific sync protocols\n - Kobo store integration\n - Metadata synchronization\n - Reading progress sync"
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: POST
url: '{{base_url}}/sync/auto-link-books'
url: '{{base_url}}/api/sync/auto-link-books'
auth: inherit
body:
type: json
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: POST
url: '{{base_url}}/sync/bulk-link-books'
url: '{{base_url}}/api/sync/bulk-link-books'
auth: inherit
body:
type: json
@@ -5,7 +5,7 @@ info:
http:
method: GET
url: '{{base_url}}/api/sync/kobo/v1/initialization'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/v1/initialization'
auth: inherit
docs: |-
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: POST
url: '{{baseURL}}/api/sync/kobo/sync-from-server'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/sync-from-server'
auth: inherit
body:
type: json
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/sync-from-server'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/sync-from-server'
auth: inherit
headers:
- key: Content-Type
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/markup'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/markup'
auth: inherit
headers:
- key: Content-Type
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/markup'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/markup'
auth: inherit
headers:
- key: Content-Type
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/markup'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/markup'
auth: inherit
headers:
- key: Content-Type
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/bookmark'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/bookmark'
auth: inherit
headers:
- key: Content-Type
@@ -5,7 +5,7 @@ info:
http:
method: POST
url: '{{base_url}}/api/sync/kobo/markup'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/markup'
auth: inherit
headers:
- key: Content-Type
@@ -4,7 +4,7 @@ info:
seq: 3
http:
method: POST
url: '{{base_url}}/api/v1/kobo/bookmark'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/bookmark'
auth: inherit
body:
type: json
@@ -4,7 +4,7 @@ info:
seq: 4
http:
method: GET
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/v1/initialization'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/v1/initialization'
auth: none
body:
type: none
@@ -4,7 +4,7 @@ info:
seq: 3
http:
method: GET
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/library'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/v1/initialization'
auth: none
body:
type: none
@@ -4,7 +4,7 @@ info:
seq: 4
http:
method: GET
url: '{{base_url}}/api/sync/unlinked-books'
url: '{{base_url}}/api/devices/{{device_id}}/sync/unlinked-books'
auth: inherit
body:
type: none
@@ -1,34 +0,0 @@
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
+1 -1
View File
@@ -4,7 +4,7 @@ info:
seq: 5
http:
method: POST
url: '{{base_url}}/api/sync/link-book'
url: '{{base_url}}/api/devices/{{device_id}}/sync/link-book'
auth: inherit
body:
type: json
@@ -1,52 +0,0 @@
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
@@ -4,7 +4,7 @@ info:
seq: 2
http:
method: POST
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/bookmark'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/bookmark'
auth: none
body:
type: json
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: POST
url: '{{base_url}}/sync/kobo/{{kobo_device_token}}/markup'
url: '{{base_url}}/api/sync/kobo/{{kobo_device_token}}/markup'
auth: none
body:
type: json
+11 -89
View File
@@ -1,92 +1,14 @@
info:
name: Get Book Metadata
type: http
seq: 8
docs: "## Get KOReader Book Metadata\n\nRetrieves metadata for a specific book from the server.\n\n**Method:** GET\n\n**Endpoint:** /api/sync/koreader/metadata/:book_uuid\n\n**Authentication:** Bearer token\n\n**Path Parameters:**\n- `book_uuid` (string): SHA-256 based book identifier\n\n**Response:**\n- `uuid` (string): Book UUID (SHA-256)\n- `title` (string): Book title\n- `authors` (array): Author names\n- `series` (string, optional): Series name\n- `series_index` (number, optional): Position in series\n- `publisher` (string, optional): Publisher name\n- `publication_date` (string, optional): Release date\n- `language` (string, optional): ISO 639-1 language code\n- `description` (string, optional): Book description\n- `cover_url` (string, optional): Cover image URL\n- `cover_thumbnail_url` (string, optional): Thumbnail URL\n- `identifiers` (object): Various identifiers\n - `isbn` (string, optional): ISBN-13\n - `asin` (string, optional): Amazon ASIN\n - `goodreads` (string, optional):\
\ Goodreads ID\n - `google_books` (string, optional): Google Books ID\n- `metadata_sources` (array): Sources metadata was pulled from\n- `last_synced` (string): Last metadata sync timestamp\n- `file_metadata` (object):\n - `file_size` (integer): File size in bytes\n - `format` (string): File format (epub, pdf, mobi, etc.)\n - `pages` (integer, optional): Page count\n - `word_count` (integer, optional): Estimated words\n\n**Status Codes:**\n- 200: Success\n- 401: Unauthorized\n- 404: Book not found\n\n**Metadata Purpose:**\n- Enrich book information on device\n- Improve book organization\n- Enable better search\n- Support series sorting\n- Provide cover images\n- Link to external sources\n\n**KOReader Usage:**\n- Display in book info dialog\n- Used for library sorting\n- Shown in file browser\n- Series grouping\n- Cover display\n- Search optimization\n\n**SHA-256 Book ID:**\n- Primary identifier in KOReader\n- Universal across devices\n- Format-independent\n- Generated from file content\n\
- Survives metadata changes\n\n**Metadata Sources:**\n- Google Books API\n- Open Library\n- Goodreads API\n- ISBN database lookup\n- Publisher metadata\n- User-provided metadata\n\n**Use Cases:**\n- Initial book import\n- Metadata refresh\n- Cover image download\n- Series organization\n- Duplicate detection\n- Library management"
http:
headers: []
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Get Book Metadata
seq: 8
type: http
+11 -31
View File
@@ -1,34 +1,14 @@
info:
name: KOReader Get Library
type: http
seq: 3
docs: "## KOReader Get Library\n\n Retrieves the user's library for KOReader sync operations.\n\n **Method:** GET\n\n **Endpoint:** /api/sync/koreader/library\n\n **Authentication:** Bearer token (device token)\n\n **Response:**\n - `library_sync` (object): Library sync data\n - `total_books` (number): Total number of books\n - `books` (array): Array of book objects\n\n **Status Codes:**\n - 200: Success\n - 401: Unauthorized\n - 500: Internal server error"
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
headers: []
method: GET
url: '{{base_url}}/api/sync/koreader/library'
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: KOReader Get Library
seq: 3
type: http
@@ -1,103 +1,15 @@
info:
name: Get User Library for KOReader
type: http
seq: 9
docs: "## Get KOReader User Library\n\nRetrieves the user's book library for KOReader device sync.\n\n**Method:** GET\n\n**Endpoint:** /api/sync/koreader/library\n\n**Authentication:** Bearer token (koreader_device_token)\n\n**Query Parameters:**\nNone (returns entire library)\n\n**Response:**\n- `books` (array): Library items\n - `uuid` (string): SHA-256 based book identifier\n - `title` (string): Book title\n - `authors` (array): Author names\n - `series` (string, optional): Series name\n - `series_index` (number, optional): Series position\n - `publisher` (string, optional): Publisher\n - `publication_date` (string, optional): Release date\n - `language` (string, optional): Language code\n - `description` (string, optional): Description\n - `cover_url` (string, optional): Cover image URL\n - `cover_thumbnail_url` (string, optional): Thumbnail URL\n - `file_metadata` (object):\n - `format` (string): File format\n - `file_size` (integer): Size in bytes\n - `pages` (integer,\
\ optional): Page count\n - `progress` (object, optional): Reading progress\n - `percentage` (number): Progress 0-100\n - `last_read` (string): Last read timestamp\n - `epubcfi` (string): Current position\n - `annotations_count` (object, optional): Annotation stats\n - `highlights` (integer): Highlight count\n - `notes` (integer): Note count\n - `bookmarks` (integer): Bookmark count\n- `library_info` (object):\n - `total_books` (integer): Total book count\n - `last_sync` (string): Last library sync timestamp\n - `has_updates` (boolean): Updates available\n- `user_info` (object):\n - `user_id` (string): User identifier\n - `email` (string): Email (masked)\n - `libraries` (array): Available library IDs\n\n**Status Codes:**\n- 200: Success\n- 401: Unauthorized\n- 403: Device not approved\n\n**Library Purpose for KOReader:**\n- Discover books available for download\n- Browse catalog on device\n- Sync reading progress across books\n- Download covers/metadata\n- Series-based\
\ organization\n- Cloud library access\n\n**KOReader Device Features:**\n- **OPDS catalog**: Native OPDS client\n- **File browser**: See server books\n- **Cloud download**: Download books on-demand\n- **Metadata sync**: Automatic metadata fetching\n- **Cover images**: Display in library view\n- **Progress sync**: See progress across all books\n- **Search**: Search library by title/author\n\n**KOReader-Specific Features:**\n- SHA-256 based book IDs\n- Multi-format support (EPUB, FB2, PDF, DJVU, MOBI, etc.)\n- Series sorting and grouping\n- Language filtering\n- Cover image caching\n- Metadata for file browser enhancement\n- Integration with KOReader's OPDS client\n\n**Performance:**\n- Typical response: 100-500KB for 100 books\n- Processing time: 300ms-1s\n- Cache duration: 5 minutes\n- Pagination support for libraries >500 books\n\n**Use Cases:**\n- Initial device setup\n- Library browsing on device\n- Book download\n- Metadata refresh\n- Cover image sync\n- Progress overview\n- Series-based\
\ reading"
http:
headers: []
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Get User Library for KOReader
seq: 9
type: http
-22
View File
@@ -1,22 +0,0 @@
info:
name: Bookhoard KOReader Sync API
type: collection
seq: 1
http:
method: POST
url: '"http://localhost:8765/api"'
docs: |-
## Bookhoard KOReader Sync API
Collection of endpoints specifically for KOReader e-reader device synchronization.
**Base URL:** http://localhost:8765/api
**Authentication:** Device token or Bearer token required
**Endpoints:**
- KOReader-specific sync protocols
- Metadata synchronization
- Reading progress sync
- Highlights and notes sync
+7
View File
@@ -0,0 +1,7 @@
info:
name: Bookhoard KOReader Sync API
type: folder
seq: 1
request:
auth: inherit
docs: "## Bookhoard KOReader Sync API\n\n Collection of endpoints specifically for KOReader e-reader device synchronization.\n\n **Base URL:** http://localhost:8765/api\n\n **Authentication:** Device token or Bearer token required\n\n **Endpoints:**\n - KOReader-specific sync protocols\n - Metadata synchronization\n - Reading progress sync\n - Highlights and notes sync"
@@ -1,123 +1,29 @@
info:
name: Checkpoint Sync
type: http
seq: 11
docs: "## Checkpoint Sync\n\nIncremental sync using checkpoint-based change tracking.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `sync_mode` (string): Must be `checkpoint`\n- `checkpoint_id` (string): Unique checkpoint identifier\n- `since_timestamp` (string): ISO 8601 timestamp for incremental sync\n- `books` (array): Book progress items\n - `uuid` (string): Book UUID\n - `percentage` (number): Progress 0.0-1.0\n - `chapter` (integer): Current chapter\n - `epubcfi` (string, optional): Current position\n - `modified_since` (boolean, optional): Whether modified since checkpoint\n\n**Response:**\n- `checkpoint_id` (string): Server checkpoint ID\n- `checkpoint_timestamp` (string): Checkpoint creation time\n- `processed` (integer): Books processed\n- `changes_only` (boolean): Whether only changed items synced\n- `next_checkpoint_id` (string): ID for next checkpoint sync\n- `results` (array): Per-book results\n\
\n**Status Codes:**\n- 200: Checkpoint sync completed\n- 401: Unauthorized\n- 400: Invalid checkpoint or timestamp\n\n**Checkpoint Sync Benefits:**\n- **Incremental**: Only sync changed items\n- **Efficient**: Smaller payloads\n- **Fast**: Reduced processing time\n- **Reliable**: Checkpoint-based tracking\n- **Resumable**: Can continue from last checkpoint\n\n**Checkpoint Mechanism:**\n- Server tracks changes since checkpoint\n- Client provides checkpoint ID or timestamp\n- Only modified books returned/processed\n- Checkpoint ID advances on each sync\n- Supports large libraries efficiently\n\n**Use Cases:**\n- Large libraries (100+ books)\n- Intermittent connectivity\n- Bandwidth optimization\n- Battery conservation\n- Background sync\n- Periodic sync (every 5-15 minutes)\n\n**Checkpoint Lifecycle:**\n1. Initial sync: No checkpoint (full sync)\n2. Server returns checkpoint_id\n3. Next sync: Client sends checkpoint_id\n4. Server processes only changes\n5. New checkpoint_id returned\n6.\
\ Repeat from step 3\n\n**Sync Optimization:**\n- Only books with progress changes\n- Skips unmodified books\n- Delta transfer\n- Compression for large payloads\n- Batch processing\n\n**Failure Handling:**\n- Checkpoint ID preserved on failure\n- Retry with same checkpoint\n- Full sync if checkpoint expired\n- Checkpoint validity: 24 hours\n- Auto-fallback to full sync\n\n**Performance:**\n- Small changes (1-10 books): 100-300ms\n- Medium changes (10-50 books): 300ms-1s\n- Large changes (50-100 books): 1-3s\n- Typical: 5-10x faster than full sync\n\n**When to Use:**\n- Default sync mode for most users\n- Periodic background sync\n- Large library management\n- Mobile/network-constrained environments\n- Battery-powered devices\n\n**Configuration:**\n- Checkpoint expiration: 24 hours\n- Max history: 100 checkpoints\n- Auto-cleanup of old checkpoints\n- Configurable sync interval"
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
books:
- chapter: 3
percentage: 0.45
uuid: '{{media_item_id}}'
- chapter: 8
percentage: 0.75
uuid: '{{media_item_id}}'
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
sync_mode: checkpoint
type: json
headers:
- key: Content-Type
value: application/json
method: POST
url: '{{base_url}}/api/sync/koreader/progress'
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Checkpoint Sync
seq: 11
type: http
@@ -1,105 +1,25 @@
info:
name: Immediate Sync - Page Turn
type: http
seq: 10
docs: "## Immediate Sync - Page Turn\n\nReal-time progress sync triggered immediately on page turn.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `sync_mode` (string): Must be `immediate`\n- `books` (array): Current book progress\n - `uuid` (string): Book UUID\n - `percentage` (number): Precise progress (0.45678 = 45.678%)\n - `chapter` (integer): Current chapter\n - `timestamp` (string): ISO 8601 timestamp\n - `epubcfi` (string, optional): Current position\n - `page` (integer, optional): Current page\n\n**Response:**\n- `synced` (boolean): Immediate sync status\n- `timestamp` (string): Server timestamp\n- `next_sync_suggested` (string): Suggested next sync time\n\n**Status Codes:**\n- 200: Sync queued\n- 202: Accepted for processing\n- 401: Unauthorized\n- 429: Too many immediate sync requests (rate limited)\n\n**Immediate Sync Mode:**\n- **Purpose**: Real-time progress updates\n- **Trigger**: Every page\
\ turn (configurable)\n- **Priority**: High priority processing\n- **Latency**: <100ms typical\n- **Best effort**: May be queued under load\n\n**Rate Limiting:**\n- Max 60 requests per minute per device\n- Throttled after limit reached\n- Suggests switching to periodic sync\n- Prevents server overload\n\n**Use Cases:**\n- Real-time multi-device reading\n- Live progress sharing\n- Instant position backup\n- Critical reading points\n- Test/profiling mode\n\n**Performance:**\n- Ultra-fast sync\n- Minimal payload\n- Optimized for speed\n- Async processing\n- No confirmation wait\n\n**Battery Considerations:**\n- More frequent network use\n- Higher battery consumption\n- WiFi recommended\n- Can reduce sync frequency in settings\n\n**Configuration:**\n- Can enable/disable per device\n- Adjustable frequency (every page, every N pages)\n- Automatic fallback to periodic sync on error\n- Respects device power-save mode\n\n**When to Use:**\n- Critical reading sessions\n- Multi-device concurrent reading\n\
- Research and study\n- Testing sync functionality\n- When power source available\n\n**When NOT to Use:**\n- Battery conservation needed\n- Unstable network\n- Extended reading sessions\n- Background sync preferred"
http:
body:
json:
books:
- chapter: 3
percentage: 0.45678
timestamp: '2026-01-30T20:00:00Z'
uuid: '{{media_item_id}}'
sync_mode: immediate
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Immediate Sync - Page Turn
seq: 10
type: http
@@ -1,44 +1,15 @@
docs: "## KOReader Sync Annotations - Per-Book SHA-256\n\n Synchronizes annotations (highlights) from KOReader with per-annotation SHA-256 hashes for multi-book sync.\n\n **Method:** POST\n\n **Endpoint:** /api/v1/koreader/sync/bookmarks\n\n **Authentication:** Bearer token (KOReader device token)\n\n **Request Body:**\n - `book_uuid` (string): Primary book UUID\n - `highlights` (array): Array of highlight objects\n - `text` (string): Highlighted text\n - `pos0`, `pos1` (string): EPUB CFI positions\n - `color` (string): Highlight color (hex)\n - `page` (number): Page number\n - `book_sha256` (string): SHA-256 hash for this specific book\n\n **Response:**\n - `highlights_synced` (number): Number of highlights synced\n\n **Status Codes:**\n - 200: Success\n - 401: Unauthorized\n - 500: Internal server error\n\n **Note:** Each highlight can include its own book_sha256, allowing annotations from multiple books in a single request."
http:
body:
jsonBody: "{\n \"book_uuid\": \"{{book_uuid"
type: json
headers: []
method: POST
url: '{{base_url}}/api/sync/koreader/bookmarks'
auth:
type: bearer
token: '{{koreader_device_token}}'
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.
type: http
@@ -1,40 +1,15 @@
docs: "## KOReader Sync Bookmarks - SHA-256\n\n Synchronizes bookmarks, notes, and highlights from KOReader using SHA-256 hash for book identification.\n\n **Method:** POST\n\n **Endpoint:** /api/v1/koreader/sync/bookmarks\n\n **Authentication:** Bearer token (KOReader device token)\n\n **Request Body:**\n - `book_sha256` (string): SHA-256 hash of book file\n - `bookmarks` (array): Array of bookmarks\n - `notes` (array): Array of notes\n - `highlights` (array): Array of highlights\n\n **Response:**\n - `sync_status` (string): Sync status\n - `total_synced` (number): Total items synced\n\n **Status Codes:**\n - 200: Success\n - 401: Unauthorized\n - 500: Internal server error"
http:
body:
jsonBody: "{\n \"book_sha256\": \"{{book_sha256"
type: json
headers: []
method: POST
url: '{{base_url}}/api/sync/koreader/bookmarks'
auth:
type: bearer
token: '{{koreader_device_token}}'
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
type: http
@@ -1,105 +1,31 @@
info:
name: Sync Bookmarks
type: http
seq: 5
docs: "## Sync KOReader Bookmarks\n\nSynchronizes bookmarks separately from progress for KOReader.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/bookmarks\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Books with bookmarks\n - `uuid` (string): Book UUID\n - `bookmarks` (array): Bookmark items\n - `chapter` (integer): Chapter number\n - `datetime` (string): ISO 8601 timestamp\n - `notes` (string): Bookmark description\n - `pos0` (string): EPUB CFI start position\n - `pos1` (string): EPUB CFI end position\n - `page` (integer): Page number\n - `text` (string): Displayed text\n - `type` (string): `bookmark`, `highlight`, or `note`\n\n**Response:**\n- `synced` (integer): Number of bookmarks synced\n- `duplicates_skipped` (integer): Duplicate bookmarks skipped\n- `results` (array): Per-bookmark results\n- `timestamp` (string): Sync timestamp\n\n**Status Codes:**\n- 200: Success\n\
- 401: Unauthorized\n- 400: Invalid data\n\n**Dedicated Bookmark Endpoint:**\n- **Purpose**: Sync bookmarks independently\n- **Use case**: More frequent bookmark updates\n- **Advantage**: Separate from progress sync\n- **Efficiency**: Smaller payloads\n\n**KOReader Bookmark Features:**\n- Chapter-based organization\n- Quick navigation markers\n- Hierarchical bookmarks (via plugins)\n- Custom bookmark titles\n- Date/time tracking\n- EPUB CFI precision\n\n**Bookmark Types in KOReader:**\n- **Location bookmarks**: Quick navigation points\n- **Chapter marks**: Auto-generated chapter markers\n- **Progress bookmarks**: Last read positions\n- **Custom bookmarks**: User-created markers\n- **Search bookmarks**: Saved search results\n\n**Sync Behavior:**\n- Duplicate detection by position + text\n- Most recent wins on conflicts\n- Chapter order preserved\n- Auto-generated vs manual bookmarks differentiated\n- Merge with existing bookmarks\n\n**KOReader Device Integration:**\n- Created via \"Add\
\ bookmark\" menu\n- Shown in \"Bookmarks\" panel\n- Quick access via \"Go to bookmark\"\n- Exportable to JSON\n- Can be edited/deleted\n\n**Use Cases:**\n- Quick navigation aids\n- Chapter markers\n- Important passages\n- Reading progress points\n- Study session markers"
http:
body:
json:
books:
- bookmarks:
- chapter: 3
datetime: '2026-01-30T19:55:00Z'
notes: Marked this chapter as important
page: 45
pos0: epubcfi(/6/4/2:15)
pos1: epubcfi(/6/4/2:20)
text: Important passage
type: bookmark
uuid: '{{media_item_id}}'
library_id: optional-library-uuid
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Bookmarks
seq: 5
type: http
@@ -1,110 +1,19 @@
info:
name: Sync Highlights
type: http
seq: 6
docs: "## Sync KOReader Highlights\n\nSynchronizes text highlights separately from other annotations.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/highlights\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Books with highlights\n - `uuid` (string): Book UUID\n - `highlights` (array): Highlight items\n - `datetime` (string): Creation timestamp\n - `text` (string): Highlighted text content\n - `chapter` (integer): Chapter number\n - `pos0` (string): EPUB CFI start position\n - `pos1` (string): EPUB CFI end position\n - `page_start` (integer): Start page\n - `page_end` (integer): End page\n - `color` (string, optional): Color name or hex\n - `note` (string, optional): Attached note\n\n**Response:**\n- `synced` (integer): Highlights synced\n- `duplicates_skipped` (integer): Duplicates found\n- `with_notes` (integer): Highlights that have notes attached\n- `timestamp` (string):\
\ Sync timestamp\n\n**KOReader Highlight Features:**\n- Precise text selection (EPUB CFI)\n- Custom color support (via plugins)\n- Multi-page highlights\n- Chapter references\n- Timestamps for sorting\n- Attached notes support\n- Full text preservation\n\n**Highlight Colors (via plugins):**\n- Yellow (default): General highlighting\n- Green: Important concepts\n- Blue: Key information\n- Red/pink: Critical content\n- Orange: Interesting quotes\n- Custom RGB colors available\n\n**EPUB CFI Advantages:**\n- Precise start/end positions\n- Works across font size changes\n- Survives text reflow\n- Device-independent\n- Standardized format\n\n**Dedicated Highlight Endpoint:**\n- **Separate from progress**: Sync highlights independently\n- **Smaller payload**: Just highlights, no progress\n- **More frequent**: Can sync highlights immediately\n- **Focused**: Single-purpose endpoint\n\n**Sync Behavior:**\n- Exact text matching for duplicates\n- Position-based conflict resolution\n- Color preservation\
\ across devices\n- Note attachments preserved\n- Order maintained by position\n\n**KOReader Device Features:**\n- Created via long-press or selection\n- Color picker available\n- Can add notes immediately\n- Shows in \"Highlights\" panel\n- Exportable to Evernote, etc.\n- Searchable by content\n\n**Use Cases:**\n- Study and research\n- Content curation\n- Quote collection\n- Academic work\n- Sharing insights"
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
jsonBody: "{\n \"book_uuid\": \"786b9c39-e8c3-47ab-a48a-c7f6cd769930\",\n \"highlights\": [\n {\n \"datetime\": \"2026-01-30T19:50:00Z\",\n \"text\": \"bruno sweep highlight\",\n \"chapter\": 1,\n \"page\": 1,\n \"pos0\": \"1\",\n \"pos1\": \"9\",\n \"color\": \"#ffff00\"\n }\n ]\n}"
headers:
- key: Content-Type
value: application/json
method: POST
url: '{{base_url}}/api/sync/koreader/bookmarks'
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Highlights
seq: 6
type: http
+16 -105
View File
@@ -1,108 +1,19 @@
docs: "## Sync KOReader Notes\n\nSynchronizes user notes separately from highlights and bookmarks.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/notes\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Books with notes\n - `uuid` (string): Book UUID\n - `notes` (array): Note items\n - `datetime` (string): Creation/modification timestamp\n - `text` (string): Note content\n - `chapter` (integer): Chapter number\n - `pos0` (string, optional): Related EPUB CFI position\n - `page` (integer, optional): Page number\n - `highlighted_text` (string, optional): Related highlight\n\n**Response:**\n- `synced` (integer): Notes synced\n- `duplicates_skipped` (integer): Duplicate notes found\n- `attached_to_highlights` (integer): Notes linked to highlights\n- `timestamp` (string): Sync timestamp\n\n**KOReader Note Features:**\n- Free-form text notes\n- Can be standalone or attached to highlights\n- Chapter-based\
\ organization\n- Timestamped for sorting\n- Markdown support (some versions)\n- Longer form content\n- No character limit\n\n**Note Types:**\n- **Standalone notes**: Independent notes about chapter/section\n- **Attached notes**: Notes attached to specific highlights\n- **Chapter notes**: Notes about entire chapter\n- **Book notes**: General notes about the book\n\n**Dedicated Notes Endpoint:**\n- **Separate sync**: Notes sync independently\n- **Flexible**: Not tied to highlights\n- **Efficient**: Smaller, focused payload\n- **Immediate**: Can sync right after note creation\n\n**Attached Notes:**\n- Linked to specific highlight\n- Shares highlight's position\n- Shown together with highlight\n- Deleted when highlight deleted (optional)\n- Color matches highlight\n\n**Sync Behavior:**\n- Text-based duplicate detection\n- Time-based conflict resolution\n- Chapter organization preserved\n- Markdown formatting preserved\n- Attachment links maintained\n\n**KOReader Device Integration:**\n- Created\
\ via \"Add note\" option\n- Edited in note editor\n- Shown in \"Notes\" panel\n- Can be organized by chapter\n- Export functionality available\n- Search support\n\n**Advanced Features:**\n- **Markdown**: Bold, italic, lists (some versions)\n- **Tags**: User-defined tags (via plugins)\n- **Links**: Internal/external links\n- **Formatting**: Rich text in newer versions\n\n**Use Cases:**\n- Study notes\n- Personal reflections\n- Academic annotations\n- Research insights\n- Book club discussion prep\n- Knowledge management"
http:
body:
jsonBody: "{\n \"book_uuid\": \"{{media_item_id}}\",\n \"notes\": [\n {\n \"datetime\": \"2026-01-30T19:52:00Z\",\n \"notes\": \"A personal note about this chapter\",\n \"chapter\": 4,\n \"page\": 57,\n \"pos0\": \"3\"\n }\n ]\n}"
type: json
headers:
- key: Content-Type
value: application/json
method: POST
url: '{{base_url}}/api/sync/koreader/bookmarks'
auth:
type: bearer
token: '{{koreader_device_token}}'
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
type: http
@@ -1,47 +1,15 @@
docs: "## KOReader Sync Progress - SHA-256 Only\n\n Synchronizes reading progress using only SHA-256 hash for book identification (when UUID is not available).\n\n **Method:** POST\n\n **Endpoint:** /api/v1/koreader/sync/progress\n\n **Authentication:** Bearer token (KOReader device token)\n\n **Request Body:**\n - `sync_mode` (string): Sync mode (immediate, deferred)\n - `books` (array): Array of book progress objects\n - `sha256` (string): SHA-256 hash of book file\n - `file_path` (string): Path to book file\n - `percentage` (number): Progress percentage\n - `page` (number): Current page\n - `total_pages` (number): Total pages\n\n **Response:**\n - `sync_status` (string): Sync status\n - `books_synced` (number): Number of books synced\n\n **Status Codes:**\n - 200: Success\n - 202: Accepted\n - 401: Unauthorized\n - 500: Internal server error\n\n **Note:** Use this when book UUID is not available, falling back to SHA-256 hash for identification."
http:
body:
jsonBody: "{\n \"sync_mode\": \"immediate\",\n \"books\": [\n {\n \"sha256\": \"{{book_sha256"
type: json
headers: []
method: POST
url: '{{base_url}}/api/sync/koreader/progress'
auth:
type: bearer
token: '{{koreader_device_token}}'
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.
type: http
@@ -1,51 +1,16 @@
docs: "## KOReader Sync Progress - SHA-256\n\n Synchronizes reading progress from a KOReader device using SHA-256 book hash for identification.\n\n **Method:** POST\n\n **Endpoint:** /api/v1/koreader/sync/progress\n\n **Authentication:** Bearer token (KOReader device token)\n\n **Request Body:**\n - `sync_mode` (string): Sync mode (immediate, deferred)\n - `books` (array): Array of book progress objects\n - `uuid` (string): Book UUID\n - `sha256` (string): SHA-256 hash of book file for identification\n - `file_path` (string): Path to book file on device\n - `percentage` (number): Progress percentage (0-1)\n - `chapter` (number): Current chapter\n - `page` (number): Current page\n - `total_pages` (number): Total pages\n - `epubcfi` (string): EPUB location\n - `last_read` (string): ISO 8601 timestamp\n - `title` (string): Book title\n - `authors` (array): List of authors\n\n **Response:**\n - `sync_status` (string): Sync status\n - `books_synced`\
\ (number): Number of books synced\n\n **Status Codes:**\n - 200: Success\n - 202: Accepted - processing\n - 401: Unauthorized\n - 500: Internal server error"
http:
body:
jsonBody: "{\n \"sync_mode\": \"immediate\",\n \"books\": [\n {\n \"uuid\": \"{{book_uuid"
type: json
headers: []
method: POST
url: '{{base_url}}/api/sync/koreader/progress'
auth:
type: bearer
token: '{{koreader_device_token}}'
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
type: http
@@ -1,90 +1,38 @@
info:
name: Sync Progress - Multiple Books
type: http
seq: 2
docs: "## Sync KOReader Progress - Multiple Books\n\nSynchronizes reading progress for multiple books in a single request.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Multiple book progress items\n - Each item contains: uuid, title, authors, progress, percentage, last_read, chapter, epubcfi\n\n**Response:**\n- `synced` (integer): Number of books successfully synced\n- `failed` (integer): Number of books that failed\n- `results` (array): Per-book sync results\n- `timestamp` (string): Sync timestamp\n\n**Status Codes:**\n- 200: Batch sync completed\n- 207: Multi-status (partial success)\n- 401: Unauthorized\n- 413: Payload too large\n\n**Batch Sync Advantages:**\n- Efficient sync of entire library\n- Single HTTP request for multiple books\n- Faster periodic sync\n- Reduced battery usage vs individual syncs\n- Better for batch processing\n\n**KOReader\
\ Batch Behavior:**\n- Triggered on device wake from sleep\n- Occurs during \"Sync now\" operation\n- Runs on WiFi connection\n- Limited to 100 books per request\n- Automatic retry on failed books\n\n**Performance:**\n- Small batch (2-10 books): 200-500ms\n- Medium batch (10-50 books): 500ms-2s\n- Large batch (50-100 books): 2-5s\n- Timeout: 30 seconds\n\n**Use Cases:**\n- Device initialization sync\n- Periodic background sync\n- Post-offline catch-up sync\n- Library-wide progress update\n- Before firmware update"
http:
body:
json:
books:
- authors:
- Author One
chapter: 1
epubcfi: epubcfi(/6/4/2:10)
last_read: '2026-01-30T19:00:00Z'
percentage: 0.25
progress: 0.25
title: Book One
uuid: '{{media_item_id}}'
- authors:
- Author Two
chapter: 8
epubcfi: epubcfi(/6/4/2:50)
last_read: '2026-01-30T20:00:00Z'
percentage: 0.75
progress: 0.75
title: Book Two
uuid: '{{media_item_id}}'
library_id: optional-library-uuid
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Progress - Multiple Books
seq: 2
type: http
@@ -1,92 +1,31 @@
info:
name: Sync Progress - Single Book
type: http
seq: 1
docs: "## Sync KOReader Progress - Single Book\n\nSynchronizes reading progress for a single book from KOReader device.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token (koreader_device_token)\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID for multi-library setups\n- `books` (array): Array with single book progress\n - `uuid` (string): Unique book identifier (often SHA-256 hash)\n - `title` (string): Book title\n - `authors` (array): List of authors\n - `progress` (number): Progress decimal (0.0 to 1.0)\n - `percentage` (number): Progress percentage (0.45 = 45%)\n - `last_read` (string): ISO 8601 timestamp of last read\n - `chapter` (integer): Current chapter number\n - `epubcfi` (string): EPUB Canonical Fragment Identifier\n - `character` (integer): Character position in book\n - `page` (integer, optional): Current page number\n\n**Response:**\n- `synced` (integer): Number of books synced\n- `timestamp`\
\ (string): Server sync timestamp\n- `books` (array): Sync results\n - `uuid` (string): Book UUID\n - `status` (string): `synced`, `updated`, `skipped`\n - `server_progress` (object): Server-side progress data\n\n**Status Codes:**\n- 200: Success\n- 401: Unauthorized\n- 400: Invalid request format\n\n**KOReader Progress Tracking:**\n- SHA-256 based book identification (universal across devices)\n- EPUB CFI for precise location (standard format)\n- Chapter-based navigation\n- Character-level precision\n- Supports EPUB, FB2, PDF, DJVU, MOBI formats\n\n**EPUB CFI Format:**\n- Standardized location format for EPUBs\n- Example: `epubcfi(/6/4/2:15)`\n- Identifies exact position even after reflow\n- Works across different devices/apps\n- Preserved after file modifications\n\n**Book Identification:**\n- Primary: SHA-256 hash of book file\n- Universal: Same book = same UUID across devices\n- Format-agnostic: Works for any supported format\n- Case-sensitive: Hash must match exactly\n\n**Use Cases:**\n\
- Real-time page turn sync\n- Progress backup\n- Cross-device continuity\n- Reading time tracking\n- Chapter completion detection"
http:
body:
json:
books:
- authors:
- Author Name
chapter: 3
character: 15432
epubcfi: epubcfi(/6/4/2:15)
last_read: '2026-01-30T20:00:00Z'
percentage: 0.45
progress: 0.45
title: Book Title
uuid: '{{media_item_id}}'
library_id: optional-library-uuid
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Progress - Single Book
seq: 1
type: http
@@ -1,106 +1,37 @@
info:
name: Sync Progress - With Bookmarks
type: http
seq: 3
docs: "## Sync Progress with Bookmarks\n\nSynchronizes reading progress with bookmarks/highlights from KOReader.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Books with progress and bookmarks\n - `uuid`, `title`, `authors`, `progress`, etc.\n - `bookmarks` (array): Bookmark items\n - `chapter` (integer): Chapter number\n - `datetime` (string): ISO 8601 timestamp\n - `notes` (string): Note content or highlighted text\n - `pos0` (string): EPUB CFI start position\n - `pos1` (string): EPUB CFI end position\n - `page` (integer): Page number\n - `text` (string): Displayed text excerpt\n - `type` (string): `highlight`, `bookmark`, or `note`\n\n**Response:**\n- `progress_synced` (integer): Progress items synced\n- `bookmarks_synced` (integer): Bookmark items synced\n- `highlights_synced` (integer): Highlight count\n- `timestamp`\
\ (string): Sync timestamp\n\n**KOReader Bookmark Types:**\n- **highlight**: Selected text passages\n- **bookmark**: Location markers\n- **note**: Text annotations (can be attached to highlights)\n\n**KOReader Highlight Features:**\n- Custom colors (via color extensions)\n- Multi-color support\n- Precise EPUB CFI positioning\n- Chapter-based organization\n- Text excerpts preserved\n- Date/time stamped\n- Page number tracking\n\n**EPUB CFI in Bookmarks:**\n- `pos0`: Start position (highlight start)\n- `pos1`: End position (highlight end)\n- Exact text selection boundaries\n- Survives text reflow\n- Works across different font sizes\n\n**Sync Behavior:**\n- Duplicate detection by text + position\n- Most recent edit wins\n- Chapter references maintained\n- Order preserved from device\n- Merges with existing server bookmarks\n\n**KOReader Device Integration:**\n- Created in KOReader highlight interface\n- Shows in \"Bookmarks\" menu\n- Can be edited/deleted on device\n- Exportable to JSON/XML\n\
- Searchable by content\n\n**Use Cases:**\n- Study and research\n- Content review\n- Passage tracking\n- Quick navigation\n- Cross-device bookmark access"
http:
body:
json:
books:
- authors:
- Author Name
bookmarks:
- chapter: 3
datetime: '2026-01-30T19:55:00Z'
notes: highlighted text
page: 45
pos0: epubcfi(/6/4/2:15)
pos1: epubcfi(/6/4/2:20)
text: highlighted text excerpt
type: highlight
last_read: '2026-01-30T20:00:00Z'
percentage: 0.45
progress: 0.45
title: Book Title
uuid: '{{media_item_id}}'
library_id: optional-library-uuid
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Progress - With Bookmarks
seq: 3
type: http
@@ -1,117 +1,40 @@
info:
name: Sync Progress - With Highlights and Notes
type: http
seq: 4
docs: "## Sync Progress with Highlights and Notes\n\nSynchronizes reading progress with separate highlights and notes arrays.\n\n**Method:** POST\n\n**Endpoint:** /api/sync/koreader/progress\n\n**Authentication:** Bearer token\n\n**Request Body:**\n- `library_id` (string, optional): Library UUID\n- `books` (array): Books with progress and annotations\n - `uuid`, `title`, `authors`, `progress`, `percentage`, `last_read`\n - `highlights` (array): Text highlights\n - `datetime` (string): Creation timestamp\n - `text` (string): Highlighted text content\n - `chapter` (integer): Chapter number\n - `pos0` (string): EPUB CFI start\n - `pos1` (string): EPUB CFI end\n - `page_start` (integer): Start page\n - `page_end` (integer): End page\n - `color` (string, optional): Highlight color\n - `notes` (array): Notes\n - `datetime` (string): Creation timestamp\n - `text` (string): Note content\n - `chapter` (integer): Chapter number\n - `pos0` (string, optional):\
\ Related position\n\n**Response:**\n- `progress_synced` (boolean): Progress sync status\n- `highlights_synced` (integer): Highlights synced\n- `notes_synced` (integer): Notes synced\n- `conflicts_resolved` (integer): Conflict count\n- `timestamp` (string): Sync timestamp\n\n**KOReader Annotation Model:**\n- **Separate arrays**: Highlights and notes stored separately\n- **Linked**: Notes can reference highlights\n- **Rich metadata**: Timestamps, positions, page numbers\n- **Flexible**: Supports complex annotations\n\n**Highlight Features:**\n- Multi-color highlighting (via plugins)\n- Precise text selection with EPUB CFI\n- Page range tracking\n- Chapter references\n- Timestamps for sorting\n- Full text preserved\n\n**Note Features:**\n- Free-form text notes\n- Can be standalone or attached\n- Chapter-based organization\n- Timestamped\n- Longer form than highlights\n- Support for markdown (some versions)\n\n**Color Support (via plugins):**\n- Yellow: Default highlight\n- Green: Important\
\ passages\n- Blue: Key concepts\n- Red: Critical information\n- Orange: Interesting quotes\n- Custom colors available\n\n**Sync Advantages:**\n- Separation allows granular control\n- Highlights sync without notes\n- Notes sync independently\n- Better conflict resolution\n- Efficient for large annotation sets\n\n**Use Cases:**\n- Academic research\n- Study groups\n- Content analysis\n- Personal knowledge management\n- Sharing insights"
http:
body:
json:
books:
- authors:
- Author Name
highlights:
- chapter: 4
datetime: '2026-01-30T19:50:00Z'
page_end: 79
page_start: 78
pos0: epubcfi(/6/4/2:20)
pos1: epubcfi(/6/4/2:30)
text: Important passage
last_read: '2026-01-30T20:00:00Z'
notes:
- chapter: 4
datetime: '2026-01-30T19:52:00Z'
text: My note about this chapter
percentage: 0.6
progress: 0.6
title: Book Title
uuid: '{{media_item_id}}'
library_id: optional-library-uuid
type: json
headers:
- key: Content-Type
value: application/json
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: Sync Progress - With Highlights and Notes
seq: 4
type: http
@@ -1,53 +1,16 @@
info:
name: KOReader Sync Progress
type: http
seq: 1
docs: "## KOReader Sync Progress\n\n Synchronizes reading progress from a KOReader device to the Bookhoard server.\n\n **Method:** POST\n\n **Endpoint:** /api/sync/koreader/progress\n\n **Authentication:** Bearer token (device token)\n\n **Request Body:**\n - `library_id` (string, optional): Library UUID\n - `books` (array): Array of book progress objects\n - `uuid` (string): Book UUID\n - `title` (string): Book title\n - `authors` (array): List of authors\n - `progress` (number): Progress value\n - `percentage` (number): Percentage complete (0-1)\n - `last_read` (string): ISO 8601 timestamp\n - `chapter` (number): Current chapter\n - `epubcfi` (string): EPUB Canonical Fragment Identifier\n - `page` (number): Current page\n - `total_pages` (number): Total pages\n - `sync_mode` (string): Sync mode (immediate, deferred)\n - `device_info` (object): Device information\n - `koreader_version` (string): KOReader version\n - `device_model` (string): Device\
\ model identifier\n\n **Response:**\n - `sync_status` (string): Sync status (accepted, processing)\n - `books_synced` (number): Number of books synced\n\n **Status Codes:**\n - 202: Accepted - sync queued\n - 401: Unauthorized\n - 500: Internal server error"
http:
body:
jsonBody: "{\n \"library_id\": null,\n \"books\": [\n {\n \"uuid\": \"{{book_uuid"
type: json
headers: []
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
auth:
type: bearer
token: '{{koreader_device_token}}'
info:
name: KOReader Sync Progress
seq: 1
type: http
+1 -1
View File
@@ -23,7 +23,7 @@ variables:
- name: library_folder
value: /app/uploads
- name: opds_base_url
value: ""
value: http://localhost:8765/opds
- secret: true
name: token
- secret: true
-52
View File
@@ -1,52 +0,0 @@
meta:
name: Browse library folders
type: http
seq: 1
config:
test:
filter: "response.status == 200"
assertions:
- type: stddev
target: response_time
threshold: 1000
- type: jsonpath
expression: response.directories
condition: exists
- type: jsonpath
expression: response.current_path
condition: exists
- type: jsonpath
expression: response.parent_path
condition: exists
req:
method: GET
url: "{{base_url}}/api/libraries/browse?path=/tmp"
headers:
Authorization: "Bearer {{ADMIN_TOKEN}}"
docs: |-
## Browse Library Folders
Navigates through the filesystem to browse folders for library configuration.
**Method:** GET
**Endpoint:** /api/libraries/browse
**Authentication:** Required (Bearer token, Admin only)
**Query Parameters:**
- `path` (string, required): Filesystem path to browse
**Response:**
- `current_path` (string): Current browsing path
- `parent_path` (string): Parent directory path
- `directories` (array): List of subdirectories
- `files` (array): List of files (optional)
**Status Codes:**
- 200: Success
- 400: Invalid path
- 401: Unauthorized
- 403: Forbidden (admin access required)
- 404: Path not found
@@ -4,7 +4,7 @@ info:
seq: 3
http:
method: GET
url: '{{opds_base_url}}/opds/devices/{{device_id}}/download/{{book_id}}?token={{device_token}}'
url: '{{opds_base_url}}/devices/{{device_id}}/download/{{book_id}}?token={{device_token}}'
docs: |-
## Download Book - Query Token
@@ -4,7 +4,7 @@ info:
seq: 1
http:
method: GET
url: '{{opds_base_url}}/opds/devices/{{device_id}}/catalog'
url: '{{opds_base_url}}/devices/{{device_id}}/catalog'
docs: |-
## Get Device OPDS Catalog - Bearer
@@ -4,7 +4,7 @@ info:
seq: 2
http:
method: GET
url: '{{opds_base_url}}/opds/devices/{{device_id}}/catalog?token={{device_token}}'
url: '{{opds_base_url}}/devices/{{device_id}}/catalog?token={{device_token}}'
docs: |-
## Get Device OPDS Catalog - Query Token
-87
View File
@@ -1,87 +0,0 @@
info:
name: Clear Failed Items
type: http
seq: 8
http:
method: DELETE
url: '{{base_url}}/api/queue/clear-failed'
auth: inherit
docs: |-
## Clear Failed Queue Items
Removes all failed queue items from the queue.
**Method:** DELETE
**Endpoint:** /api/queue/clear-failed
**Authentication:** Required (Bearer token)
**Query Parameters:**
- `older_than` (string, optional): ISO 8601 duration - e.g., `7d`, `24h`, `60m`
- `device_id` (string, optional): Only clear items from specific device
- `type` (string, optional): Only clear specific item type
**Request Body:**
Optional filters:
```json
{
"older_than": "7d",
"device_id": "uuid",
"type": "progress"
}
```
**Response:**
- `deleted_count` (integer): Number of items deleted
- `items_cleared` (array): IDs of cleared items
- `retained_count` (integer): Items not matching filters
- `cleared_at` (string): Deletion timestamp
**Status Codes:**
- 200: Items cleared successfully
- 401: Unauthorized
- 400: Invalid filter parameters
**Deletion Behavior:**
- Removes failed items from queue
- Does not affect pending/processing/completed items
- Permanent deletion (cannot be undone)
- Logs deletion for audit trail
- Updates queue statistics
**Safety Features:**
- Default filter prevents clearing recent failures
- Per-device filtering for targeted cleanup
- Type filtering for selective clearing
- Confirmation required for large deletions
**Recommended Usage:**
- **Daily:** Clear failures older than 7 days
- **Weekly:** Clear all failed items
- **Per-device:** After removing problematic device
- **Per-type:** After fixing specific sync issue
**Use Cases:**
- Clean up old failed sync attempts
- Reduce queue database size
- Remove stuck error items
- Prepare for fresh sync attempts
- Clear items for decommissioned devices
- Reset after bug fixes
**Warnings:**
- Cannot be undone
- Failed items cleared permanently
- Consider retrying before clearing
- May hide recurring issues if overused
- Check logs before bulk clearing
**Best Practices:**
- Review error patterns before clearing
- Fix root causes before cleanup
- Use time-based filters to preserve recent failures
- Document reasons for clearing
- Monitor failure rates after cleanup
-83
View File
@@ -1,83 +0,0 @@
info:
name: Get Queue Statistics
type: http
seq: 9
http:
method: GET
url: '{{base_url}}/api/queue/stats'
auth: inherit
docs: |-
## Get Queue Statistics
Retrieves overall queue performance and status metrics.
**Method:** GET
**Endpoint:** /api/queue/stats
**Authentication:** Required (Bearer token)
**Query Parameters:**
None (all stats returned)
**Response:**
- `overview` (object):
- `total_items` (integer): All items in queue
- `pending` (integer): Items awaiting processing
- `processing` (integer): Items currently being processed
- `completed` (integer): Successfully processed items
- `failed` (integer): Failed items
- `by_type` (object):
- `progress` (object): Progress item counts
- `note` (object): Note item counts
- `highlight` (object): Highlight item counts
- `bookmark` (object): Bookmark item counts
- `by_status` (object):
- `pending`: Count by type
- `processing`: Count by type
- `completed`: Count by type
- `failed`: Count by type
- `performance` (object):
- `avg_processing_time_ms` (number): Average processing duration
- `throughput_per_minute` (number): Items processed per minute
- `success_rate` (number): Percentage of successful processing
- `failure_rate` (number): Percentage of failures
- `timing` (object):
- `oldest_pending_age_seconds` (integer): Age of oldest pending item
- `longest_processing_time_ms` (integer): Longest current processing time
- `peak_queue_size_today` (integer): Maximum queue size today
- `devices` (array): Top 5 devices by queue activity
- `device_id` (string): Device UUID
- `device_name` (string): Device name
- `item_count` (integer): Items in queue from this device
- `retention` (object):
- `completed_items_30_days` (integer): Completed items in retention period
- `purge_scheduled_at` (string): Next auto-purge time
- `generated_at` (string): Statistics generation timestamp
**Status Codes:**
- 200: Success
- 401: Unauthorized
**Cache Behavior:**
- Statistics cached for 60 seconds
- Real-time data may vary slightly
- Use `?refresh=true` to bypass cache
**Use Cases:**
- Monitor queue health
- Identify performance bottlenecks
- Track processing capacity
- Alert on failures
- Capacity planning
- SLA monitoring
- Dashboard metrics
**Key Metrics to Watch:**
- **Success Rate:** Should be >95%
- **Avg Processing Time:** Depends on type
- **Oldest Pending:** Should be <5 minutes
- **Failed Items:** Investigate if >5%
- **Throughput:** Baseline for capacity planning
@@ -4,7 +4,7 @@ info:
seq: 2
http:
method: GET
url: '{{base_url}}/queue/items?limit=50&offset=0'
url: '{{base_url}}/api/queue/items?limit=50&offset=0'
auth: inherit
body:
type: none
-74
View File
@@ -1,74 +0,0 @@
info:
name: Process Queue Item
type: http
seq: 7
http:
method: POST
url: '{{base_url}}/api/queue/items/{{queue_item_id}}/process'
auth: inherit
docs: |-
## Process Queue Item
Manually trigger processing of a specific queue item.
**Method:** POST
**Endpoint:** /api/queue/items/:queue_item_id/process
**Authentication:** Required (Bearer token)
**Path Parameters:**
- `queue_item_id` (string): UUID of the queue item to process
**Request Body:**
Empty or optional:
- `priority` (integer, optional): Override processing priority (0-10)
- `force` (boolean, optional): Re-process even if completed
**Response:**
- `id` (string): Queue item UUID
- `status` (string): New status - `processing` or `queued`
- `type` (string): Item type
- `message` (string): Processing initiation message
- `estimated_duration_ms` (integer): Expected processing time
- `started_at` (string): Processing start time
- `previous_status` (string): Status before processing
**Status Codes:**
- 200: Processing started
- 202: Queued for processing
- 401: Unauthorized
- 404: Queue item not found
- 409: Item already being processed
- 422: Invalid item state
**Processing Behavior:**
- Item moves from `pending` to `processing`
- Can override priority for faster processing
- Force re-processing of completed/failed items
- Updates item's `last_attempt` timestamp
- Increments `retry_count` for failed items
- Validates data before processing
- Executes item-specific handlers
**Use Cases:**
- Retry failed sync items
- Expedite high-priority updates
- Re-process completed items (e.g., after fix)
- Debug queue processing
- Manual intervention for stuck items
- Test specific sync operations
**Processing States:**
- `pending` → `processing` → `completed` or `failed`
- Processing can take 1-30 seconds depending on type
- WebSocket notifications sent on completion
- Automatic retry on transient failures
**Notes:**
- Does not guarantee immediate processing
- Queue workers pick up items based on priority
- Multiple manual processes queue sequentially
- Use WebSocket for real-time updates
-38
View File
@@ -1,38 +0,0 @@
info:
name: Bookhoard Sync Queue API
type: collection
seq: 1
http:
method: GET
url: '"http://localhost:8765/api"'
docs: |-
## Bookhoard Sync Queue API
Collection of endpoints for managing the synchronization queue that handles
background processing of sync operations between devices and the server.
**Base URL:** http://localhost:8765/api
**Authentication:** Bearer token required for most endpoints
**Endpoints:**
- Queue item management (create, process, retry, delete)
- Queue statistics and monitoring
- Device-specific queue operations
- Filtering by type (highlights, notes, bookmarks, progress)
- Filtering by status (pending, completed, failed)
- Bulk operations (clear device queue, clear failed items)
**Queue Item Types:**
- `highlight`: Highlight synchronization
- `note`: Note synchronization
- `bookmark`: Bookmark synchronization
- `progress`: Reading progress synchronization
**Queue Status Values:**
- `pending`: Awaiting processing
- `processing`: Currently being processed
- `completed`: Successfully processed
- `failed`: Processing failed (retryable)
- `cancelled`: Item was cancelled
+8
View File
@@ -0,0 +1,8 @@
info:
name: Bookhoard Sync Queue API
type: folder
seq: 1
request:
auth: inherit
docs: "## Bookhoard Sync Queue API\n\n Collection of endpoints for managing the synchronization queue that handles\n background processing of sync operations between devices and the server.\n\n **Base URL:** http://localhost:8765/api\n\n **Authentication:** Bearer token required for most endpoints\n\n **Endpoints:**\n - Queue item management (create, process, retry, delete)\n - Queue statistics and monitoring\n - Device-specific queue operations\n - Filtering by type (highlights, notes, bookmarks, progress)\n - Filtering by status (pending, completed, failed)\n - Bulk operations (clear device queue, clear failed items)\n\n **Queue Item Types:**\n - `highlight`: Highlight synchronization\n - `note`: Note synchronization\n - `bookmark`: Bookmark synchronization\n - `progress`: Reading progress synchronization\n\n **Queue Status Values:**\n - `pending`: Awaiting processing\n - `processing`: Currently being processed\n - `completed`: Successfully processed\n - `failed`:\
\ Processing failed (retryable)\n - `cancelled`: Item was cancelled"
@@ -4,7 +4,7 @@ info:
seq: 3
http:
method: GET
url: '{{base_url}}/queue/items?status=pending'
url: '{{base_url}}/api/queue/items?status=pending'
auth: inherit
body:
type: none
@@ -1,22 +0,0 @@
info:
name: Get Universal Progress
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/progress/{{mediaItemId}}'
auth: inherit
body:
type: none
headers:
- key: Authorization
value: Bearer {{jwt
docs: |-
## Get Universal Progress
Retrieves universal reading progress for a specific media item across all devices.
**Method:** GET
**Endpoint:** /api/progress/{mediaItemId
@@ -1,24 +0,0 @@
info:
name: Update Universal Progress
type: http
seq: 2
http:
method: POST
url: '{{base_url}}/api/progress/{{mediaItemId}}'
auth: inherit
body:
type: json
jsonBody: "{\n \"source\": \"web\",\n \"location\": {\n \"percentage\"\
: 0.45,\n \"page\": 90,\n \"total_pages\": 200"
headers:
- key: Authorization
value: Bearer {{jwt
docs: |-
## Update Universal Progress
Updates universal reading progress for a media item from a specific device or source.
**Method:** POST
**Endpoint:** /api/progress/{mediaItemId
@@ -1,19 +0,0 @@
info:
name: Delete User Account (Admin)
type: http
seq: 6
http:
method: DELETE
url: '{{base_url}}/api/auth/account?user_id={{user_id}}'
auth: inherit
body:
type: none
docs: |-
## Delete User Account (Admin)
Allows administrators to delete any user account by specifying user_id parameter.
**Method:** DELETE
**Endpoint:** /api/auth/account?user_id={user_id