Skip to main content
Version: Next

Methods

Methods are used to execute actions and request data back from the API.

Launching

run

Emulate the scanning of a token.

Parameters

Accepts two types of parameters:

  • A string, in which case the string will be treated as the token text with all other options set as default.
  • An object:
KeyTypeRequiredDescription
typestringNoAn internal category of the type of token being scanned. Not currently in use outside of logging.
uidstringNo*The UID of the token being scanned. For example, the UID of an NFC tag. Used for matching mappings.
textstringNo*The main text to be processed from a scan, should contain ZapScript.
datastringNo*The raw data read from a token, converted to a hexadecimal string. Used in mappings and detection of NFC toys.
unsafebooleanNoAllow unsafe operations. Default is false.

These parameters allow emulating a token exactly as it would be read directly from an attached reader on the server. A request's parameters must contain at least a populated uid, text or data value.

Result

Returns null on success.

Currently, it is not reported if the launched ZapScript encountered an error during launching, and the method will return before execution of ZapScript is complete.

Example

Request
{
"jsonrpc": "2.0",
"id": "52f6242e-7a5a-11ef-bf93-020304050607",
"method": "run",
"params": {
"text": "**launch.system:snes"
}
}
Response
{
"jsonrpc": "2.0",
"id": "52f6242e-7a5a-11ef-bf93-020304050607",
"result": null
}

stop

Kill any active launcher, if possible.

This method is highly dependant on the platform and specific launcher used. It's not guaranteed that a launcher is capable of killing the playing process.

Parameters

None.

Result

Returns null on success.

Currently, it is not reported if a process was killed or not.

Example

Request
{
"jsonrpc": "2.0",
"id": "176b4558-7a5b-11ef-b318-020304050607",
"method": "stop"
}
Response
{
"jsonrpc": "2.0",
"id": "176b4558-7a5b-11ef-b318-020304050607",
"result": null
}

confirm

Confirm and launch a staged token from the launch guard.

When launch guard is enabled and media is playing, scanned tokens are staged instead of launched immediately. This method confirms the currently staged token and launches it.

Parameters

None.

Result

Returns null on success. Returns an error if no token is currently staged.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5b-11ef-b318-020304050607",
"method": "confirm"
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5b-11ef-b318-020304050607",
"result": null
}

Tokens

tokens

Returns information about active and last scanned tokens.

Parameters

None.

Result

KeyTypeRequiredDescription
activeTokenResponse[]YesA list of currently active tokens.
lastTokenResponseNoThe last scanned token. Null if no token has been scanned yet.
Token object
KeyTypeRequiredDescription
typestringYesType of token.
uidstringYesUID of the token.
textstringYesText content of the token.
datastringYesRaw data of the token as hexadecimal string.
scanTimestringYesTimestamp of when the token was scanned in RFC3339 format.
readerIdstringNoID of the reader that scanned the token.

Example

Request
{
"jsonrpc": "2.0",
"id": "5e9f3a0e-7a5b-11ef-8084-020304050607",
"method": "tokens"
}
Response
{
"jsonrpc": "2.0",
"id": "5e9f3a0e-7a5b-11ef-8084-020304050607",
"result": {
"active": [],
"last": {
"type": "",
"uid": "",
"text": "**launch.system:snes",
"data": "",
"scanTime": "2024-09-24T17:49:42.938167429+08:00"
}
}
}

tokens.history

Returns a list of the last recorded token launches.

Parameters

None.

Result

KeyTypeRequiredDescription
entriesLaunchEntry[]YesA list of recorded token launches.
Launch entry object
KeyTypeRequiredDescription
datastringYesRaw data of the token as hexadecimal string.
successbooleanYesTrue if the launch was successful.
textstringYesText content of the token.
timestringYesTimestamp of the launch time in RFC3339 format.
typestringYesType of token.
uidstringYesUID of the token.

Example

Request
{
"jsonrpc": "2.0",
"id": "5e9f3a0e-7a5b-11ef-8084-020304050607",
"method": "tokens.history"
}
Response
{
"jsonrpc": "2.0",
"id": "5e9f3a0e-7a5b-11ef-8084-020304050607",
"result": {
"entries": [
{
"data": "",
"success": true,
"text": "**launch.system:snes",
"time": "2024-09-24T17:49:42.938167429+08:00",
"type": "",
"uid": ""
}
]
}
}

Media

media

Returns the current media database status and active media.

The database status includes both indexing and optimization information:

  • Indexing takes priority over optimization in the response (if both are running, only indexing status is shown)
  • Optimization status and progress are shown when no indexing is in progress

Parameters

None.

Result

KeyTypeRequiredDescription
databaseIndexingStatusYesStatus of the media database.
activeActiveMedia[]YesList of currently active media.
Indexing status object
KeyTypeRequiredDescription
existsbooleanYesTrue if the database exists.
indexingbooleanYesTrue if indexing is currently in progress.
optimizingbooleanYesTrue if database optimization is currently in progress.
totalStepsnumberNoTotal number of indexing steps.
currentStepnumberNoCurrent indexing step.
currentStepDisplaystringNoDisplay name of the current indexing step or optimization step.
totalFilesnumberNoTotal number of files to index.
totalMedianumberNoTotal number of media entries in the database. Only included when database exists and is not indexing.
Active media object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID for efficient follow-up media.meta and media.image requests. Omitted when the active path cannot be resolved in the current media database.
launcherIdstringYesID of the launcher.
systemIdstringYesID of the system.
systemNamestringYesDisplay name of the system.
mediaPathstringYesPath to the media file.
relativePathstringNoLauncher-relative convenience path, when it can be derived. Not a stable media identity.
mediaNamestringYesDisplay name of the media.
startedstringYesTimestamp when media started in RFC3339 format.
zapScriptstringYesZapScript command to launch this media item.
launcherControlsstring[]NoList of control action names supported by the active launcher. Only present if the launcher supports controls. See media.control.

Example

Request
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"method": "media"
}
Response (database ready)
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": {
"database": {
"exists": true,
"indexing": false,
"optimizing": false,
"totalMedia": 1337
},
"active": []
}
}
Response (optimization in progress)
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": {
"database": {
"exists": true,
"indexing": false,
"optimizing": true,
"currentStepDisplay": "vacuum",
"totalMedia": 1337
},
"active": []
}
}

media.search

Query the media database and return all matching indexed media.

Note: This API now uses cursor-based pagination for all requests. The total field is deprecated and always returns -1. Use the pagination object to navigate through results. For subsequent pages, include the nextCursor value in the cursor parameter of your next request.

Parameters

An object:

KeyTypeRequiredDescription
querystringNoCase-insensitive search by filename. By default, query is split by white space and results are found which contain every word. If omitted, all media is returned.
systemsstring[]NoCase-sensitive list of system IDs to restrict search to. A missing key or empty list will search all systems.
maxResultsnumberNoMax number of results to return. Default is 100.
cursorstringNoCursor for pagination. Omit for first page, use nextCursor from previous response for subsequent pages.
tagsstring[]NoFilter results by tags. Maximum 50 tags, each up to 128 characters. Tags are case-sensitive and results must match all provided tags. Can be used without query or systems for tag-only searches.
letterstringNoFilter results by first character of game name. Supports: A-Z (single letters), "0-9" (numbers), "#" (symbols). Case-insensitive.
fuzzySystembooleanNoEnable fuzzy matching for system IDs in the systems array (e.g., "snes" matches "SNES").

Result

