Build around data people can take with them.
Media Stash is a local-first app, and its standard backup is a plain JSON document. Use the schema and rules below to validate exports, build importers, or make companion tools that work with Media Stash data.
Current schema: v13 · stable URL: /schemas/mediastash-backup-v13.schema.json
Quick start
Three steps to a safe integration.
- 01
Validate the document
Validate against the published v13 schema, then surface a useful error if a required field or identity is missing.
- 02
Preserve identity
Use provider, externalId, and mediaType together. Numeric IDs are not globally interchangeable across providers.
- 03
Keep it portable
Keep unknown fields when re-exporting, and never add API keys, tokens, passwords, or provider credentials to a standard backup. Use a separate password-encrypted credential export when a device transfer needs provider keys.
The portable backup contract.
A v13 export always carries the document version and timestamp, plus the core arrays needed to reconstruct a library. Optional arrays and settings can be omitted or emitted as empty values.
Credentials stay outside this format.
Provider API keys and secrets are not part of the normal backup contract. Media Stash can export them separately as a password-encrypted credential file; import that file through the matching API-key flow and keep its password separate from the file. The password cannot be recovered.
Top-level fields
Known fields in the v13 document.
| Field | Shape | Use |
|---|---|---|
| favorites | arrayrequired | Saved media references and display metadata. |
| watchProgress | arrayrequired | Movie and series progress, including episode coordinates. |
| readingProgress | arrayoptional | Book status and page progress. |
| collections | arrayrequired | Collection records; items are kept in collectionItems. |
| collectionItems | arrayrequired | The media rows belonging to collections. |
| followedCreators | arrayoptional | People, authors, and companies followed by the user. |
| userProfile | objectoptional | Display name, region, and metadata language only. |
| settings | objectoptional | Theme and enabled-provider preferences; never credentials. |
Identity and compatibility
Make imports predictable.
The schema describes shape; these rules describe how records should be interpreted when they move between apps or devices.
- Treat provider + externalId + mediaType as the canonical media identity.
- Keep collectionId on each collection item and make it refer to a collection in the same document.
- Treat row id values as source-local identifiers; the importing app may remap them.
- For series progress, provide
seasonNumberandepisodeNumbertogether; omit both for movies, books, and games. - Version 13 uses
mediaTypeon watch progress. Older exports may need an explicit compatibility or migration step.
Start with the smallest valid document.
Empty arrays are valid and make it easy to build an importer incrementally. Add records only after their required identity fields are known.
Get the full schema{
"version": 13,
"timestamp": "2026-08-26T12:00:00.000Z",
"sourceOwner": { "id": "local-offline-user" },
"userId": "local-offline-user",
"favorites": [],
"watchProgress": [],
"readingProgress": [],
"collections": [],
"collectionItems": [],
"followedCreators": [],
"userProfile": {
"displayName": "Offline Stasher",
"region": "US",
"metadataLanguage": "en-US"
},
"settings": {
"theme": "dark",
"providers": { "enabled": { "tmdb": true } }
}
}Questions or ideas?
Talk to the people shaping the contract.
Email developers@mediastash.app for integration questions, schema feedback, or partnership ideas.