Kobo emulation + KOReader calibre-compatible surface backfilled with
device-token auth; collections reorder + update_rule created.
Claude registry: 12 entries. kobo/koreader emulation endpoints all bind
arbitrary protocol POST bodies (markup/bookmark/gettests/sync-from-server,
koreader progress/bookmarks) — registered as AnyJSONObject, not bodyless as
first drafted. Initialization returns the library sync payload, not the init
response.
Contract correction in update_rule.md: the route is SetRuleEnabled ({enabled}
required -> {collection_id, is_smart}); Beam's draft invented rule-field
updates. Reordered response/status: {item_ids} -> {status: reordered}.
make test 9/9.
77 lines
2.4 KiB
Markdown
77 lines
2.4 KiB
Markdown
---
|
|
method: GET
|
|
path: /api/sync/koreader/metadata/:uuid
|
|
auth: device-token
|
|
area: koreader
|
|
---
|
|
<!-- source: internal/handlers/koreader.go:1025 KOReaderHandler.GetMetadata -->
|
|
|
|
# Get Metadata
|
|
|
|
Get a book's stored progress and annotations for a KOReader device —
|
|
the pull half of the device sync. The reference client calls this after
|
|
linking a book via [Resolve Book](resolve_book.md) and navigates to the
|
|
returned position.
|
|
|
|
**Endpoint**: `GET /api/sync/koreader/metadata/:uuid`
|
|
**Auth**: Required (Device authentication — `Authorization: Bearer {device_token}`)
|
|
|
|
## Path Parameters
|
|
|
|
| Parameter | Type | Required | Description |
|
|
| --------- | ------------- | -------- | ----------- |
|
|
| uuid | string (UUID) | Yes | Book UUID |
|
|
|
|
### Example Request
|
|
|
|
```http
|
|
GET /api/sync/koreader/metadata/774641f9-317b-4087-8e04-53bb4392ae56
|
|
Authorization: Bearer {device_token}
|
|
```
|
|
|
|
## Response (200 OK)
|
|
|
|
```json example-response
|
|
{
|
|
"uuid": "774641f9-317b-4087-8e04-53bb4392ae56",
|
|
"title": "1984",
|
|
"author": "George Orwell",
|
|
"progress": {
|
|
"percentage": 0.045,
|
|
"koreader_xpointer": "/body/DocFragment[1]/body/p[29]/text().598",
|
|
"chapter": null,
|
|
"chapter_progress": null,
|
|
"page": null,
|
|
"total_pages": null
|
|
},
|
|
"annotations": {
|
|
"highlights": []
|
|
}
|
|
}
|
|
```
|
|
|
|
### Progress Object
|
|
|
|
| Field | Type | Description |
|
|
| ----- | ---- | ----------- |
|
|
| `percentage` | float | Stored position as a book fraction. |
|
|
| `koreader_xpointer` | string | The stored canonical position converted back to a CRE xpointer (UTF-16 `text().N` offset). **The device should navigate to this.** Reflowable books only. |
|
|
| `epubcfi` | string | The stored canonical CFI, when the conversion to a CRE xpointer is unavailable. Fallback after `koreader_xpointer`. |
|
|
| `character` | int | Book-wide rune offset (internal currency). |
|
|
| `chapter`, `chapter_progress` | int, float | Chapter position when known. |
|
|
| `page`, `total_pages` | int | Fixed-layout page position — the canonical locator for image-based books (CFI/xpointer are omitted for them). |
|
|
|
|
`progress` is `null` when the book has no stored progress.
|
|
|
|
The `annotations` object carries device-format highlights/bookmarks/notes
|
|
synced from other clients; its presence depends on annotation sync being
|
|
enabled.
|
|
|
|
## Error Responses
|
|
|
|
| Code | Description |
|
|
| ---- | ----------- |
|
|
| 400 | Invalid book UUID |
|
|
| 401 | Device authentication failed |
|
|
| 404 | Book not found |
|