KeyTypeRequiredDescription
resultsMedia[]YesA list of all search results from the given query.
totalnumberYesDeprecated: Returns the count of results in the current response page. Use pagination info for navigation.
paginationPaginationYesPagination information for cursor-based navigation.
Media object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID for efficient follow-up media.meta and media.image requests.
systemSystemYesSystem which the media has been indexed under.
namestringYesA human-readable version of the result's filename without a file extension.
pathstringYesCanonical indexed media path. Use with system.id for media.meta and media.image.
relativePathstringNoLauncher-relative convenience path, when it can be derived. Not a stable media identity.
zapScriptstringYesZapScript command to launch this media item.
tagsTagInfo[]YesArray of tags associated with this media item.
System object
KeyTypeRequiredDescription
idstringNoInternal system ID for this system.
namestringNoDisplay name of the system.
categorystringNoCategory of system (e.g., "Console", "Computer"). Not yet formalised.
releaseDatestringNoRelease date of the system in ISO 8601 format (YYYY-MM-DD).
manufacturerstringNoManufacturer of the system (e.g., "Nintendo", "Sega").
Pagination object
KeyTypeRequiredDescription
nextCursorstringNoCursor for the next page of results. Omitted if no more pages available.
hasNextPagebooleanYesWhether there are more results available after the current page.
pageSizenumberYesNumber of results requested for this page (matches maxResults parameter).
TagInfo object
KeyTypeRequiredDescription
tagstringYesThe tag name.
typestringYesThe type/category of the tag (e.g., "genre", "year").

Example

Request
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"method": "media.search",
"params": {
"query": "240p"
}
}
Response
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": {
"results": [
{
"mediaId": 123,
"name": "240p Test Suite (PD) v0.03 tepples",
"path": "/media/fat/games/Gameboy/240p Test Suite (PD) v0.03 tepples.gb",
"relativePath": "Gameboy/240p Test Suite (PD) v0.03 tepples.gb",
"zapScript": "@Gameboy/240p Test Suite (PD) v0.03 tepples",
"system": {
"category": "Handheld",
"id": "Gameboy",
"name": "Gameboy"
},
"tags": [
{
"tag": "test",
"type": "category"
},
{
"tag": "homebrew",
"type": "category"
}
]
}
],
"total": 1,
"pagination": {
"hasNextPage": false,
"pageSize": 100
}
}
}
Example with tag filtering
Request
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5d-11ef-9c7b-020304050607",
"method": "media.search",
"params": {
"query": "mario",
"tags": ["platformer", "nintendo"],
"maxResults": 10
}
}
Response
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5d-11ef-9c7b-020304050607",
"result": {
"results": [
{
"mediaId": 456,
"name": "Super Mario Bros.",
"path": "/media/fat/games/NES/Super Mario Bros.nes",
"relativePath": "NES/Super Mario Bros.nes",
"zapScript": "@NES/Super Mario Bros. (year:1985)",
"system": {
"category": "Console",
"id": "NES",
"name": "Nintendo Entertainment System"
},
"tags": [
{
"tag": "platformer",
"type": "genre"
},
{
"tag": "nintendo",
"type": "publisher"
},
{
"tag": "1985",
"type": "year"
}
]
}
],
"total": 1,
"pagination": {
"hasNextPage": false,
"pageSize": 10
}
}
}

media.browse

Browse indexed media content by directory, similar to navigating a file manager. Supports filesystem paths, virtual URI schemes (e.g. mame-arcade://), and paginated results.

When called without a path parameter (or with an empty path), returns top-level root entries including filesystem roots and virtual scheme roots. When systems is provided without path, returns populated launcher routes for those systems only. Pass the same systems filter when browsing a returned route to keep shared paths scoped to the selected systems.

Parameters

All parameters are optional. When called with no parameters, returns root entries.

KeyTypeRequiredDescription
pathstringNoDirectory path to browse. Omit or set empty to list root entries. Supports filesystem paths and virtual URI schemes (e.g. mame-arcade://).
systemsstring[]NoCase-sensitive list of system IDs to restrict route discovery and browse results to. A missing key or empty list preserves unfiltered behavior.
fuzzySystembooleanNoEnable fuzzy matching for system IDs in the systems array (e.g., "snes" matches "SNES").
maxResultsnumberNoMaximum results per page. Default is 100, maximum is 1000.
cursorstringNoOpaque pagination cursor from a previous response's nextCursor. Omit for first page. Cursors are valid only with the same path, systems, letter, and sort parameters.
letterstringNoFilter results to entries starting with this letter.
sortstringNoSort order. One of: name-asc (default), name-desc, filename-asc, filename-desc. The filename variants sort by full file path.

Result

KeyTypeRequiredDescription
pathstringYesThe browsed directory path. Empty string when listing roots.
entriesBrowseEntry[]YesArray of entries in the current path.
totalFilesnumberYesTotal count of media files in the current directory (respects letter filter).
paginationPaginationNoPagination info. Omitted when there are no file results.
Browse entry object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID. Present on media entries for efficient follow-up media.meta and media.image requests.
namestringYesDisplay name of the entry.
pathstringYesFull path to the entry.
typestringYesEntry type: root, directory, or media.
fileCountnumberNoNumber of files in this directory. Present on root and directory entries.
groupstringNoLauncher group name. Present on virtual scheme root entries.
systemIdstringNoSystem ID for the media or single-system filtered route (e.g. SNES). Present on media entries and filtered root entries when exactly one system applies.
systemIdsstring[]NoSystem IDs represented by a filtered root or directory entry.
zapScriptstringNoZapScript command to launch this media. Present on media entries.
relativePathstringNoRelative path from root directory. Present on media entries.
tagsobject[]NoTags attached to the media. Each object has tag (string) and type (string). Present on media entries.
Browse pagination object
KeyTypeRequiredDescription
hasNextPageboolYesWhether more results exist beyond the current page.
pageSizenumberYesThe requested page size.
nextCursorstringNoOpaque cursor for the next page. Absent on the last page.

System route example

Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "media.browse",
"params": {
"systems": ["SNES"]
}
}
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"path": "",
"entries": [
{
"name": "SNES",
"path": "/roms/SNES",
"type": "root",
"fileCount": 150,
"systemId": "SNES",
"systemIds": ["SNES"]
}
],
"totalFiles": 0
}
}

Browse path example

Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "media.browse",
"params": {
"path": "/roms/SNES",
"maxResults": 3
}
}
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"path": "/roms/SNES",
"entries": [
{
"name": "RPGs",
"path": "/roms/SNES/RPGs",
"type": "directory",
"fileCount": 42
},
{
"mediaId": 42,
"name": "Super Mario World",
"path": "/roms/SNES/Super Mario World.sfc",
"type": "media",
"systemId": "SNES",
"zapScript": "@SNES/Super Mario World",
"relativePath": "Super Mario World.sfc",
"tags": [
{"tag": "1990", "type": "year"},
{"tag": "2", "type": "players"}
]
},
{
"mediaId": 43,
"name": "The Legend of Zelda - A Link to the Past",
"path": "/roms/SNES/The Legend of Zelda - A Link to the Past.sfc",
"type": "media",
"systemId": "SNES",
"zapScript": "@SNES/The Legend of Zelda - A Link to the Past",
"relativePath": "The Legend of Zelda - A Link to the Past.sfc",
"tags": [
{"tag": "1991", "type": "year"},
{"tag": "1", "type": "players"}
]
}
],
"totalFiles": 150,
"pagination": {
"hasNextPage": true,
"pageSize": 3,
"nextCursor": "eyJzb3J0VmFsdWUiOiJUaGUgTGVnZW5kIG9mIFplbGRhIC0gQSBMaW5rIHRvIHRoZSBQYXN0IiwibGFzdElkIjo0Mn0="
}
}
}

media.tags

Query the media database and return available tags for filtering.

This method returns all available tags (with their types) for the specified systems. Use this to build dynamic filter UIs showing available tag options.

Parameters

KeyTypeRequiredDescription
systemsstring[]NoCase-sensitive list of system IDs to restrict tags to. A missing key or empty list will get all systems.
fuzzySystembooleanNoEnable fuzzy matching for system IDs in the systems array (e.g., "snes" matches "SNES").

Result

KeyTypeRequiredDescription
tagsTagInfo[]YesArray of available tags.

Tag Capping: To prevent large responses, long-tail tag types are capped at 100 entries per type. Tags within each type are sorted by usage count (most popular first), then alphabetically. The following types are capped: credit, developer, mameparent, publisher, search. Taxonomy types (e.g., region, year, lang, gamegenre, gamefamily) have finite vocabularies per system and are always returned in full without truncation.

