ryOS ryOS / Docs
GitHub Launch

KOReader Progress Sync (kosync)

ryOS embeds a KOReader-compatible Progress Sync server so e-ink devices (and other kosync clients) can share reading progress with the Books app.

Endpoints

Base URL (set this as the custom sync server in KOReader):

https://<your-ryos-host>/api/kosync
MethodPathPurpose
GET/api/kosync/healthcheck{ state: "OK" }
POST/api/kosync/users/createRegister kosync credentials
GET/api/kosync/users/authValidate X-Auth-User + X-Auth-Key
PUT/api/kosync/syncs/progressUpsert progress
GET/api/kosync/syncs/progress/:documentFetch progress

Protocol details match the official koreader-sync-server: JSON bodies, Accept: application/vnd.koreader.v1+json, and MD5 password keys.

Setup in KOReader

  1. Sign in to ryOS (web) at least once with your account — that syncs an MD5
of your password for KOReader auth.
  1. Open Progress Sync plugin settings.
  2. Set Custom sync server to https://<host>/api/kosync.
  3. Register or Login with the same username and password as ryOS.
KOReader sends md5(password); the server matches it to your ryOS password.
  1. Prefer filename document matching when the EPUB basename matches the
file in ryOS /Books/ (e.g. Meditations - Marcus Aurelius.epub). Binary (partial MD5) matching also works once Books has hashed the file.

Auth notes

Kosync uses your ryOS account password (via MD5 on the wire, same as the official KOReader protocol). Signing in, registering, or changing your password on ryOS refreshes the kosync key. There is no separate sync password. Registration from KOReader requires an existing ryOS account that has signed in at least once.

How it bridges to Books

Books keeps two locators for the same reading position:

FieldUsed byPurpose
cfiryOS Books (epub.js)Native EPUB CFI for precise restore in the browser
kosyncProgressCrossPoint / KOReader KOSyncKO-style XPath (/body/DocFragment[N]/body/.../text()[N].offset)
percentageBoth (fallback)Approximate 0..1 progress when XPath/CFI conversion fails
Restore precedence in Books: cfi → converted kosyncProgress → percentage. KOSync progress field: emits kosyncProgress when available. Never sends an EPUB CFI as CrossPoint progress (CrossPoint cannot navigate CFIs). When no valid XPath exists, ryOS emits a numeric placeholder (round(percentage × 10000)) and CrossPoint falls back to byte-weighted percentage.

Conversion between CFI and XPath is best-effort in the browser (UTF-16 CFI offsets vs Unicode codepoint XPath offsets; sanitizer/DOM differences). Stale XPath is cleared when relocation cannot re-derive it from the current CFI.

  • Progress is stored in Redis under integration:kosync:… (kosync-native).
  • On PUT, the server also writes Cloud Sync v2
bookshelf/progress:<path> so logged-in Books clients receive the update. CrossPoint XPath is preserved in kosyncProgress; percentage remains for fallback.
  • KOSync clients do not send reading timestamps. To prevent a delayed retry
from rolling back a newer Books update, a lower PUT is treated as a successful no-op when Books changed after the client's previous accepted PUT. Equal or forward progress is still accepted.
  • On GET, kosync-native progress is merged with Books bookshelf progress
(newer timestamp wins). On equal timestamp and percentage, a record with valid native KO XPath is preferred over a percentage placeholder.
  • Document IDs resolve to /Books/….epub via:
    1. cached docpath mapping
    2. synced bookshelf/docmap:<path> (filenameMd5 / partialMd5)
    3. filename MD5 of files in the user's files/item:/Books/… sync KV

CrossPoint / hardware verification

After deploying, open one real EPUB on ryOS Books and on CrossPoint firmware:

  1. Read a few pages on Books, wait for sync, confirm CrossPoint lands on the
same visible sentence (not only the displayed percentage).
  1. Advance on CrossPoint, sync, reopen the book in Books and confirm the same
sentence restores via kosyncProgress.
  1. If XPath conversion fails for a title, both sides should still move roughly
via percentage (byte-weighted on CrossPoint vs epub.js locations in Books).

Optional developer check: build the crossmux simulator (simulator/ in the crossmux repo) and verify generated XPaths resolve through ProgressMapper. Monitor CrossPoint heap during sync to confirm no firmware RAM regression.