Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/rommapp/romm/llms.txt

Use this file to discover all available pages before exploring further.

RomM stores save files and save states server-side, making your game progress accessible from any device. The Saves API manages .sav and related files created by emulators during gameplay, while the States API manages full save-state snapshots (emulator memory dumps). Both support optional screenshot attachments and device-based sync tracking.

Save Files

POST /api/saves

Upload a save file for a ROM. Accepts multipart/form-data. Required scope: assets.write
rom_id
integer
required
Internal ID of the ROM this save belongs to.
emulator
string
Emulator identifier (e.g. mgba, snes9x). Used to organise saves by emulator.
slot
string
Save slot label (e.g. slot1, auto). When set, RomM appends a datetime tag to the filename so multiple saves per slot are preserved.
device_id
string
Device UUID to associate with this upload. Requires devices.write scope. Enables sync-conflict detection.
session_id
integer
Sync session ID for operation counting.
overwrite
boolean
default:"false"
When true, skips conflict detection and overwrites the existing save unconditionally.
autocleanup
boolean
default:"false"
When true, automatically deletes old saves beyond autocleanup_limit in the same slot.
autocleanup_limit
integer
default:"10"
Maximum number of saves to keep per slot when autocleanup=true.
saveFile
file
required
The save file to upload.
screenshotFile
file
Optional screenshot to associate with this save (shown in the continue-playing rail).
curl -X POST "http://localhost:8080/api/saves?rom_id=42&emulator=mgba&slot=slot1" \
  -H "Authorization: Bearer <token>" \
  -F "saveFile=@/path/to/save.sav"
Response: SaveSchema object.
id
integer
Internal save ID.
rom_id
integer
Associated ROM ID.
user_id
integer
Owner user ID.
file_name
string
Stored filename (may include datetime tag for slot saves).
file_path
string
Directory path on the server.
file_size_bytes
integer
File size in bytes.
emulator
string | null
Emulator the save was created with.
slot
string | null
Slot label.
content_hash
string | null
Hash of the file content for deduplication.
is_public
boolean
Whether the save is publicly downloadable.
device_syncs
array
List of device sync records showing which devices have this save and whether they are current.
created_at
string
ISO 8601 creation timestamp.
updated_at
string
ISO 8601 last-updated timestamp.
When device_id is provided and the slot already contains a newer save since the device’s last sync, the upload is rejected with 409 Conflict to prevent overwriting progress. Pass overwrite=true to bypass this guard.

GET /api/saves

List save files for the current user. Required scope: assets.read
rom_id
integer
Filter to saves for a specific ROM.
platform_id
integer
Filter to saves for all ROMs on a platform.
device_id
string
Filter with device sync information. Requires devices.read scope.
slot
string
Filter to a specific save slot.
curl "http://localhost:8080/api/saves?rom_id=42" \
  -H "Authorization: Bearer <token>"

GET /api/saves/identifiers

Retrieve only the IDs of the current user’s saves. Required scope: assets.read

GET /api/saves/summary

Retrieve a summary of saves for a ROM, grouped by slot. Required scope: assets.read
rom_id
integer
required
ROM internal ID.
curl "http://localhost:8080/api/saves/summary?rom_id=42" \
  -H "Authorization: Bearer <token>"
Response:
{
  "total_count": 5,
  "slots": [
    { "slot": "slot1", "count": 3, "latest": { ... } },
    { "slot": null, "count": 2, "latest": { ... } }
  ]
}

GET /api/saves/

Retrieve a single save by ID. Required scope: assets.read
id
integer
required
Save internal ID.
device_id
string
Include device sync information. Requires devices.read scope.

GET /api/saves//content

Download a save file. The owner can download any of their saves. Other authenticated users can only download saves marked is_public=true. Required scope: assets.read
id
integer
required
Save internal ID.
device_id
string
Device ID — records an optimistic sync timestamp on download. Requires devices.read scope.
session_id
integer
Sync session ID for operation counting.
optimistic
boolean
default:"true"
When true and a device is provided, marks the save as synced on download.
curl "http://localhost:8080/api/saves/10/content" \
  -H "Authorization: Bearer <token>" \
  -o save.sav

PUT /api/saves/

Update a save file’s content or replace its associated screenshot. Required scope: assets.write
id
integer
required
Save internal ID.
device_id
string
Device ID for sync tracking. Requires devices.write scope.
saveFile
file
Replacement save file.
screenshotFile
file
Replacement screenshot.

PUT /api/saves//visibility

Toggle a save’s public/private visibility. Owner only. Required scope: assets.write
id
integer
required
Save internal ID.
is_public
boolean
required
New visibility state.
curl -X PUT http://localhost:8080/api/saves/10/visibility \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"is_public": true}'

POST /api/saves/delete

Delete one or more saves and their associated screenshot files. Required scope: assets.write
saves
integer[]
required
List of save IDs to delete.
curl -X POST http://localhost:8080/api/saves/delete \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"saves": [10, 11]}'
Response: Array of deleted save IDs.

POST /api/saves//downloaded

Confirm that a save was successfully downloaded by a device (non-optimistic sync confirmation). Required scope: devices.write
id
integer
required
Save internal ID.
device_id
string
required
Device UUID confirming the download.

POST /api/saves//track / POST /api/saves//untrack

Enable or disable sync tracking for a save on a specific device. Required scope: devices.write
id
integer
required
Save internal ID.
device_id
string
required
Device UUID.

Save States

Save states are full emulator memory snapshots. The States API mirrors the Saves API in structure but without slot or sync-conflict logic.

POST /api/states

Upload a save state for a ROM. Required scope: assets.write
rom_id
integer
required
ROM internal ID.
emulator
string
Emulator identifier.
stateFile
file
required
Save state file to upload.
screenshotFile
file
Optional screenshot.
curl -X POST "http://localhost:8080/api/states?rom_id=42&emulator=mgba" \
  -H "Authorization: Bearer <token>" \
  -F "stateFile=@/path/to/state.state"
Response: StateSchema object.
id
integer
Internal state ID.
rom_id
integer
Associated ROM ID.
user_id
integer
Owner user ID.
file_name
string
Stored filename.
file_size_bytes
integer
File size in bytes.
emulator
string | null
Emulator the state was created with.
is_public
boolean
Whether the state is publicly downloadable.
created_at
string
ISO 8601 creation timestamp.
updated_at
string
ISO 8601 last-updated timestamp.

GET /api/states

List save states for the current user. Required scope: assets.read
rom_id
integer
Filter to states for a specific ROM.
platform_id
integer
Filter to states for all ROMs on a platform.

GET /api/states/identifiers

Retrieve only the IDs of the current user’s save states. Required scope: assets.read

GET /api/states/

Retrieve a single save state by ID. Required scope: assets.read

GET /api/states//content

Download a save state file. Owner downloads any; others only download public states. Required scope: assets.read
curl "http://localhost:8080/api/states/5/content" \
  -H "Authorization: Bearer <token>" \
  -o game.state

PUT /api/states/

Update a save state’s content or screenshot. Required scope: assets.write
id
integer
required
State internal ID.
stateFile
file
Replacement state file.
screenshotFile
file
Replacement screenshot.

PUT /api/states//visibility

Toggle a state’s public/private visibility (owner only). Required scope: assets.write
id
integer
required
State internal ID.
is_public
boolean
required
New visibility state.

POST /api/states/delete

Delete one or more save states. Required scope: assets.write
states
integer[]
required
List of state IDs to delete.
curl -X POST http://localhost:8080/api/states/delete \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"states": [5, 6]}'
Response: Array of deleted state IDs.

Build docs developers (and LLMs) love