TagInfo object
KeyTypeRequiredDescription
tagstringYesThe tag value.
typestringYesThe tag type (e.g., "genre", "year").

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"method": "media.tags",
"params": {
"systems": ["NES", "SNES"]
}
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"result": {
"tags": [
{
"type": "genre",
"tag": "action"
},
{
"type": "genre",
"tag": "platformer"
},
{
"type": "gamefamily",
"tag": "Mario Bros"
},
{
"type": "gamefamily",
"tag": "Super Mario"
}
]
}
}

media.tags.update

Add or remove user tags for an indexed media item.

The initial mutable tag is user:favorite. It appears in normal media tag results and can be queried with media.search tag filters such as user:favorite, -user:favorite, and ~user:favorite.

Parameters

KeyTypeRequiredDescription
mediaIdnumberNoMedia DBID to update. Cannot be mixed with system/path.
systemstringNoSystem ID for path-based lookup. Required when using path.
pathstringNoMedia path for path-based lookup. Required with system.
addstring[]NoTags to add. Currently only user:favorite is mutable.
removestring[]NoTags to remove. Currently only user:favorite is mutable.

Either mediaId or system plus path is required. At least one of add or remove is required. Search operators (+, -, ~) are not valid in mutation requests.

Result

KeyTypeRequiredDescription
tagsTagInfo[]YesEffective tags for the media item.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"method": "media.tags.update",
"params": {
"mediaId": 42,
"add": ["user:favorite"]
}
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"result": {
"tags": [
{
"type": "user",
"tag": "favorite"
}
]
}
}

media.generate

Create a new media database index.

During indexing, the server will emit media.indexing notifications showing progress of the index.

Parameters

Optionally, an object:

KeyTypeRequiredDescription
systemsstring[]NoList of system IDs to restrict indexing to. Other system indexes will remain as is.
fuzzySystembooleanNoEnable fuzzy matching for system IDs in the systems array (e.g., "snes" matches "SNES").

An omitted or null value parameters key is also valid and will index every system.

Selective Indexing Behavior:

  • When systems is provided with specific system IDs, only those systems will be reindexed
  • The server will validate all provided system IDs and return an error if any are invalid
  • If all systems are specified (equivalent to no restriction), a full database rebuild will be performed for optimal performance
  • Selective indexing cannot be performed while database optimization is running
  • Resume functionality will validate that the system configuration hasn't changed between indexing sessions

Result

Returns null on success. Indexing runs in the background after the response is sent. Track progress using media.indexing notifications.

Examples

Full index request
{
"jsonrpc": "2.0",
"id": "6f20e07c-7a5e-11ef-84bb-020304050607",
"method": "media.generate"
}
Response
{
"jsonrpc": "2.0",
"id": "6f20e07c-7a5e-11ef-84bb-020304050607",
"result": null
}
Selective index request
{
"jsonrpc": "2.0",
"id": "7f30e17d-7a5e-11ef-85cc-020304050607",
"method": "media.generate",
"params": {
"systems": ["NES", "SNES", "Genesis"]
}
}
Response
{
"jsonrpc": "2.0",
"id": "7f30e17d-7a5e-11ef-85cc-020304050607",
"result": null
}

media.generate.cancel

Cancel any currently running media database indexing operation.

Parameters

None.

Result

KeyTypeRequiredDescription
messagestringYesStatus message about the cancellation.

Example

Request
{
"jsonrpc": "2.0",
"id": "8f40e28e-7a5e-11ef-86dd-020304050607",
"method": "media.generate.cancel"
}
Response (indexing was running)
{
"jsonrpc": "2.0",
"id": "8f40e28e-7a5e-11ef-86dd-020304050607",
"result": {
"message": "Media indexing cancelled successfully"
}
}
Response (no indexing running)
{
"jsonrpc": "2.0",
"id": "8f40e28e-7a5e-11ef-86dd-020304050607",
"result": {
"message": "No media indexing operation is currently running"
}
}

media.active

Returns the currently active media.

Parameters

None.

Result

Returns an ActiveMedia object if media is currently active, or null if no media is active.

Example

Request
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"method": "media.active"
}
Response (no active media)
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": null
}
Response (media active)
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": {
"mediaId": 42,
"started": "2024-09-24T17:49:42.938167429+08:00",
"launcherId": "SNES",
"systemId": "SNES",
"systemName": "Super Nintendo Entertainment System",
"mediaPath": "/roms/snes/Super Mario World (USA).sfc",
"relativePath": "snes/Super Mario World (USA).sfc",
"mediaName": "Super Mario World",
"zapScript": "@SNES/Super Mario World",
"launcherControls": ["load_state", "save_state", "toggle_menu"]
}
}

media.active.update

Update the currently active media information.

Parameters

An object:

KeyTypeRequiredDescription
systemIdstringYesID of the system.
mediaPathstringYesPath to the media file.
mediaNamestringYesDisplay name of the media.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"method": "media.active.update",
"params": {
"systemId": "SNES",
"mediaPath": "/roms/snes/game.sfc",
"mediaName": "Game"
}
}
Response
{
"jsonrpc": "2.0",
"id": "47f80537-7a5d-11ef-9c7b-020304050607",
"result": null
}

media.history

Return paginated media play history.

Parameters

Optionally, an object:

KeyTypeRequiredDescription
limitnumberNoMaximum number of entries to return. Default is 25, maximum is 100.
cursorstringNoCursor for pagination. Omit for first page, use nextCursor from previous response for subsequent pages.
systemsstring[]NoFilter to one or more system IDs (e.g., ["SNES", "NES"]).
fuzzySystembooleanNoEnable fuzzy matching for system IDs.

Result

KeyTypeRequiredDescription
entriesMediaHistoryEntry[]YesA list of media play history entries.
paginationPaginationNoPagination information for cursor-based navigation. Only present when entries are returned.
Media history entry object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID for efficient follow-up media.meta and media.image requests. Omitted when the history path cannot be resolved in the current media database.
systemIdstringYesID of the system.
systemNamestringYesDisplay name of the system.
mediaNamestringYesDisplay name of the media.
mediaPathstringYesPath to the media file.
relativePathstringNoLauncher-relative convenience path, when it can be derived. Not a stable media identity.
launcherIdstringYesID of the launcher used.
startedAtstringYesTimestamp when media started in RFC3339 format.
endedAtstringNoTimestamp when media stopped in RFC3339 format. Omitted if media is still active.
playTimenumberYesDuration of the play session in seconds.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"method": "media.history",
"params": {
"limit": 10
}
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5d-11ef-9c7b-020304050607",
"result": {
"entries": [
{
"mediaId": 42,
"systemId": "SNES",
"systemName": "Super Nintendo Entertainment System",
"mediaName": "Super Mario World",
"mediaPath": "/roms/snes/Super Mario World (USA).sfc",
"relativePath": "snes/Super Mario World (USA).sfc",
"launcherId": "SNES",
"startedAt": "2025-01-22T14:30:00Z",
"endedAt": "2025-01-22T15:15:30Z",
"playTime": 2730
}
],
"pagination": {
"hasNextPage": false,
"pageSize": 10
}
}
}

media.history.top

Return aggregated media play history grouped by game, sorted by total play time descending. Useful for "most played" displays.

Parameters

Optionally, an object:

KeyTypeRequiredDescription
limitnumberNoMaximum number of entries to return. Default is 25, maximum is 100.
systemsstring[]NoFilter to one or more system IDs (e.g., ["SNES", "NES"]).
fuzzySystembooleanNoEnable fuzzy matching for system IDs.
sincestringNoOnly count sessions starting after this RFC3339 timestamp.

Result

KeyTypeRequiredDescription
entriesMediaHistoryTopEntry[]YesA ranked list of games by total play time.
Media history top entry object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID for efficient follow-up media.meta and media.image requests. Omitted when the history path cannot be resolved in the current media database.
systemIdstringYesID of the system.
systemNamestringYesDisplay name of the system.
mediaNamestringYesDisplay name of the media.
mediaPathstringYesPath to the media file (from most recent session).
relativePathstringNoLauncher-relative convenience path, when it can be derived. Not a stable media identity.
totalPlayTimenumberYesTotal play time across all sessions in seconds.
sessionCountnumberYesNumber of play sessions.
lastPlayedAtstringYesTimestamp of the most recent session in RFC3339 format.

