Metadata export API¶
New in 1.33.0. A read-only API that hands what MangaPixer knows about your series to another program on your network - built for MangaList, open to any client. It lists every folder (or archive) that has its own series link, with the linked record, the volume list, the Completion answer and when the information is looked at again, and it tells a client what changed since its last call.
It is built from what MangaPixer has already stored. Calling it never contacts a website, and it changes nothing: there is no write or trigger endpoint. It never returns a file-system path - folder and file names only.
Authentication¶
Every export endpoint needs one of:
- a personal access token with the
metadata:readscope, sent asAuthorization: Bearer <token>. An admin creates tokens in MangaPixer Administration; a token is shown once, and it works on the export endpoints only - nowhere else in MangaPixer. - an admin's browser login (useful to look at the answers by hand).
Never put a token in a URL. A reader account gets 403. Tokens are read-only: the export answers only GET (other methods get 405), and a token is refused on anything but GET / HEAD. GET /api/v1/export/ping answers { "ok": true, "serverTime": "...", "auth": "token" } - use it to test a token. See API tokens.
Endpoints¶
All endpoints are GET, under /api/v1/export/, and answer JSON. Times are UTC ISO 8601 with milliseconds: 2026-10-04T12:00:00.000Z.
GET /api/v1/export/libraries¶
{
"schemaVersion": 1,
"serverTime": "2026-10-04T12:00:00.000Z",
"libraries": [
{ "id": "lib0manga", "displayName": "Manga", "kind": "manga", "folderCount": 712, "itemCount": 698,
"lastScanAt": "2026-10-04T03:00:00.000Z" }
]
}
kind: the library's declared type (manga,manhwa,manhua,webtoon,comic,graphic-novel,novel), ornullwhen the library declares none (see Declared hints).folderCount: folders in the library;itemCount: items the export has for it (see below);lastScanAt: the last finished scan.
GET /api/v1/export/metadata¶
| Parameter | |
|---|---|
library |
Required: a library id from /libraries. One library per call. |
updatedSince |
Optional: only items changed at or after this time (inclusive), plus the removals since then. Without it: a full sync. |
cursor |
The nextCursor of the previous page. Repeat the other parameters unchanged. |
limit |
Items per page, 1-500 (default 200). |
include |
Optional blocks to return, comma-separated: volumes, completion, refresh. Default: all three. include= returns none. |
{
"schemaVersion": 1,
"serverTime": "2026-10-04T12:00:00.000Z",
"library": { "id": "lib0manga", "displayName": "Manga", "kind": "manga" },
"items": [ { "nodeId": "...", "...": "..." } ],
"removed": [ { "nodeId": "...", "reason": "linkCleared", "at": "2026-10-04T12:00:00.000Z" } ],
"nextCursor": null
}
A complete synthetic page - every link state, a folder and an archive, a removal, a carriedFrom, a volume list with dates, official
links - is in the repository at
contracts/samples/metadata-export-v1.json.
It is generated by a test, so it always matches what the server sends. The full schema is in the OpenAPI document
(/openapi/v1.json, contracts/openapi.json).
Items¶
An item is a live folder or archive with its own link row: Confirmed, Auto, Needs review or Don't match. Folders below a linked folder inherit its link in MangaPixer; the export lists only the node that carries the row, so a client applies the nearest-ancestor rule itself (a Don't match row stops it).
| Field | |
|---|---|
nodeId |
The node's id. A renamed or moved folder becomes a new node with a new id; an archive keeps its id when it moves, also to another library. |
nodeKind |
folder or archive (an archive that is its own work, such as a one-shot). |
carriedFrom |
The old nodeId when MangaPixer's folder carry-over moved this link from a renamed or moved folder; re-key your row instead of removing and adding it. Shown for at least the removal window. Otherwise null. |
trail |
The on-disk names from below the library root down to the node itself (["Shonen", "Series"]; an archive's trail ends with its file name). Names only, never a path. |
updatedAt |
When the export last saw this item change. |
link |
state (Confirmed, Auto, NeedsReview, DontMatch), method (search, reference, comicInfo, auto, or null), score (0-1 or null), updatedAt. |
record |
The linked record, or null - always null for Needs review and Don't match. provider is mangaupdates (or gcd for comics; ignore providers you do not know). Unit numbers such as latestChapter are exact strings ("12.5"). englishPublishers lists the English publishers with their volume / chapter totals and status. |
companions |
mangadex: the MangaDex record id, or null; anilist: { id, chapters, volumes }, or null. |
officialLinks |
Official sources from the linked MangaDex record: { kind, label, url, source: "mangadex" }, kind being publisher or store. [] until MangaPixer next reads that record (they fill in on each series' refresh schedule). |
volumes |
The per-volume list (below), or null when none is stored. |
completion |
The Completion answer (below), or null - only folders with a Confirmed or Auto link have one. |
refresh |
lastFetchedAt, intervalDays, nextDueAt: when MangaPixer read the record and looks at it again; null without a record. |
Volumes¶
"volumes": { "source": "merged", "fetchedAt": "...", "items": [
{ "volume": "1", "title": null, "chapters": { "from": "1", "to": "8" }, "englishDate": "2025-03-04",
"englishDateKind": "released", "isbn": "9780000000011", "sources": ["mangadex", "wikipedia"] } ] }
The same list MangaPixer's own Volumes view uses: MangaDex's volume list, completed from Wikipedia where MangaDex lacks volumes or
chapters, with Wikipedia's English release dates and ISBNs. source is mangadex, wikipedia or merged. Numbers are exact strings.
chapters is null when the volume's chapters are not known. englishDate may be partial (2025-07, 2025); englishDateKind is
released when the whole date is not after today, else announced.
Completion¶
{ "answer", "reason", "upgradeAvailable", "upgradeVolumes", "computedAt", "basedOnScanAt" } - the answer of the
Completion tab, computed from MangaPixer's own scan of the folder:
answer |
Meaning |
|---|---|
HaveItAll |
Finished - the original run ended and the folder holds the whole edition it collects. |
FinishedMissing |
Finished - but something released (or part of the finished edition) is not in the folder. |
UpToDate |
Everything released so far in the preferred language is here; more is still to come. |
MissingSome |
Still running, and something released in the preferred language is not here. |
CantTell |
No comparison possible; reason says why. |
reason is one of None, Running, OnHiatus, StatusUnknown, WaitingForLanguage, LanguageEditionDropped, NoNumbers,
NumberingRestarts, NothingKnownReleased, NoVolumeTotal, OneShot. upgradeVolumes: volumes released officially that the folder
holds only as chapters (the first 50); upgradeAvailable is true when there is at least one. computedAt and basedOnScanAt are the
time and the library scan of the export rebuild that last changed this item - a later rebuild that finds the same answer does not
move them (the response's serverTime says when it was checked again).
Keeping in sync¶
- Full sync: call without
updatedSinceand follownextCursoruntil it isnull. Keep the FIRST page'sserverTime. - Incremental sync: call with
updatedSince= theserverTimeyou kept, follownextCursor, keep the new first page'sserverTime.updatedSinceis inclusive and the same item may come twice - treat items as upserts. Use MangaPixer'sserverTime, never your own clock. - Removals come on the first page of an incremental call (
removed, empty on later pages and in a full sync): nodeGone: the folder or archive is gone (deleted, or renamed - a rename that carry-over could follow shows ascarriedFrominstead);linkCleared: the node is still there but no longer has its own link (it may inherit one again);movedToOtherLibrary: the node (or the folder its link was carried to) is now in another library - look for it there.
A node is never both an item and a removal in one answer.
4. 409 { "error": "fullSyncRequired" }: updatedSince lies before the window MangaPixer keeps removals for (at least 30 days, and
at least the trash retention). Do a full sync. The first call after the export was introduced, or after a client was off
for longer than the window, ends here.
MangaPixer rebuilds a library's export at most once every 5 minutes (configurable, Export:MinRebuildMinutes); calls in between are
served from the last rebuild. Only the first page of a call can start a rebuild. A rebuild between two pages only moves changed items
to the end, so following the cursor still returns every item.
Errors¶
Errors are { "error": "<code>" }.
| Status | error |
|
|---|---|---|
| 400 | libraryRequired, invalidUpdatedSince, invalidCursor, invalidInclude |
Fix the request. |
| 401 | No credentials; a token that is wrong, revoked or expired, or whose admin is no longer an active admin. The WWW-Authenticate header says Bearer error="invalid_token" when a token was refused. |
|
| 403 | Signed in with a browser login that is not an admin's (a reader account). | |
| 404 | libraryNotFound |
The library id is unknown (it may have been removed: call /libraries). |
| 409 | fullSyncRequired |
See above. |
| 429 | rate_limited, too_many_attempts |
Wait for the Retry-After header's seconds. rate_limited: this token made more requests a minute than the server allows (600 by default). too_many_attempts: too many wrong tokens came from your address; every token request from it is refused for a few minutes. |
Versioning¶
schemaVersion is 1. New fields may appear in any MangaPixer release without changing it - ignore fields you do not know. A field
is never removed or renamed, and a value never changes meaning, without raising schemaVersion; a client should refuse a higher version
than it knows.