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
| Method | Path | Purpose |
|---|---|---|
| GET | /api/kosync/healthcheck | { state: "OK" } |
| POST | /api/kosync/users/create | Register kosync credentials |
| GET | /api/kosync/users/auth | Validate X-Auth-User + X-Auth-Key |
| PUT | /api/kosync/syncs/progress | Upsert progress |
| GET | /api/kosync/syncs/progress/:document | Fetch progress |
Protocol details match the official koreader-sync-server: JSON bodies, Accept: application/vnd.koreader.v1+json, and MD5 password keys.
Setup in KOReader
- Sign in to ryOS (web) at least once with your account — that syncs an MD5
- Open Progress Sync plugin settings.
- Set Custom sync server to
https://<host>/api/kosync. - Register or Login with the same username and password as ryOS.
md5(password); the server matches it to your ryOS password.
- Prefer filename document matching when the EPUB basename matches the
/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:
| Field | Used by | Purpose |
|---|---|---|
cfi | ryOS Books (epub.js) | Native EPUB CFI for precise restore in the browser |
kosyncProgress | CrossPoint / KOReader KOSync | KO-style XPath (/body/DocFragment[N]/body/.../text()[N].offset) |
percentage | Both (fallback) | Approximate 0..1 progress when XPath/CFI conversion fails |
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
- On GET, kosync-native progress is merged with Books bookshelf progress
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/….epubvia:- cached docpath mapping
- synced
bookshelf/docmap:<path>(filenameMd5/partialMd5) - 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:
- Read a few pages on Books, wait for sync, confirm CrossPoint lands on the
- Advance on CrossPoint, sync, reopen the book in Books and confirm the same
kosyncProgress. - If XPath conversion fails for a title, both sides should still move roughly
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.