Example

Request
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-8b6e-12f0-ad8c-030405060708",
"method": "media.history.top",
"params": {
"limit": 5,
"systems": ["SNES"]
}
}
Response
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-8b6e-12f0-ad8c-030405060708",
"result": {
"entries": [
{
"mediaId": 42,
"systemId": "SNES",
"systemName": "Super Nintendo Entertainment System",
"mediaName": "Super Mario World",
"mediaPath": "/roms/snes/Super Mario World (USA).sfc",
"relativePath": "snes/Super Mario World (USA).sfc",
"totalPlayTime": 7200,
"sessionCount": 12,
"lastPlayedAt": "2026-02-14T20:30:00Z"
}
]
}
}

media.lookup

Resolve a game name and system to a media database match.

Given a system ID and game name, searches the media database for the best matching title. Uses fuzzy matching to handle minor differences in naming. Returns null for the match when no title is found or confidence is too low.

Parameters

An object:

KeyTypeRequiredDescription
systemstringYesSystem ID to search within (e.g., "SNES", "Genesis").
namestringYesGame name to look up.
fuzzySystembooleanNoEnable fuzzy matching for the system ID (e.g., "snes" matches "SNES").

Result

KeyTypeRequiredDescription
matchMediaLookupMatchNoThe best matching media entry, or null if no match found.
Media lookup match object
KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID for efficient follow-up media.meta and media.image requests.
systemSystemYesSystem the media was found in.
namestringYesDisplay name of the matched media.
pathstringYesPath to the media file.
relativePathstringNoLauncher-relative convenience path, when it can be derived. Not a stable media identity.
zapScriptstringYesZapScript command to launch this media item.
tagsTagInfo[]YesArray of tags associated with this media item.
confidencenumberYesMatch confidence score from 0.0 to 1.0.

Example

Request
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5d-11ef-9c7b-020304050607",
"method": "media.lookup",
"params": {
"system": "SNES",
"name": "Super Mario World"
}
}
Response (match found)
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5d-11ef-9c7b-020304050607",
"result": {
"match": {
"mediaId": 42,
"system": {
"id": "SNES",
"name": "Super Nintendo Entertainment System",
"category": "Console",
"releaseDate": "1990-11-21",
"manufacturer": "Nintendo"
},
"name": "Super Mario World",
"path": "/roms/snes/Super Mario World (USA).sfc",
"relativePath": "SNES/Super Mario World (USA).sfc",
"zapScript": "@SNES/Super Mario World",
"tags": [
{
"tag": "platformer",
"type": "genre"
},
{
"tag": "1990",
"type": "year"
}
],
"confidence": 0.95
}
}
}
Response (no match)
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5d-11ef-9c7b-020304050607",
"result": {
"match": null
}
}

media.meta

Return the full metadata graph for one indexed media row, including its title, system, tags, and scraped properties.

Use this when a client has a search, browse, or lookup result and needs all metadata attached to that row. Identify media by the result's mediaId when available, or by system.id and canonical path. Launcher-relative paths in the system/path shape are accepted as a compatibility fallback when they resolve to exactly one indexed media row. Properties are separated by scope: media.properties applies to the specific ROM/file row, and media.title.properties applies to the shared title.

Parameters

An object:

KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID from search, browse, or lookup. Cannot be mixed with system/path.
systemstringNoSystem ID for the media row. Required when mediaId is omitted.
pathstringNoCanonical indexed media path. Required when mediaId is omitted.
itemsobject[]NoBatch request items. Each item uses either mediaId or system/path. Maximum 100 items. Cannot be mixed with top-level media ref fields.

Single requests return the existing single media response shape. Batch requests return { "items": [...] } in input order. Each batch item contains either media or error, so one missing media row does not fail the whole batch.

Result

KeyTypeRequiredDescription
mediaMediaMetaYesMetadata for the media row.
Media meta object
KeyTypeRequiredDescription
pathstringYesMedia file path.
parentDirstringYesParent directory stored for the media row.
isMissingbooleanYesWhether the indexed file is currently missing.
tagsTagInfo[]YesROM-level tags for this media row.
propertiesobjectYesROM-level properties keyed by canonical type tag.
titleMediaMetaTitleYesShared title metadata for this media row.
Media meta title object
KeyTypeRequiredDescription
slugstringYesPrimary normalized title slug.
secondarySlugstringNoSecondary title slug, when available.
namestringYesDisplay title.
slugLengthnumberYesCharacter length of the primary slug.
slugWordCountnumberYesWord count of the primary slug.
systemobjectYesStored system object with id and name.
tagsTagInfo[]YesTitle-level tags shared by matching media rows.
propertiesobjectYesTitle-level properties keyed by canonical type tag.
Media meta property object
KeyTypeRequiredDescription
textstringYesText value or source path for the property.
contentTypestringYesMIME type for binary-backed properties, empty for text-only values.
extensionstringNoFile extension without a dot, derived from MIME type or source path.
datastringNoBase64-encoded binary property data. Omitted for text-only properties.

Property keys are canonical type tags such as property:description, property:image-image, or property:manual.

Example

Request
{
"jsonrpc": "2.0",
"id": "d4e5f6a7-7a5d-11ef-9c7b-020304050607",
"method": "media.meta",
"params": {
"system": "SNES",
"path": "/roms/snes/Super Mario World.sfc"
}
}
Response
{
"jsonrpc": "2.0",
"id": "d4e5f6a7-7a5d-11ef-9c7b-020304050607",
"result": {
"media": {
"path": "/roms/snes/Super Mario World.sfc",
"parentDir": "/roms/snes",
"isMissing": false,
"tags": [
{"type": "region", "tag": "usa"}
],
"properties": {},
"title": {
"slug": "super mario world",
"name": "Super Mario World",
"slugLength": 17,
"slugWordCount": 3,
"system": {
"id": "SNES",
"name": "Super Nintendo Entertainment System"
},
"tags": [
{"type": "developer", "tag": "Nintendo"},
{"type": "gamegenre", "tag": "platformer"}
],
"properties": {
"property:description": {
"text": "Mario's dinosaur friend Yoshi makes his debut.",
"contentType": ""
}
}
}
}
}
}
Batch Request
{
"jsonrpc": "2.0",
"id": "d4e5f6a7-7a5d-11ef-9c7b-020304050608",
"method": "media.meta",
"params": {
"items": [
{"mediaId": 42},
{"system": "SNES", "path": "/roms/snes/Super Metroid.sfc"}
]
}
}

media.image

Return the best matching image for one indexed media row as base64-encoded data.

media.image checks the requested image types in order. For each type it tries media-level properties first, then title-level properties. If a stored file path no longer exists, the stale property is removed and lookup continues.

Parameters

An object identifying the media row by mediaId or (system, path). Canonical indexed paths are preferred. Launcher-relative paths in the system/path shape are accepted as a compatibility fallback when they resolve to exactly one indexed media row.

KeyTypeRequiredDescription
mediaIdnumberNoOpaque media database row ID from search, browse, or lookup. Cannot be mixed with system/path.
systemstringNoSystem ID. Required when mediaId is omitted.
pathstringNoCanonical indexed media path. Required when mediaId is omitted.
imageTypesstring[]NoImage type preference order. Defaults to image, boxart, screenshot, wheel, titleshot, map, marquee, fanart.
itemsobject[]NoBatch request items. Each item uses either mediaId or system/path, and may include item-level imageTypes. Maximum 50 items. Cannot be mixed with top-level media ref fields.

Supported image type values are image, boxart, screenshot, wheel, titleshot, map, marquee, and fanart. They resolve to canonical property tags such as property:image-image and property:image-boxart.

Single requests return the existing single image response shape. Batch requests return { "items": [...] } in input order. Each batch item contains either image or error. Top-level imageTypes applies to all batch items unless an item has its own imageTypes override.

Result

KeyTypeRequiredDescription
contentTypestringYesMIME type of the returned image data.
extensionstringNoFile extension without a dot, derived from MIME type or source path.
datastringYesBase64-encoded image bytes.
typeTagstringYesCanonical property tag that matched.

