Files
bookhoard/docs/developer/api/koreader/sync_bookmarks.md
T
John O'Keefe 25ef0d12ba docs(kobo,koreader,collections): Beam WO5 batch 6 — 12 endpoints
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.
2026-10-24 16:25:00 -04:00

4.6 KiB

method, path, auth, area
method path auth area
POST /api/sync/koreader/bookmarks device-token koreader

Sync Bookmarks

Sync bookmarks, notes, and highlights from a KOReader device (bidirectional — the response also returns the server's current state for the book so the device can reconcile).

Endpoint: POST /api/sync/koreader/bookmarks Auth: Device token (Bearer)

Request Body

Field Type Required Description
book_uuid string one of uuid/sha Book UUID (highest-confidence match)
book_sha256 string one of uuid/sha Full-file SHA-256 (64 hex chars); format-aware (also matches media_item_formats, so a KEPUB/PDF download matches)
bookmarks array No Bookmark objects
notes array No Note objects
highlights array No Highlight objects

At least one of book_uuid or book_sha256 is required; book_sha256 resolves through the shared BookResolver.

Bookmark / Note / Highlight Object

All three types share the same KOReader annotation shape:

Field Type Required Description
chapter int No Chapter index
datetime string No ISO 8601 creation/edit timestamp
pos0 / pos1 string No Start/end xpointer (or page:N / bare page)
page int No Page number (fallback location when pos0 is empty)
text string No Highlighted text
notes string No Note text attached to the annotation
type string No Annotation type (highlight, note, bookmark)
color string No Highlight color (highlights only) — KOReader palette name, see below
percentage float No Position within the book (0-1)
book_sha256 string No Per-annotation SHA-256; overrides the request-level book match
dedup_key string No Stable echo key; an entry whose content is unchanged from what the server previously served is recognized as an echo rather than a new edit

Color Semantics

KOReader paints highlights from a fixed palette of color names; the web reader uses hex swatches. Colors are mapped at the boundary (unmappable values fall back to yellow on both sides):

KOReader name Web hex
yellow, orange #ffd54f
green, olive #a5d6a7
cyan, blue #90caf9
purple #ce93d8
red #f48fb1
  • An echo (device re-reporting an annotation it received from the server) carries no color, so the stored web color is never clobbered.
  • A non-empty color means the user edited the highlight on the device; it is mapped to the nearest web swatch.

Example Request

{
  "book_sha256": "64-hex-char-sha256",
  "bookmarks": [
    {
      "chapter": 3,
      "datetime": "2026-08-20T10:00:00Z",
      "pos0": "/body/Doc[4]/Sec[2]",
      "page": 25,
      "text": "",
      "type": "bookmark",
      "percentage": 0.125
    }
  ],
  "highlights": [
    {
      "datetime": "2026-08-20T10:05:00Z",
      "pos0": "/body/Doc[4]/Sec[2]/text()[3]:0",
      "pos1": "/body/Doc[4]/Sec[2]/text()[3]:42",
      "text": "Text to remember",
      "notes": "Why this matters",
      "type": "highlight",
      "color": "blue",
      "dedup_key": "echo-key-from-server"
    }
  ]
}

Response (200 OK)

{
  "sync_status": "ok",
  "bookmarks_synced": 1,
  "notes_synced": 0,
  "highlights_synced": 1
}

Error Responses

Code Description
400 Invalid request, or neither uuid nor SHA provided
401 Missing/invalid device token
404 Book not found by SHA-256