ImportReadingProgressRequest
POST /api/v1/reading-progress/import request body.
A stem match (v01.cbr renamed to v01.cbz) is reported either way,
but only written when this is set: two files can share a stem, and
applying it silently risks writing progress onto the wrong one.
How a conflict between an imported value and an existing row is resolved.
Possible values: [newest, furthest, skip_existing, overwrite]
Compute and report the outcome without writing anything.
file objectrequired
The whole export: one user's reading state, self-describing enough to be matched back against a differently organised library.
codex-reading-progressseries object[]
books object[]
completions object[]
Empty when the book was never analyzed; never treated as a value to match on in that case.
v01.cbzRelative to the series folder, so a series move does not invalidate it.
Vol 01/v01.cbzprogress object
The live resume position for one book. Retains r2_progression: it is the
only place the EPUB locator survives, since sessions strip it.
sessions object[]
Omitted entirely (not an empty array) when the export was taken with
includeSessions=false.
"measured", "inferred", or "unknown".
measured"progress", "completed", or "reset".
progressexternalIds object[]
12345plugin:<name>, comicinfo, epub, or manual.
plugin:mangabakaThe series path as stored, relative to the library root.
shonen/NarutoNarutoWhen the rating was last changed. The newest conflict policy needs it
to tell a stale rating from a fresh one; a file without it never
overwrites an existing rating except under overwrite.
1How aggressively hashes are used to match a book.
Possible values: [off, verify, match]
Which libraries a series may match into. Omitted searches every
library the reader can see. Narrowing to the target library is what
lets an import run before the old library has been rescanned: two
copies of one series would otherwise both match and report
ambiguous.
When a session or completion in the file already exists as the
importer's own row but is not on a live book (its book was hard-deleted,
leaving book_id null, or the scanner marked it deleted after the file
moved), move it onto the matched book instead of skipping it.
External-id sources to try, in order, before falling back to path and then normalized name.
Omitted means every source the exported series carries, in the order the document lists them. An external id survives a rename and a move where neither the path nor the name does, so defaulting this to nothing silently downgrades every import to the two weakest steps. An explicit empty list still skips straight to path matching, for a caller that wants exactly that.
{
"acceptStemMatches": true,
"conflictPolicy": "newest",
"dryRun": true,
"file": {
"exportedAt": "2024-07-29T15:51:28.071Z",
"format": "codex-reading-progress",
"includesSessions": true,
"series": [
{
"books": [
{
"completions": [
{
"completedAt": "2024-07-29T15:51:28.071Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"startedAt": "2024-07-29T15:51:28.071Z"
}
],
"fileHash": "string",
"fileName": "v01.cbz",
"partialHash": "string",
"path": "Vol 01/v01.cbz",
"progress": {
"completed": true,
"completedAt": "2024-07-29T15:51:28.071Z",
"currentPage": 0,
"progressPercentage": 0,
"r2Progression": "string",
"startedAt": "2024-07-29T15:51:28.071Z",
"updatedAt": "2024-07-29T15:51:28.071Z"
},
"sessions": "Unknown Type: array,null"
}
],
"externalIds": [
{
"id": "12345",
"source": "plugin:mangabaka"
}
],
"libraryRelativePath": "shonen/Naruto",
"name": "Naruto",
"notes": "string",
"rating": 0,
"ratingUpdatedAt": "2024-07-29T15:51:28.071Z"
}
],
"version": 1
},
"hashMode": "off",
"libraryIds": "Unknown Type: array,null",
"reattachSessions": true,
"sourcePreference": "Unknown Type: array,null"
}