Example

Request
{
"jsonrpc": "2.0",
"id": "e5f6a7b8-7a5d-11ef-9c7b-020304050607",
"method": "media.image",
"params": {
"system": "SNES",
"path": "/roms/snes/Super Mario World.sfc",
"imageTypes": ["boxart", "image"]
}
}
Batch Request
{
"jsonrpc": "2.0",
"id": "e5f6a7b8-7a5d-11ef-9c7b-020304050608",
"method": "media.image",
"params": {
"imageTypes": ["boxart", "image"],
"items": [
{"mediaId": 42},
{"mediaId": 43, "imageTypes": ["screenshot"]}
]
}
}
Response
{
"jsonrpc": "2.0",
"id": "e5f6a7b8-7a5d-11ef-9c7b-020304050607",
"result": {
"contentType": "image/png",
"extension": "png",
"data": "iVBORw0KGgoAAAANSUhEUgAA...",
"typeTag": "property:image-boxart"
}
}

scrapers

List all registered metadata scrapers.

Parameters

None.

Result

KeyTypeRequiredDescription
scrapersScraperInfo[]YesRegistered scraper implementations.
Scraper info object
KeyTypeRequiredDescription
idstringYesStable scraper ID used by media.scrape.
namestringYesHuman-readable scraper name.
supportedSystemsstring[]YesSupported system IDs. Empty means the scraper can run against all systems.

Example

Request
{
"jsonrpc": "2.0",
"id": "f6a7b8c9-7a5d-11ef-9c7b-020304050607",
"method": "scrapers"
}
Response
{
"jsonrpc": "2.0",
"id": "f6a7b8c9-7a5d-11ef-9c7b-020304050607",
"result": {
"scrapers": [
{
"id": "gamelist.xml",
"name": "gamelist.xml",
"supportedSystems": []
}
]
}
}

media.scrape

Start a metadata scraper run in the background.

Scraping enriches existing MediaDB records only. It does not create media rows; run media.generate first so the filesystem scanner has indexed the library. Scraping and media indexing are mutually exclusive, and only one scraper can run at a time.

Progress is reported with media.scraping notifications and can be queried with media.scrape.status. Scraping pauses while media is running and resumes automatically when playback stops.

Parameters

An object:

KeyTypeRequiredDescription
scraperIdstringYesScraper ID from the scrapers method, for example gamelist.xml.
systemsstring[]NoSystem IDs to scrape. Omit or pass an empty array to scrape all eligible systems.
forcebooleanNoRe-scrape records that already have this scraper's sentinel tag. Default is false.

Result

Returns null on success. The scraper continues after the response is sent.

Example

Request
{
"jsonrpc": "2.0",
"id": "a7b8c9d0-7a5d-11ef-9c7b-020304050607",
"method": "media.scrape",
"params": {
"scraperId": "gamelist.xml",
"systems": ["SNES", "NES"],
"force": false
}
}
Response
{
"jsonrpc": "2.0",
"id": "a7b8c9d0-7a5d-11ef-9c7b-020304050607",
"result": null
}

media.scrape.status

Return the latest known metadata scraper status.

This method behaves like media does for indexing status: clients can query the current scrape snapshot after opening a UI, then continue listening for media.scraping notifications. If no scrape has run since startup, the result is idle with scraping: false and done: false.

Parameters

None.

Result

KeyTypeRequiredDescription
scraperIdstringNoScraper ID for the latest or active run.
systemIdstringNoSystem currently being processed, when known.
processedintegerYesNumber of records processed.
totalintegerYesTotal records expected for the current scrape, when known.
matchedintegerYesNumber of records matched and enriched.
skippedintegerYesNumber of records skipped.
totalScrapedintegerYesNumber of media records already marked scraped.
scrapingbooleanYesWhether a scrape is currently running.
donebooleanYesWhether the latest scrape reached a terminal state.
pausedbooleanYesWhether the active scrape is paused because media is running or until resumed.

Example

Request
{
"jsonrpc": "2.0",
"id": "b8c9d0e1-7a5d-11ef-9c7b-020304050607",
"method": "media.scrape.status"
}
Response
{
"jsonrpc": "2.0",
"id": "b8c9d0e1-7a5d-11ef-9c7b-020304050607",
"result": {
"scraperId": "gamelist.xml",
"systemId": "snes",
"processed": 42,
"total": 100,
"matched": 38,
"skipped": 4,
"totalScraped": 1200,
"scraping": true,
"done": false,
"paused": false
}
}

media.scrape.cancel

Cancel the currently running metadata scraper operation.

Parameters

None.

Result

KeyTypeRequiredDescription
messagestringYesStatus message about the cancellation.

Example

Request
{
"jsonrpc": "2.0",
"id": "b8c9d0e1-7a5d-11ef-9c7b-020304050607",
"method": "media.scrape.cancel"
}
Response
{
"jsonrpc": "2.0",
"id": "b8c9d0e1-7a5d-11ef-9c7b-020304050607",
"result": {
"message": "scraping cancelled"
}
}

media.scrape.resume

Resume a paused metadata scraper operation.

Scraping normally resumes automatically when playback stops. This method mirrors media.generate.resume and lets a local client force the active scrape to continue while the pauser is currently paused.

Parameters

None.

Result

KeyTypeRequiredDescription
messagestringYesStatus message about resuming.

Example

Request
{
"jsonrpc": "2.0",
"id": "c9d0e1f2-7a5d-11ef-9c7b-020304050607",
"method": "media.scrape.resume"
}
Response
{
"jsonrpc": "2.0",
"id": "c9d0e1f2-7a5d-11ef-9c7b-020304050607",
"result": {
"message": "Media scraping resumed"
}
}

media.clean.orphans

Delete media rows marked missing and remove orphaned related data.

This is intended for cleanup after files have been removed from disk and the media database has been refreshed. It removes missing Media rows, their tags and properties, and any titles that no longer have media rows. It does not run VACUUM; SQLite will reuse freed pages.

Parameters

None.

Result

KeyTypeRequiredDescription
deletednumberYesNumber of missing media rows removed.

Example

Request
{
"jsonrpc": "2.0",
"id": "c9d0e1f2-7a5d-11ef-9c7b-020304050607",
"method": "media.clean.orphans"
}
Response
{
"jsonrpc": "2.0",
"id": "c9d0e1f2-7a5d-11ef-9c7b-020304050607",
"result": {
"deleted": 12
}
}

media.control

Send a control action to the active media's launcher.

Requires active media with a launcher that supports control capabilities. The available control actions depend on the launcher. Use the launcherControls field from media.active or media to discover supported actions.

Control actions run in a restricted runtime that blocks media-launching and playlist commands. Utility commands like input.keyboard, execute, delay and echo are allowed. The execute command bypasses the allow_execute allowlist for control scripts defined in launcher configuration.

Parameters

An object:

KeyTypeRequiredDescription
actionstringYesThe control action to execute (e.g., "save_state", "toggle_pause").
argsobjectNoOptional key-value arguments for the control action. Values are strings.

Result

Returns an empty object {} on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "c3d4e5f6-7a5d-11ef-9c7b-020304050607",
"method": "media.control",
"params": {
"action": "save_state"
}
}
Response
{
"jsonrpc": "2.0",
"id": "c3d4e5f6-7a5d-11ef-9c7b-020304050607",
"result": {}
}

systems

List all currently indexed systems.

Parameters

None.

Result

KeyTypeRequiredDescription
systemsSystem[]YesA list of all indexed systems.

See System object.

Example

Request
{
"jsonrpc": "2.0",
"id": "dbd312f3-7a5f-11ef-8f29-020304050607",
"method": "systems"
}
Response
{
"jsonrpc": "2.0",
"id": "dbd312f3-7a5f-11ef-8f29-020304050607",
"result": {
"systems": [
{
"id": "GameboyColor",
"name": "Gameboy Color",
"category": "Handheld",
"releaseDate": "1998-10-21",
"manufacturer": "Nintendo"
},
{
"id": "EDSAC",
"name": "EDSAC",
"category": "Computer",
"releaseDate": "1949-05-06",
"manufacturer": "University of Cambridge"
}
]
}
}

