Manifest of everything the account currently holds
The starting point of every sync cycle. Lists the current save of each character and each shared stash — anything without a current save is simply absent — with its sha256, byte size, the machine that last pushed it, and a download_path ready to use.
The client compares the manifest's sha256 against its local file: same sha, nothing to do; different sha and the server's synced_at is newer, pull it; different sha and the local file is newer, push it.
download_path and sidecars_download_path are opaque. Append them to the host and go. Do not reconstruct them.
This is the tightest budget in the API, because this is the endpoint a polling loop hits. One call per cycle is the intended shape.
Responses
-
200
The manifest. An account with nothing in it returns two empty arrays, not an error.
Field Type Description charactersarray of objectOne entry per character that has a current save, sorted by name. A character whose saves were all archived with
set_current: falsehas no current save and does not appear here.namestringfilenamestringThe name the save has on disk —
<name>.d2s.sha256stringsha256 of the current save's bytes. This is the whole sync protocol: compare it with the sha256 of your local file. Equal means in sync — do nothing.
sizeintegerSize of the current save in bytes.
synced_atstring (date-time)ISO 8601, UTC — when the server received this save. Compare against your local file's mtime to decide who is newer when the shas differ.
source_machinestring | nullThe
source_machinethe uploading client declared, ornullif it declared none.download_pathstringPath to the raw save. Use it verbatim — prepend the host, do not rebuild it from the name.
sidecarsarray of objectThe character's map-reveal sidecars. Always present; an empty array when there are none. Same sha-comparison protocol as the save itself.
filenamestringsha256stringLowercase hex sha256.
sizeintegersidecars_download_pathstringPath to the sidecar batch. Use it verbatim. Always present, even with no sidecars.
shared_stashesarray of objectOne entry per shared stash that has a current save, sorted by (mode, variant).
modestringsoftcore · hardcorevariantstringmodern · legacyfilenamestringThe name this stash has on disk. Send this exact string back as
filenameonPOST /api/v1/snapshotsand the upload lands on this same stash — the round-trip is guaranteed by construction.sizeintegersha256stringLowercase hex sha256.
synced_atstring (date-time)source_machinestring | nulldownload_pathstringPath to the raw
.d2i. Use it verbatim.One character (with map sidecars) and one shared stash
{ "characters": [ { "name": "Kristan", "filename": "Kristan.d2s", "sha256": "4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a", "size": 8447, "synced_at": "2026-07-13T18:04:21Z", "source_machine": "windows-pc", "download_path": "/api/v1/characters/Kristan/current", "sidecars": [ { "filename": "Kristan.ma0", "sha256": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b", "size": 4096 }, { "filename": "Kristan.map", "sha256": "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35", "size": 3 } ], "sidecars_download_path": "/api/v1/characters/Kristan/sidecars" } ], "shared_stashes": [ { "mode": "softcore", "variant": "modern", "filename": "ModernSharedStashSoftCoreV2.d2i", "size": 27231, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "synced_at": "2026-07-13T18:04:22Z", "source_machine": "windows-pc", "download_path": "/api/v1/stash/softcore/modern/current" } ] }A brand-new account
{ "characters": [], "shared_stashes": [] } -
401
The
Authorizationheader is missing, malformed, or carries a token that no longer exists (revoked on the Devices page, or the account was deleted).{ "error": "Invalid or missing token" } -
429
Over the rate limit for this token. No
Retry-Afteris sent; wait out the 10-minute window. Failed requests count too — the limiter runs before validation.{ "error": "Too many requests, wait before sending again" } -
503
Downloads are paused server-side (feature flag
api_download), which covers the manifest as well as the raw-bytes endpoints. Retry later with backoff.{ "error": "Downloads are temporarily disabled — try again later" }