Settings

settings

List currently set configuration settings.

This method will list values set in the Config File. Some config file options may be omitted which are not appropriate to be read or written remotely.

Parameters

None.

Result

KeyTypeRequiredDescription
runZapScriptbooleanYesWhether ZapScript execution is enabled.
debugLoggingbooleanYesWhether debug logging is enabled.
audioScanFeedbackbooleanYesWhether audio feedback on scan is enabled.
readersAutoDetectbooleanYesWhether automatic reader detection is enabled.
readersScanModestringYesCurrent scan mode setting.
readersScanExitDelaynumberYesDelay before exiting scan mode in seconds.
readersScanIgnoreSystemsstring[]YesList of system IDs to ignore during scanning.
errorReportingbooleanYesWhether error reporting is enabled.
readersConnectReaderConnection[]YesList of manually configured reader connections.
systemDefaultsSystemDefault[]YesPer-system overrides for default launcher and exit ZapScript.
Reader connection object
KeyTypeRequiredDescription
driverstringYesReader driver type (e.g., "pn532uart", "acr122pcsc").
pathstringYesPath or address for the reader connection.
idSourcestringNoSource for the reader ID.
enabledboolNoWhether the connection is enabled. Defaults to true if omitted.
System default object
KeyTypeRequiredDescription
systemstringYesSystem ID this default applies to. Accepts canonical IDs and aliases.
launcherstringNoLauncher ID or group name to use for this system. Empty means no override.
beforeExitstringNoZapScript to run when a media instance for this system is exiting (before the new launch starts).

Example

Request
{
"jsonrpc": "2.0",
"id": "f208d996-7ae6-11ef-960e-020304050607",
"method": "settings"
}
Response
{
"jsonrpc": "2.0",
"id": "f208d996-7ae6-11ef-960e-020304050607",
"result": {
"runZapScript": true,
"debugLogging": false,
"audioScanFeedback": true,
"readersAutoDetect": true,
"readersScanMode": "tap",
"readersScanExitDelay": 0.0,
"readersScanIgnoreSystems": ["DOS"],
"errorReporting": true,
"readersConnect": [],
"systemDefaults": [
{
"system": "Genesis",
"launcher": "retroarch"
}
]
}
}

settings.update

Update one or more settings in-memory and save changes to disk.

This method will only write values which are supplied. Existing values will not be modified.

Parameters

An object containing any of the following optional keys:

KeyTypeRequiredDescription
runZapScriptbooleanNoWhether ZapScript execution is enabled.
debugLoggingbooleanNoWhether debug logging is enabled.
audioScanFeedbackbooleanNoWhether audio feedback on scan is enabled.
readersAutoDetectbooleanNoWhether automatic reader detection is enabled.
readersScanModestringNoCurrent scan mode setting.
readersScanExitDelaynumberNoDelay before exiting scan mode in seconds.
readersScanIgnoreSystemsstring[]NoList of system IDs to ignore during scanning.
errorReportingbooleanNoWhether error reporting is enabled.
readersConnectReaderConnection[]NoList of manually configured reader connections.
systemDefaultsSystemDefault[]NoReplace the full list of per-system launcher/exit-script overrides. Each launcher value, if non-empty, must match a known launcher ID or group (case-insensitive).

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "settings.update",
"params": {
"debugLogging": false
}
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

settings.reload

Reload settings from the configuration file.

Parameters

None.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "settings.reload"
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

settings.auth.claim

Redeem a claim token against a remote auth server and store the resulting credentials in auth.toml.

This method performs trust discovery using the .well-known/zaparoo protocol. It first verifies that the claim URL's root domain supports auth (auth: 1 in the well-known response), then redeems the claim token to obtain a bearer credential. If the root domain's well-known response includes a trusted list, each related domain is checked for bidirectional trust confirmation before extending the credential.

Parameters

An object:

KeyTypeRequiredDescription
claimUrlstringYesHTTPS URL of the claim endpoint to redeem the token against.
tokenstringYesThe one-time claim token to redeem.

Result

KeyTypeRequiredDescription
domainsstring[]YesList of domains the credential was stored for (root + any trusted).

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-auth-claim-example",
"method": "settings.auth.claim",
"params": {
"claimUrl": "https://api.example.com/auth/claim",
"token": "claim-token-abc123"
}
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-auth-claim-example",
"result": {
"domains": [
"https://api.example.com",
"https://cdn.example.com"
]
}
}

settings.logs.download

Download the current log file as base64-encoded content.

Parameters

None.

Result

KeyTypeRequiredDescription
filenamestringYesName of the log file.
sizenumberYesSize of the log file in bytes.
contentstringYesBase64-encoded content of the log file.

Example

Request
{
"jsonrpc": "2.0",
"id": "9f50e39f-7a5e-11ef-87ee-020304050607",
"method": "settings.logs.download"
}
Response
{
"jsonrpc": "2.0",
"id": "9f50e39f-7a5e-11ef-87ee-020304050607",
"result": {
"filename": "zaparoo.log",
"size": 1024,
"content": "MjAyNC0wOS0yNFQxNzowMDowMC4wMDBaIElORk8gU3RhcnRpbmcgWmFwYXJvby4uLg=="
}
}

Playtime

playtime

Query current playtime session status and usage statistics.

This method returns comprehensive information about the current playtime session, including active game time, cumulative session time, cooldown state, daily usage, and remaining time before limits are reached.

Session States:

  • reset - No active session, ready to start new session
  • active - Game currently running, time being tracked
  • cooldown - Game stopped but session persists (within session reset timeout)

Parameters

None.

Result

KeyTypeRequiredDescription
statestringYesCurrent session state: "reset", "active", or "cooldown".
sessionActivebooleanYesWhether a game is currently running.
limitsEnabledbooleanYesWhether playtime limits are currently enabled for enforcement.
sessionStartedstringNoISO 8601 timestamp when current game started. Only present during "active" state.
sessionDurationstringNoTotal time in current session (Go duration format). Present during "active" and "cooldown" states.
sessionCumulativeTimestringNoCumulative time from previous games in session. Present during "active" and "cooldown" states.
sessionRemainingstringNoTime remaining before session limit reached. Only present if session limit is configured.
cooldownRemainingstringNoTime until session auto-resets. Only present during "cooldown" state.
dailyUsageTodaystringNoTotal playtime accumulated today. Available in all states when data is available.
dailyRemainingstringNoTime remaining before daily limit reached. Available in all states if daily limit is configured.

Note: All duration fields use Go's duration format (e.g., "1h30m45s", "45m", "2h").

Examples

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5e-11ef-9c7b-020304050607",
"method": "playtime"
}
Response (reset state)
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5e-11ef-9c7b-020304050607",
"result": {
"state": "reset",
"sessionActive": false,
"limitsEnabled": true,
"dailyUsageToday": "1h30m0s",
"dailyRemaining": "2h30m0s"
}
}
Response (active game with limits)
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5e-11ef-9c7b-020304050607",
"result": {
"state": "active",
"sessionActive": true,
"limitsEnabled": true,
"sessionStarted": "2025-01-22T14:30:00Z",
"sessionDuration": "45m30s",
"sessionCumulativeTime": "15m",
"sessionRemaining": "14m30s",
"dailyUsageToday": "2h15m30s",
"dailyRemaining": "1h44m30s"
}
}
Response (cooldown state)
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-7a5e-11ef-9c7b-020304050607",
"result": {
"state": "cooldown",
"sessionActive": false,
"limitsEnabled": true,
"sessionDuration": "45m30s",
"sessionCumulativeTime": "45m30s",
"sessionRemaining": "14m30s",
"cooldownRemaining": "12m30s",
"dailyUsageToday": "2h15m30s",
"dailyRemaining": "1h44m30s"
}
}

settings.playtime.limits

Get current playtime limit configuration.

Returns all configured playtime limits including daily limits, session limits, session reset timeout, warning intervals, and retention settings.

Parameters

None.

Result

KeyTypeRequiredDescription
enabledbooleanYesWhether playtime limits are enabled for enforcement.
dailystringNoDaily playtime limit in Go duration format (e.g., "4h"). Omitted if not configured.
sessionstringNoPer-session playtime limit in Go duration format (e.g., "1h"). Omitted if not configured.
sessionResetstringNoIdle timeout before session auto-resets in Go duration format (e.g., "20m"). "0s" means session never resets.
warningsstring[]YesList of time intervals when warnings are sent before limits reached (e.g., ["5m", "2m", "1m"]). Empty array if none.
retentionnumberNoNumber of days to retain playtime history. Omitted if not configured.

Example

Request
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5e-11ef-9c7b-020304050607",
"method": "settings.playtime.limits"
}
Response
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-7a5e-11ef-9c7b-020304050607",
"result": {
"enabled": true,
"daily": "4h",
"session": "1h",
"sessionReset": "20m",
"warnings": ["5m", "2m", "1m"],
"retention": 30
}
}

settings.playtime.limits.update

Update playtime limit settings.

This method updates one or more playtime limit configuration values in-memory and saves changes to disk. Only provided fields will be updated; omitted fields remain unchanged.

Parameters

An object containing any of the following optional keys:

KeyTypeRequiredDescription
enabledbooleanNoEnable or disable playtime limit enforcement.
dailystringNoDaily playtime limit in Go duration format (e.g., "4h", "2h30m"). Use "0" or "0s" to disable daily limit.
sessionstringNoPer-session playtime limit in Go duration format (e.g., "1h", "45m"). Use "0" or "0s" to disable session limit.
sessionResetstringNoIdle timeout before session auto-resets in Go duration format (e.g., "20m"). Use "0" or "0s" for sessions that never reset.
warningsstring[]NoList of time intervals for warnings in Go duration format (e.g., ["10m", "5m", "1m"]). Empty array disables warnings.
retentionnumberNoNumber of days to retain playtime history. Use 0 for no retention limit.

Important: Duration strings must use Go duration format: combinations of hours (h), minutes (m), and seconds (s). Examples: "1h", "30m", "1h30m", "2h15m30s".

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "c3d4e5f6-7a5e-11ef-9c7b-020304050607",
"method": "settings.playtime.limits.update",
"params": {
"enabled": true,
"session": "1h",
"warnings": ["10m", "5m", "2m"]
}
}
Response
{
"jsonrpc": "2.0",
"id": "c3d4e5f6-7a5e-11ef-9c7b-020304050607",
"result": null
}

Mappings

Mappings are used to modify the contents of tokens before they're launched, based on different types of matching parameters. Stored mappings are queried before every launch and applied to the token if there's a match. This allows, for example, adding ZapScript to a read-only NFC tag based on its UID.

mappings

List all mappings.

Returns a list of all active and inactive mappings entries stored on server.

Parameters

None.

Result

KeyTypeRequiredDescription
mappingsMapping[]YesList of all stored mappings. See mapping object.
Mapping object
KeyTypeRequiredDescription
idstringYesInternal database ID of mapping entry. Used to reference mapping for updates and deletions.
addedstringYesTimestamp of the time mapping was created in RFC3339 format.
labelstringYesAn optional display name shown to the user.
enabledbooleanYesTrue if the mapping will be used when looking up matching mappings.
typestringYesThe field which will be matched against:
_ uid: match on UID, if available. UIDs are normalized before matching to remove spaces, colons and convert to lowercase.
_ text: match on the stored text on token.
* data: match on the raw token data, if available. This is converted from bytes to a hexadecimal string and should be matched as this.
matchstringYesThe method used to match a mapping pattern:
_ exact: match the entire string exactly to the field.
_ partial: match part of the string to the field.
* regex: use a regular expression to match the field.
patternstringYesPattern that will be matched against the token, using the above settings.
overridestringYesFinal text that will completely replace the existing token text if a match was successful.

Example

Request
{
"jsonrpc": "2.0",
"id": "1a8bee28-7aef-11ef-8427-020304050607",
"method": "mappings"
}
Response
{
"jsonrpc": "2.0",
"id": "1a8bee28-7aef-11ef-8427-020304050607",
"result": {
"mappings": [
{
"id": "1",
"added": "1970-01-21T06:08:18+08:00",
"label": "barcode pokemon",
"enabled": true,
"type": "text",
"match": "partial",
"pattern": "9780307468031",
"override": "**launch.search:gbc/*pokemon*gold*"
}
]
}
}

mappings.new

Create a new mapping.

Parameters

An object:

KeyTypeRequiredDescription
labelstringYesAn optional display name shown to the user.
enabledbooleanYesTrue if the mapping will be used when looking up matching mappings.
typestringYesThe field which will be matched against:
_ uid: match on UID, if available. UIDs are normalized before matching to remove spaces, colons and convert to lowercase.
_ text: match on the stored text on token.
* data: match on the raw token data, if available. This is converted from bytes to a hexadecimal string and should be matched as this.
matchstringYesThe method used to match a mapping pattern:
_ exact: match the entire string exactly to the field.
_ partial: match part of the string to the field.
* regex: use a regular expression to match the field.
patternstringYesPattern that will be matched against the token, using the above settings.
overridestringYesFinal text that will completely replace the existing token text if a match was successful.

Result

Returns an empty object {} on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "mappings.new",
"params": {
"label": "Test Mapping",
"enabled": true,
"type": "text",
"match": "exact",
"pattern": "test",
"override": "**launch.system:snes"
}
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": {}
}

mappings.delete

Delete an existing mapping.

Parameters

An object:

KeyTypeRequiredDescription
idnumberYesDatabase ID of mapping.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "mappings.delete",
"params": {
"id": 1
}
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

mappings.update

Change an existing mapping.

Parameters

An object:

KeyTypeRequiredDescription
idnumberYesInternal database ID of mapping entry.
labelstringNoAn optional display name shown to the user.
enabledbooleanNoTrue if the mapping will be used when looking up matching mappings.
typestringNoThe field which will be matched against:
_ uid: match on UID, if available. UIDs are normalized before matching to remove spaces, colons and convert to lowercase.
_ text: match on the stored text on token.
* data: match on the raw token data, if available. This is converted from bytes to a hexadecimal string and should be matched as this.
matchstringNoThe method used to match a mapping pattern:
_ exact: match the entire string exactly to the field.
_ partial: match part of the string to the field.
* regex: use a regular expression to match the field.
patternstringNoPattern that will be matched against the token, using the above settings.
overridestringNoFinal text that will completely replace the existing token text if a match was successful.

Only keys which are provided in the object will be updated in the database.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "e98fd686-7e62-11ef-8f8c-020304050607",
"method": "mappings.update",
"params": {
"id": 1,
"enabled": false
}
}
Response
{
"jsonrpc": "2.0",
"id": "e98fd686-7e62-11ef-8f8c-020304050607",
"result": null
}

mappings.reload

Reload mappings from the configuration file.

Parameters

None.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "mappings.reload"
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

Readers

readers

List all currently connected readers and their capabilities.

Parameters

None.

Result

KeyTypeRequiredDescription
readersReaderInfo[]YesA list of all connected readers.
Reader info object
KeyTypeRequiredDescription
idstringYesDevice path or system identifier of the reader. Legacy field, prefer readerId for stable identification.
readerIdstringYesStable reader ID, deterministic across restarts. Format: {driver}-{hash}.
driverstringYesDriver type for the reader (e.g., "pn532", "acr122pcsc", "file").
infostringYesHuman-readable information about the reader.
connectedbooleanYesWhether the reader is currently connected.
capabilitiesstring[]YesList of capabilities supported by the reader.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "readers"
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": {
"readers": [
{
"id": "/dev/ttyUSB0",
"readerId": "pn532-ujqixjv6",
"driver": "pn532",
"info": "PN532 (1-2.3.1)",
"capabilities": ["read", "write"],
"connected": true
}
]
}
}

readers.write

Attempt to write given text to the first available write-capable reader, if possible.

Parameters

An object:

KeyTypeRequiredDescription
textstringYesZapScript to be written to the token.
readerIdstringNoID of a specific reader to write to. If omitted, uses the first available write-capable reader.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "readers.write",
"params": {
"text": "**launch.system:snes"
}
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

readers.write.cancel

Cancel any ongoing write operation.

Parameters

Optionally, an object:

KeyTypeRequiredDescription
readerIdstringNoID of a specific reader to cancel write on. If omitted, cancels on all readers.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"method": "readers.write.cancel"
}
Response
{
"jsonrpc": "2.0",
"id": "562c0b60-7ae8-11ef-87d7-020304050607",
"result": null
}

Launchers

launchers

List all launchers known to the running service. Suitable for populating a UI launcher picker (for example, when assigning a per-system default via settings.update).

Parameters

None.

Result

KeyTypeRequiredDescription
launchersLauncher[]YesAll cached launchers, sorted by systemId then id.
Launcher object
KeyTypeRequiredDescription
idstringYesUnique launcher identifier.
systemIdstringNoThe system this launcher targets. Omitted for generic launchers without a fixed system.
systemNamestringNoHuman-readable system name resolved from system metadata. Omitted when no metadata is available.
groupsstring[]NoGroup names this launcher belongs to. Group names are valid values for systemDefaults.launcher.

Example

Request
{
"jsonrpc": "2.0",
"id": "5b8c3a40-7a5e-11ef-88ff-020304050607",
"method": "launchers"
}
Response
{
"jsonrpc": "2.0",
"id": "5b8c3a40-7a5e-11ef-88ff-020304050607",
"result": {
"launchers": [
{
"id": "retroarch",
"systemId": "Genesis",
"systemName": "Genesis",
"groups": ["libretro"]
},
{
"id": "snes9x",
"systemId": "SNES",
"systemName": "Super Nintendo",
"groups": ["libretro"]
}
]
}
}

launchers.refresh

Refresh the internal launcher cache, forcing a reload of launcher configurations.

Parameters

None.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "af60e4a0-7a5e-11ef-88ff-020304050607",
"method": "launchers.refresh"
}
Response
{
"jsonrpc": "2.0",
"id": "af60e4a0-7a5e-11ef-88ff-020304050607",
"result": null
}

Service

version

Return server's current version and platform.

Parameters

None.

Result

KeyTypeRequiredDescription
platformstringYesID of platform the service is currently running on.
versionstringYesCurrent version of the running Zaparoo service.

Example

Request
{
"jsonrpc": "2.0",
"id": "ca47f646-7e47-11ef-971a-020304050607",
"method": "version"
}
Response
{
"jsonrpc": "2.0",
"id": "ca47f646-7e47-11ef-971a-020304050607",
"result": {
"platform": "mister",
"version": "2.0.0-dev"
}
}

health

Simple health check to verify the server is running and responding.

Parameters

None.

Result

KeyTypeRequiredDescription
statusstringYesHealth status. Returns "ok" when server is healthy.

Example

Request
{
"jsonrpc": "2.0",
"id": "db58f757-7e47-11ef-982b-020304050607",
"method": "health"
}
Response
{
"jsonrpc": "2.0",
"id": "db58f757-7e47-11ef-982b-020304050607",
"result": {
"status": "ok"
}
}

Inbox

Inbox messages are system notifications stored on the server, typically used to inform the user of events like update availability, errors, or other important information.

inbox

List all inbox messages.

Parameters

None.

Result

KeyTypeRequiredDescription
messagesInboxMessage[]YesList of inbox messages.
Inbox message object
KeyTypeRequiredDescription
idnumberYesUnique identifier of the message.
titlestringYesTitle of the message.
bodystringNoBody text of the message.
severitynumberYesSeverity level (0=info, 1=warning, 2=error).
categorystringNoCategory of the message.
profileIdnumberNoAssociated profile ID, if applicable.
createdAtstringYesTimestamp when message was created in RFC3339 format.

Example

Request
{
"jsonrpc": "2.0",
"id": "ec69f868-7e47-11ef-993c-020304050607",
"method": "inbox"
}
Response
{
"jsonrpc": "2.0",
"id": "ec69f868-7e47-11ef-993c-020304050607",
"result": {
"messages": [
{
"id": 1,
"title": "Update Available",
"body": "A new version of Zaparoo is available.",
"severity": 0,
"category": "update",
"createdAt": "2024-09-24T17:49:42.938167429+08:00"
}
]
}
}

inbox.delete

Delete a specific inbox message by ID.

Parameters

An object:

KeyTypeRequiredDescription
idnumberYesID of the message to delete.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "fd7a0979-7e47-11ef-9a4d-020304050607",
"method": "inbox.delete",
"params": {
"id": 1
}
}
Response
{
"jsonrpc": "2.0",
"id": "fd7a0979-7e47-11ef-9a4d-020304050607",
"result": null
}

inbox.clear

Delete all inbox messages.

Parameters

None.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "0e8b1a8a-7e48-11ef-9b5e-020304050607",
"method": "inbox.clear"
}
Response
{
"jsonrpc": "2.0",
"id": "0e8b1a8a-7e48-11ef-9b5e-020304050607",
"result": null
}

Input

Direct platform input control for remote control use cases. These methods bypass the token pipeline entirely: no hooks, history, or sound effects are triggered.

The input macro format is identical to what goes after the : in a ZapScript input.keyboard or input.gamepad command on a token. Each character is a separate keypress, {...} groups are special keys/combos, and \ is the escape character.

input.keyboard

Press keyboard keys using the ZapScript input macro format.

Parameters

An object:

KeyTypeRequiredDescription
keysstringYesInput macro string. Each character is a keypress, {...} for special keys (e.g. {enter}, {f9}, {ctrl+q}). Same format as ZapScript on a token.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"method": "input.keyboard",
"params": {
"keys": "abc{enter}"
}
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"result": null
}

input.gamepad

Press gamepad buttons using the ZapScript input macro format.

Parameters

An object:

KeyTypeRequiredDescription
buttonsstringYesInput macro string. Each character is a button press, {...} for named buttons (e.g. {up}, {start}, {l1}). Same format as ZapScript on a token.

Result

Returns null on success.

Example

Request
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-2345-6789-abcd-ef0123456789",
"method": "input.gamepad",
"params": {
"buttons": "^^vv<><>BA{start}"
}
}
Response
{
"jsonrpc": "2.0",
"id": "b2c3d4e5-2345-6789-abcd-ef0123456789",
"result": null
}

Screenshot

screenshot

Capture a screenshot of the current platform display. Returns the image as base64-encoded data and the path where it was saved on disk.

Currently supported on MiSTer only. Other platforms will return an error.

Parameters

None.

Result

KeyTypeRequiredDescription
pathstringYesPath where the screenshot was saved on disk.
datastringYesBase64-encoded image data.
sizenumberYesSize of the image data in bytes.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"method": "screenshot"
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"result": {
"path": "/media/fat/screenshots/MiSTer_20260329_181500.png",
"data": "iVBORw0KGgo...",
"size": 245760
}
}

Updates

update.check

Check if a newer version of Zaparoo Core is available. Returns version information and release notes. On development builds, always returns updateAvailable: false.

Parameters

None.

Result

KeyTypeRequiredDescription
currentVersionstringYesThe currently running version.
latestVersionstringNoThe latest available version (if check succeeded).
updateAvailablebooleanYesWhether a newer version is available.
releaseNotesstringNoRelease notes for the latest version.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"method": "update.check"
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"result": {
"currentVersion": "2.9.1",
"latestVersion": "2.10.0",
"updateAvailable": true,
"releaseNotes": "..."
}
}

update.apply

Download and apply the latest available update, then gracefully restart the service. The response is sent to the client before the restart occurs. Returns an error if media indexing is in progress or if running a development build.

Parameters

None.

Result

KeyTypeRequiredDescription
previousVersionstringYesThe version before the update.
newVersionstringYesThe version after the update.

Example

Request
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"method": "update.apply"
}
Response
{
"jsonrpc": "2.0",
"id": "a1b2c3d4-1234-5678-9abc-def012345678",
"result": {
"previousVersion": "2.9.1",
"newVersion": "2.10.0"
}
}