{"openapi":"3.0.0","paths":{"/cats/v1/folders":{"get":{"description":"Returns an object containing a list of folders and permissions for root folders.","operationId":"FolderController_list_v1","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderList"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List folders","tags":["Folders"]},"post":{"operationId":"FolderController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalFolder"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to create the folder."},"422":{"description":"Folder name is not unique."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create folder","tags":["Folders"]}},"/cats/v1/folders/{id}":{"patch":{"operationId":"FolderController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalFolder"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the folder."},"404":{"description":"Folder not found."},"422":{"description":"Folder name is not unique."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update folder","tags":["Folders"]},"delete":{"description":"The folder must be empty of assets and subfolders before it can be deleted.","operationId":"FolderController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to delete the folder."},"404":{"description":"Folder not found."},"422":{"description":"Folder is not empty."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete folder","tags":["Folders"]}},"/cats/v1/licences/features":{"get":{"description":"Returns the features available for the current user's account\nbased on their licence level.","operationId":"LicenceFeatureController_getFeatures_v1","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenceFeaturesResponse"}}}},"401":{"description":"Not authenticated."},"403":{"description":"No user principal found in current context."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get licence features","tags":["Licences"]}},"/cats/v1/assets":{"get":{"description":"This API is intended to be used to build folder-based views of\n         signage content. It will return any content that can be assigned\n         to a folder. You can use the content-specific APIs (such as\n         `/playlists` and `/media`) and aggregate the content yourself if\n         you prefer.","operationId":"AssetController_list_v1","parameters":[{"name":"folderId","required":true,"in":"query","schema":{"type":"number"}},{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"]}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/MediaAsset"},{"$ref":"#/components/schemas/PlaylistAsset"},{"$ref":"#/components/schemas/ScheduleAsset"}]}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List assets","tags":["Assets"]}},"/cats/v1/assets/move":{"post":{"description":"This API is a convenience API to move assets between folders.\n         You can use the content-specific APIs (such as `/playlists/:id` and\n         `/media/:id`) and move the assets directly if you prefer.\n         Returns the destination folder that the assets were moved into.","operationId":"AssetController_bulkMove_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkMoveCommand"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalFolder"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Bulk move assets","tags":["Assets"]}},"/cats/v1/assets/delete":{"post":{"description":"This API is a convenience API to delete assets.\n         You can use the content-specific APIs (such as `/playlists/:id` and\n         `/media/:id`) and delete the assets directly if you prefer.","operationId":"AssetController_bulkDelete_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeleteCommand"}}}},"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Bulk delete assets","tags":["Assets"]}},"/cats/v1/assets/{type}/{id}/usages":{"get":{"description":"Returns the usage graph for a given asset, walking up the\n         hierarchy to show all parents that consume this asset. Each edge\n         contains the child asset, the parent that uses it, and the depth\n         from the starting asset.","operationId":"AssetController_getUsages_v1","parameters":[{"name":"type","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssetUsageEdge"}}}}},"400":{"description":"Invalid asset type."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get asset usages","tags":["Assets"]}},"/cats/v1/media":{"post":{"operationId":"MediaController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalMedia"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to create media item."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create media","tags":["Media"]},"get":{"operationId":"MediaController_list_v1","parameters":[{"name":"folderId","required":false,"in":"query","schema":{"type":"number"}},{"name":"mediaType","required":false,"in":"query","schema":{"type":"string","enum":["IMAGE","VIDEO","WIDGET","WEBSITE","CANVA","POWER_BI","TABLEAU","DESIGN","ZONE","DOCUMENT"]}},{"name":"tags","required":false,"in":"query","description":"Filter by a list of tags that all media items matching the filter must have.","schema":{"minItems":1,"type":"array","items":{"type":"string"}}},{"name":"name","required":false,"in":"query","description":"Filter by a partial name match.","schema":{"type":"string"}},{"name":"createdAfter","required":false,"in":"query","description":"Filter to media items created after this date (exclusive).","schema":{"format":"date-time","type":"string"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Media"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List media","tags":["Media"]}},"/cats/v1/media/{id}/upload":{"post":{"description":"Prepares and returns an upload URL that can be used to upload a\n         file. Only use this for media items that have a `PROVIDED` source.\n         Clients must `PUT` the file against the returned URL.","operationId":"MediaController_startUpload_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadStartResponse"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to prepare a media upload."},"404":{"description":"Media not found."},"422":{"description":"Media upload already completed."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Start a media upload","tags":["Media"]},"patch":{"operationId":"MediaController_completeUpload_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadCompleteCommandDTO"}}}},"responses":{"200":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to complete a media upload."},"404":{"description":"Media not found."},"422":{"description":"Media upload already completed."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Complete a media upload","tags":["Media"]}},"/cats/v1/media/{id}/import/{correlationId}":{"put":{"description":"Requests an import of an externally edited media file (e.g. a\n         Canva design). The import will be processed asynchronously.","operationId":"MediaController_requestImportTask_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"correlationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"202":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to import this media item."},"404":{"description":"Media not found."},"422":{"description":"Media cannot be imported in its current state."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Request a media import","tags":["Media"]}},"/cats/v1/media/{id}":{"delete":{"description":"This will also delete any files that were uploaded.","operationId":"MediaController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to delete a media item."},"404":{"description":"Media not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete media","tags":["Media"]},"patch":{"operationId":"MediaController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalMedia"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the media item."},"404":{"description":"Media not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update media","tags":["Media"]},"get":{"operationId":"MediaController_getById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Media"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Media not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get media","tags":["Media"]}},"/cats/v1/media/{id}/links":{"get":{"description":"This will return known URL links for the media file. The most\n         common use case is to download the media file, but other links\n         may be available - for example, editing the media file.","operationId":"MediaController_links_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MediaLink"}}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Media not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get media links","tags":["Media"]}},"/cats/v1/screens/pair":{"post":{"operationId":"ScreenController_pair_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenPairCommand"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalScreen"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to pair the screen."},"422":{"description":"Update request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Pair screen","tags":["Screens"]}},"/cats/v1/screens/{identity}":{"patch":{"operationId":"ScreenController_update_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalScreen"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to configure the screen."},"422":{"description":"Update request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Configure screen","tags":["Screens"]},"get":{"operationId":"ScreenController_getByIdentity_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Screen"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get screen","tags":["Screens"]},"delete":{"operationId":"ScreenController_delete_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete screen","tags":["Screens"]}},"/cats/v1/screens/{identity}/screenshots":{"get":{"description":"Returns the most recent live screenshots taken of the screen.","operationId":"ScreenController_getScreenshotsByIdentity_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Screenshot"}}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen not found."},"422":{"description":"Screen not capable of taking screenshots."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get screenshots","tags":["Screens"]}},"/cats/v1/screens":{"get":{"operationId":"ScreenController_list_v1","parameters":[{"name":"applicationVersion","required":false,"in":"query","description":"Filter by the application version.","schema":{"example":"1.0.3","type":"string"}},{"name":"runtime","required":false,"in":"query","description":"Filter by the application runtime - e.g. `ANDROID` or `BRIGHTSIGN`.","schema":{"type":"string","enum":["ANDROID","TIZEN","BRIGHTSIGN","WEB","WEBOS","WINDOWS","LINUX"]}},{"name":"name","required":false,"in":"query","description":"Filter by a partial name match.","schema":{"type":"string"}},{"name":"tags","required":false,"in":"query","description":"Filter by a list of tags that all screens matching the filter must have.","schema":{"minItems":1,"type":"array","items":{"type":"string"}}},{"name":"groupId","required":false,"in":"query","description":"Filter by screens in a screen group.","schema":{"type":"number"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Screen"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List screens","tags":["Screens"]}},"/cats/v1/screens/{identity}/commands":{"post":{"description":"Dispatches a command to the screen. The screen must be online to\n         receive and process the command. This API response will include\n         the ID of the command, which can be used to query the status of\n         the command.","operationId":"ScreenController_dispatchCommand_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandDispatchRequestDTO"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen not found."},"422":{"description":"Command is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Dispatch command","tags":["Screens"]}},"/cats/v1/screens/{identity}/commands/{id}":{"get":{"operationId":"ScreenController_getCommandById_v1","parameters":[{"name":"identity","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen or command not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get command","tags":["Screens"]}},"/cats/v1/screen-groups":{"post":{"operationId":"ScreenGroupController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenGroupCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalScreenGroup"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to create the screen group."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create screen group","tags":["Screen groups"]},"get":{"operationId":"ScreenGroupController_list_v1","parameters":[{"name":"parentId","required":false,"in":"query","schema":{"nullable":true,"type":"number"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ScreenGroup"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List screen groups","tags":["Screen groups"]}},"/cats/v1/screen-groups/{id}":{"patch":{"operationId":"ScreenGroupController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenGroupUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalScreenGroup"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the screen group."},"404":{"description":"Screen group does not exist."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update screen group","tags":["Screen groups"]},"get":{"operationId":"ScreenGroupController_getById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenGroup"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Screen group not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get screen group","tags":["Screen groups"]},"delete":{"operationId":"ScreenGroupController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to delete the screen group."},"404":{"description":"Screen group not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete screen group","tags":["Screen groups"]}},"/cats/v1/screen-groups/{id}/screens":{"post":{"operationId":"ScreenGroupController_addScreen_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenGroupAddScreenCommand"}}}},"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the screen group."},"404":{"description":"Screen group not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Add a screen to a screen group","tags":["Screen groups"]}},"/cats/v1/screen-groups/{id}/screens/{identity}":{"delete":{"operationId":"ScreenGroupController_removeScreen_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"identity","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the screen group."},"404":{"description":"Screen group or screen not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Remove a screen from a screen group","tags":["Screen groups"]}},"/cats/v1/playlists":{"post":{"operationId":"PlaylistController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalPlaylist"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to create the playlist."},"422":{"description":"Create request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create playlist","tags":["Playlists"]},"get":{"operationId":"PlaylistController_list_v1","parameters":[{"name":"folderId","required":false,"in":"query","schema":{"type":"number"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Playlist"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List playlists","tags":["Playlists"]}},"/cats/v1/playlists/{id}/duplicate":{"post":{"description":"Duplicates a playlist, including all of its items. The new\n         playlist will be created in the same folder as the original and\n         will have the same name with the suffix `(duplicate)`.","operationId":"PlaylistController_duplicate_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalPlaylist"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to duplicate the playlist."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Duplicate playlist","tags":["Playlists"]}},"/cats/v1/playlists/{id}":{"patch":{"operationId":"PlaylistController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalPlaylist"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the playlist."},"422":{"description":"Update request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update playlist","tags":["Playlists"]},"delete":{"description":"The deleted playlist will automatically be removed from playlists\n         where it is a sub playlist, and any zones that reference it. The\n         playlist will be unpublished from screens.","operationId":"PlaylistController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to delete the playlist."},"409":{"description":"Playlist does not exist."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete playlist","tags":["Playlists"]},"get":{"operationId":"PlaylistController_getById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Playlist"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Playlist not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get playlist","tags":["Playlists"]}},"/cats/v1/playlists/{id}/publish":{"post":{"description":"Publishes the playlist to the targeted screens or screen groups.\nThis process is asynchronous and will return once the targets have been\nvalidated. The status of the publishing process can be queried using the\nreturned job id.","operationId":"PlaylistController_publish_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistPublishCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJob"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to publish the playlist, or to publish to the target screen or screen group."},"422":{"description":"Publish request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Publish playlist","tags":["Playlists"]}},"/cats/v1/schedules":{"post":{"operationId":"ScheduleController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalSchedule"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to create the schedule."},"422":{"description":"Create request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create schedule","tags":["Schedules"]},"get":{"operationId":"ScheduleController_list_v1","parameters":[{"name":"folderId","required":false,"in":"query","description":"Filter schedules to only those stored in the specified folder.","schema":{"type":"number"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Schedule"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List schedules","tags":["Schedules"]}},"/cats/v1/schedules/{id}":{"patch":{"operationId":"ScheduleController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleUpdateCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalSchedule"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to update the schedule."},"422":{"description":"Update request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update schedule","tags":["Schedules"]},"delete":{"description":"The deleted schedule will automatically be removed from any\n         screens or screen groups that reference it.","operationId":"ScheduleController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to delete the schedule."},"409":{"description":"Schedule does not exist."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete schedule","tags":["Schedules"]},"get":{"operationId":"ScheduleController_getById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schedule"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Schedule not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get schedule","tags":["Schedules"]}},"/cats/v1/schedules/{id}/duplicate":{"post":{"description":"Duplicates a schedule, including all of its events. The new\n         schedule will be created in the same folder as the original and\n         will have the same name with the suffix ` (duplicate)`.","operationId":"ScheduleController_duplicate_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalSchedule"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to duplicate the schedule."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Duplicate schedule","tags":["Schedules"]}},"/cats/v1/schedules/{id}/publish":{"post":{"description":"Publishes the schedule to the targeted screens or screen groups.\nThis process is asynchronous and will return once the targets have been\nvalidated. The status of the publishing process can be queried using the\nreturned job id.","operationId":"ScheduleController_publish_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchedulePublishCommandDTO"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJob"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to publish the schedule, or to publish to the target screen or screen group."},"422":{"description":"Publish request is invalid."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Publish schedule","tags":["Schedules"]}},"/cats/v1/tags":{"post":{"operationId":"TagController_create_v1","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagCreateCommand"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalTag"}}}},"400":{"description":"Bad request."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"409":{"description":"Tag with the same name already exists."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Create tag","tags":["Tags"]},"get":{"operationId":"TagController_list_v1","parameters":[{"name":"name","required":false,"in":"query","description":"Filter tags by name. Performs an exact, case-insensitive match.","schema":{"type":"string"}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Optional sort in the format `field:dir` where `dir` is `asc` or `desc`.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.]+:(asc|desc)$"},"examples":{"desc":{"value":"id:desc"},"asc":{"value":"id:asc"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}}}]}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"List tags","tags":["Tags"]}},"/cats/v1/tags/{id}":{"get":{"operationId":"TagController_getById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tag"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Tag not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get tag","tags":["Tags"]},"patch":{"operationId":"TagController_update_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagUpdateCommand"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tag"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Tag not found."},"409":{"description":"New name already exists."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Update tag","tags":["Tags"]},"delete":{"operationId":"TagController_delete_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Tag not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Delete tag","tags":["Tags"]}},"/cats/v1/publish/{id}":{"get":{"description":"Returns the current state of a publish job. Use this to poll for\ncompletion after calling `POST /playlists/{id}/publish` or\n`POST /schedules/{id}/publish` — the job ID is returned in those responses.\nPoll until `status` reaches `COMPLETED` or `FAILED`. The `screens` array\nprovides per-screen granularity so you can identify which screens succeeded\nor failed individually. Access is permitted if the caller has read access\nto at least one screen targeted by the job.","operationId":"PublishController_getJobById_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJob"}}}},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised to access this resource."},"404":{"description":"Job not found."}},"security":[{"personal-access-token":[]},{"oauth2":[]}],"summary":"Get publish job","tags":["Publishing"]}},"/cats/v1/proof-of-play/summary":{"get":{"description":"Returns aggregated proof of play data grouped by the requested dimensions.\nThe `MEDIA` dimension is always present in the output. Additional\ndimensions (`SCREEN`, `PLAYLIST`, `DATE`) can be requested via the\n`groupBy` parameter.\n\nThe date range must not exceed 90 days. Proof of play data older than\n90 days is permanently deleted and cannot be queried.","operationId":"ProofOfPlayController_getSummary_v1","parameters":[{"name":"startDate","required":true,"in":"query","description":"Start of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-01T00:00:00Z`.","schema":{"type":"string"}},{"name":"endDate","required":true,"in":"query","description":"End of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-31T23:59:59Z`.\nMust be on or after `startDate`. The range must not exceed 90 days.","schema":{"type":"string"}},{"name":"screenIdentities","required":false,"in":"query","description":"Restrict results to the specified screen identities.\nWhen omitted, all screens accessible to the current user are included.\nRequesting a screen the caller cannot access returns `403 Forbidden`.","schema":{"type":"array","items":{"type":"string"}}},{"name":"groupBy","required":false,"in":"query","description":"Dimensions to group the results by.\nDefaults to `['MEDIA']`. `media` is always present in the output\nregardless of whether it is explicitly listed here.","schema":{"type":"array","items":{"type":"string","enum":["MEDIA","SCREEN","PLAYLIST","DATE"]}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofOfPlaySummary"}}}},"400":{"description":"`startDate` or `endDate` is missing, invalid, or the range exceeds 90 days."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised — either the company lacks the Proof of Play entitlement,"}},"security":[{"personal-access-token":[]}],"summary":"Get proof of play summary","tags":["Proof of play"]}},"/cats/v1/proof-of-play/details":{"get":{"description":"Returns a paginated list of individual play events. Each row represents a\nsingle play occurrence on a screen.\n\nThe date range must not exceed 90 days. Proof of play data older than\n90 days is permanently deleted and cannot be queried.","operationId":"ProofOfPlayController_getDetails_v1","parameters":[{"name":"startDate","required":true,"in":"query","description":"Start of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-01T00:00:00Z`.","schema":{"type":"string"}},{"name":"endDate","required":true,"in":"query","description":"End of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-31T23:59:59Z`.\nMust be on or after `startDate`. The range must not exceed 90 days.","schema":{"type":"string"}},{"name":"screenIdentities","required":false,"in":"query","description":"Restrict results to the specified screen identities.\nWhen omitted, all screens accessible to the current user are included.","schema":{"type":"array","items":{"type":"string"}}},{"name":"mediaIds","required":false,"in":"query","description":"Restrict results to plays of the specified media IDs.\nWhen omitted, plays of all media are included.","schema":{"type":"array","items":{"type":"number"}}},{"name":"playlistIds","required":false,"in":"query","description":"Restrict results to plays that occurred within the specified playlist IDs.\nWhen omitted, plays from all playlists (and non-playlist plays) are included.","schema":{"type":"array","items":{"type":"number"}}},{"name":"offset","required":true,"in":"query","description":"Zero-based index of the first item to return.","schema":{"minimum":0,"default":0,"type":"number"}},{"name":"limit","required":true,"in":"query","description":"Maximum number of items to return per page.","schema":{"minimum":1,"default":10,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SwaggerPaginatedResult"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProofOfPlayDetail"}}}}]}}}},"400":{"description":"`startDate` or `endDate` is missing, invalid, or the range exceeds 90 days."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised — either the company lacks the Proof of Play entitlement,"}},"security":[{"personal-access-token":[]}],"summary":"Get proof of play details","tags":["Proof of play"]}},"/cats/v1/proof-of-play/export.csv":{"get":{"description":"Streams the full result set for the specified date range and filters as a\ndownloadable CSV file. All matching rows are included.\n\nWhen no data matches the filters, an empty CSV with headers only is returned.\n\nThe date range must not exceed 90 days. Proof of play data older than\n90 days is permanently deleted and cannot be exported.","operationId":"ProofOfPlayController_exportCsv_v1","parameters":[{"name":"startDate","required":true,"in":"query","description":"Start of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-01T00:00:00Z`.","schema":{"type":"string"}},{"name":"endDate","required":true,"in":"query","description":"End of the reporting date range (inclusive), as an ISO 8601 datetime string, e.g. `2025-01-31T23:59:59Z`.\nMust be on or after `startDate`. The range must not exceed 90 days.","schema":{"type":"string"}},{"name":"screenIdentities","required":false,"in":"query","description":"Restrict results to the specified screen identities.\nWhen omitted, all screens accessible to the current user are included.","schema":{"type":"array","items":{"type":"string"}}},{"name":"mediaIds","required":false,"in":"query","description":"Restrict results to plays of the specified media IDs.\nWhen omitted, plays of all media are included.","schema":{"type":"array","items":{"type":"number"}}},{"name":"playlistIds","required":false,"in":"query","description":"Restrict results to plays that occurred within the specified playlist IDs.\nWhen omitted, plays from all playlists (and non-playlist plays) are included.","schema":{"type":"array","items":{"type":"number"}}}],"responses":{"200":{"description":""},"400":{"description":"`startDate` or `endDate` is missing, invalid, or the range exceeds 90 days."},"401":{"description":"Not authenticated."},"403":{"description":"Not authorised."}},"security":[{"personal-access-token":[]}],"summary":"Export proof of play as CSV","tags":["Proof of play"]}}},"info":{"title":"Fusion Signage API","description":"The Fusion Signage API powers the Fusion Signage digital signage platform. Use it to manage folders, media, playlists, schedules, screens and screen groups — and to deploy content to your screens.\n\n## Authentication\n\nAll endpoints require authentication with either a **Personal Access Token (PAT)** issued from your Fusion Signage account, or with an **OAuth 2.0 access token**. Pass the token in the `Authorization` header as a Bearer token:\n\n```\nAuthorization: Bearer <your-token>\n```\n\nSee [our support site](https://support.fusionsignage.com.au/en/articles/12636349-personal-access-tokens) for details on how to generate a Personal Access Token.\n\nOur OAuth 2.0 implementation supports the [OpenID Connect Discovery Endpoint](https://auth.fusionsignage.com.au/.well-known/openid-configuration) to find the correct OAuth 2.0 / OIDC configuration settings. You can use the [oauth2.dev OpenID configuration validator tool](https://oauth2.dev/tools/openid-configuration-validator) to explore the settings further.\n\n## Getting started\n\nA typical workflow is:\n1. Create or list **folders** to organise your content.\n2. Upload **media** (images, videos, web pages, etc.) into a folder.\n3. Build **playlists** from your media items.\n4. Optionally wrap playlists in a **schedule** to automate playback across different dates and times.\n5. **Publish** a playlist or schedule to one or more **screens** or **screen groups**.\n\n## Pagination\n\nList endpoints return a paginated result. Use the `offset` and `limit` query parameters to page through results. The `total` field in the response indicates the total number of matching items.\n\n## Licence requirements\n\nSome features - such as schedules, screen groups, tagging, and certain media types - require a specific licence level. Use the `GET /licences/features` endpoint to check which features are available for your account.\n\n## Rate limiting\n\nAuthenticated requests are limited to **20 requests per second** per user. Exceeding this limit will result in a `429 Too Many Requests` response. If you receive a 429, back off and retry after a short delay.","version":"1.0","contact":{}},"tags":[{"name":"Folders","description":"Folders are used to organise digital signage content, including media, playlists and schedules, for easier management."},{"name":"Assets","description":"Assets provide a unified, high-level representation of all supported digital signage content, such as media, playlists and schedules."},{"name":"Media","description":"Media represents visual content such as images, videos, web pages and dynamic templates that can be added to playlists."},{"name":"Playlists","description":"Playlists are collections of media items with specific playback settings. Playlists are used to deploy content to screens."},{"name":"Schedules","description":"Schedules are collections of playlists with specific timing and recurrence rules. Schedules are used to automate content playback on screens across different dates and times."},{"name":"Screens","description":"Screens are the hardware devices running the signage player application to display your content."},{"name":"Screen groups","description":"Screen groups are collections of screens that can be managed collectively."},{"name":"Licences","description":"Licences control access to platform features."},{"name":"Publishing","description":"Publishing deploys content from playlists and schedules to screens."},{"name":"Tags","description":"Tags are custom attributes that can be applied to media and screens to help organise and filter your digital signage content."},{"name":"Proof of play","description":"**Coming soon** - This API is still in development. Pro licence holders can still use the CMS to export proof of play data.\n      \nProof of Play provides reporting on media playback events across your screens, including aggregated summaries and individual play records. Use it to verify that content was delivered and to analyse playback performance."}],"servers":[],"components":{"securitySchemes":{"personal-access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"Authorization","description":"Authenticate using a personal access token for your account.\n        \nReview [our support site](https://support.fusionsignage.com.au/en/articles/12636349-personal-access-tokens) for details on how to get a personal access token.\n        ","in":"header"},"oauth2":{"type":"openIdConnect","flows":{},"openIdConnectUrl":"https://auth.fusionsignage.com.au/.well-known/openid-configuration"}},"schemas":{"FolderCrudPermissions":{"type":"object","properties":{"create":{"type":"boolean","description":"Whether the current user can create a sub-folder inside this folder."},"read":{"type":"boolean","description":"Whether the current user can read this folder. This includes the contents\nof the folder."},"update":{"type":"boolean","description":"Whether the current user can rename or move this folder."},"delete":{"type":"boolean","description":"Whether the current user can delete this folder."}},"required":["create","read","update","delete"]},"FolderAssetPermissions":{"type":"object","properties":{"create":{"type":"object","description":"A map of asset type to a boolean indicating whether the current user can\ncreate that type of asset in this folder."}},"required":["create"]},"FolderMediaPermissions":{"type":"object","properties":{"create":{"type":"object","description":"A map of media type to a boolean indicating whether the current user can\ncreate that type of media in this folder."}},"required":["create"]},"FolderPermissions":{"type":"object","properties":{"folder":{"description":"Permissions for CRUD operations on the folder itself.","allOf":[{"$ref":"#/components/schemas/FolderCrudPermissions"}]},"asset":{"description":"Permissions for creating assets (media, playlists, schedules) inside this\nfolder.","allOf":[{"$ref":"#/components/schemas/FolderAssetPermissions"}]},"media":{"description":"Permissions for creating specific media types inside this folder.","allOf":[{"$ref":"#/components/schemas/FolderMediaPermissions"}]}},"required":["folder","asset","media"]},"Folder":{"type":"object","properties":{"id":{"type":"number","description":"The unique identifier of the folder."},"name":{"type":"string","description":"The name of the folder."},"type":{"type":"string","description":"The type of the folder. Most folders are `STANDARD`. `LOCATION` folders\nare linked to the location management system and cannot be moved.","enum":["STANDARD","LOCATION"]},"parentId":{"type":"number","description":"The ID of the parent folder. Absent when this is a root-level folder."},"assetCount":{"type":"number","description":"The number of assets (media, playlists, schedules) directly contained in\nthis folder. Does not include assets in sub-folders."},"sortSequence":{"type":"number","description":"A comparable number used to order this folder relative to its siblings.\nLower values appear first. Siblings with the same value will have an\narbitrary but stable order."},"permissions":{"description":"The permissions the current user has on this folder.","allOf":[{"$ref":"#/components/schemas/FolderPermissions"}]}},"required":["id","name","type","assetCount","sortSequence","permissions"]},"FolderListRootPermissions":{"type":"object","properties":{"folder":{"type":"object","description":"Permissions for creating root-level folders and assets outside any folder."}},"required":["folder"]},"FolderList":{"type":"object","properties":{"folders":{"description":"The complete list of all folders accessible to the current user. This is\nnot paginated — the full folder tree is returned at once.","type":"array","items":{"$ref":"#/components/schemas/Folder"}},"rootPermissions":{"description":"The current user's permissions at the root level (outside any folder).","allOf":[{"$ref":"#/components/schemas/FolderListRootPermissions"}]}},"required":["folders","rootPermissions"]},"FolderCreateCommand":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":250},"parentId":{"type":"number","nullable":true,"description":"Leave null to create a root folder."},"sortSequence":{"type":"number","description":"A comparable number representing the sortable sequence of this folder\nrelative to its siblings. Does not need to be in a precise incremental\norder - e.g. 1, 2, 3 or 1, 10, 100 will be accepted.\n\nIf this matches the sort sequence of a sibling, then siblings will be\nshifted to achieve the desired sort order. There is no guarantee that the\nvalue you provide will be used exactly as-is."}},"required":["name"]},"MinimalFolder":{"type":"object","properties":{"id":{"type":"number","description":"The unique identifier of the folder."},"name":{"type":"string","description":"The name of the folder."}},"required":["id","name"]},"FolderUpdateCommandDTO":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":250},"parentId":{"type":"number","nullable":true,"description":"Leave null to create a root folder."},"sortSequence":{"type":"number","description":"A comparable number representing the sortable sequence of this folder\nrelative to its siblings. Does not need to be in a precise incremental\norder - e.g. 1, 2, 3 or 1, 10, 100 will be accepted.\n\nIf this matches the sort sequence of a sibling, then siblings will be\nshifted to achieve the desired sort order. There is no guarantee that the\nvalue you provide will be used exactly as-is."}}},"LicenceFeatureDetail":{"type":"object","properties":{"feature":{"type":"string","description":"The feature identifier.","enum":["MEDIA_REPLACE","MEDIA_TYPE_CANVA","MEDIA_TYPE_DESIGN","MEDIA_TYPE_POWER_BI","MEDIA_TYPE_TABLEAU","MEDIA_TYPE_WIDGET","MEDIA_TYPE_ZONE","PLAYLIST_NESTED","PLAYLIST_SLIDE_SCHEDULE","PLAYLIST_SLIDE_VISIBILITY","PUBLISH_INTERACTIVE","SCHEDULE","SCREEN_GROUP","TAGGING"]},"requiredLevel":{"type":"string","description":"The minimum licence level required to access this feature.","enum":["BASIC","ADVANCED","PRO","DEMO","TRIAL"]},"available":{"type":"boolean","description":"Whether this feature is available with the company's current licence level."}},"required":["feature","requiredLevel","available"]},"LicenceFeaturesResponse":{"type":"object","properties":{"licenceLevel":{"type":"string","description":"The effective licence level of the user company.","enum":["BASIC","ADVANCED","PRO","DEMO","TRIAL"]},"features":{"description":"All features, each with its required licence level and whether it is\navailable at the company's current licence level.","type":"array","items":{"$ref":"#/components/schemas/LicenceFeatureDetail"}}},"required":["licenceLevel","features"]},"SwaggerPaginatedResult":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items that match the query across the entire dataset, not just the current page. Use this to calculate the number of pages (e.g., Math.ceil(total / limit))."},"offset":{"type":"number","description":"Zero-based index of the first item in this page relative to the full result set. Equivalent to SQL OFFSET or \"skip\". For the first page this is typically 0. Must be < total to contain data."},"limit":{"type":"number","description":"Maximum number of items requested per page. The actual number of items returned (data.length) may be less than or equal to this value, especially on the final page."},"data":{"additionalProperties":false,"description":"Items for the current page. Length is <= limit and may be 0 when there are no results or when offset >= total.","type":"array","items":{"type":"object"}}},"required":["total","offset","limit","data"]},"Origin":{"type":"object","properties":{"mediaType":{"type":"string","description":"The type of media you are creating.","enum":["IMAGE","VIDEO","WIDGET","WEBSITE","CANVA","POWER_BI","TABLEAU","DESIGN","ZONE","DOCUMENT"]},"source":{"type":"string","description":"The source of the media file. Media uploaded directly should use\n`PROVIDED`. The server will download `EXTERNAL` media on the caller's\nbehalf. `HOSTED` media will never be downloaded.\n\n**IMPORTANT:** `EXTERNAL` media is only downloaded from a domain allowlist\nthat we maintain. Please contact support to get your domain added to the\nallowlist.","enum":["PROVIDED","EXTERNAL","HOSTED"]},"url":{"type":"string","format":"uri"}},"required":["mediaType","source"]},"Dimensions":{"type":"object","properties":{"width":{"type":"number"},"height":{"type":"number"}},"required":["width","height"]},"Thumbnail":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"MinimalProcessedFile":{"type":"object","properties":{"format":{"type":"string"},"sizeInBytes":{"type":"number"}},"required":["format","sizeInBytes"]},"MediaAsset":{"type":"object","properties":{"type":{"description":"The type of asset.","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"],"type":"string","default":"MEDIA"},"origin":{"description":"The origin of the media item when it was created.","allOf":[{"$ref":"#/components/schemas/Origin"}]},"status":{"type":"string","description":"The current processing status of the media item.","enum":["CREATED","IMPORTING","UPLOADING","PROCESSING","READY","FAILED"]},"durationInSeconds":{"type":"number","description":"The duration of the media in seconds. Only present for timed media types such as video."},"dimensions":{"description":"The pixel dimensions of the media. Only present for visual media types.","allOf":[{"$ref":"#/components/schemas/Dimensions"}]},"thumbnail":{"description":"A thumbnail image representing the media item.","allOf":[{"$ref":"#/components/schemas/Thumbnail"}]},"files":{"description":"The processed file formats available for this media item.","type":"array","items":{"$ref":"#/components/schemas/MinimalProcessedFile"}},"usageCount":{"type":"number","description":"The number of playlists this media item appears in."},"tags":{"description":"Tags associated with this media item.","type":"array","items":{"type":"string"}},"id":{"type":"number","description":"The unique numeric identifier of the asset."},"name":{"type":"string","description":"The display name of the asset."},"folder":{"description":"The folder the asset is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"lastUpdated":{"format":"date-time","type":"string","description":"The UTC date and time the asset was last modified."}},"required":["type","origin","status","usageCount","tags","id","name","folder"]},"PlaylistAsset":{"type":"object","properties":{"type":{"description":"The type of asset.","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"],"type":"string","default":"PLAYLIST"},"durationInSeconds":{"type":"number","description":"The total playback duration of the playlist in seconds, calculated as the sum of all item durations."},"itemCount":{"type":"number","description":"The number of items in the playlist."},"usageCount":{"type":"number","description":"The number of schedules and playlists this playlist appears in."},"id":{"type":"number","description":"The unique numeric identifier of the asset."},"name":{"type":"string","description":"The display name of the asset."},"folder":{"description":"The folder the asset is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"lastUpdated":{"format":"date-time","type":"string","description":"The UTC date and time the asset was last modified."}},"required":["type","durationInSeconds","itemCount","usageCount","id","name","folder"]},"ScheduleAsset":{"type":"object","properties":{"type":{"description":"The type of asset.","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"],"type":"string","default":"SCHEDULE"},"itemCount":{"type":"number","description":"The number of events in this schedule."},"usageCount":{"type":"number","description":"The number of screens this schedule is published to."},"id":{"type":"number","description":"The unique numeric identifier of the asset."},"name":{"type":"string","description":"The display name of the asset."},"folder":{"description":"The folder the asset is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"lastUpdated":{"format":"date-time","type":"string","description":"The UTC date and time the asset was last modified."}},"required":["type","itemCount","usageCount","id","name","folder"]},"AssetKey":{"type":"object","properties":{"id":{"type":"number"},"type":{"type":"string","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"]}},"required":["id","type"]},"BulkMoveCommand":{"type":"object","properties":{"folderId":{"type":"number","description":"The destination folder id to move the assets to."},"assets":{"description":"The assets to move.","minItems":1,"type":"array","items":{"$ref":"#/components/schemas/AssetKey"}}},"required":["folderId","assets"]},"BulkDeleteCommand":{"type":"object","properties":{"folderId":{"type":"number","description":"If provided, performs a recursive delete of the folder and all of its\ncontents — including media, playlists, schedules, and child folders.\nThe assets array is ignored when folderId is set."},"assets":{"description":"The assets to delete. Required when folderId is not provided.","minItems":1,"type":"array","items":{"$ref":"#/components/schemas/AssetKey"}}},"required":["assets"]},"AssetUsageDetail":{"type":"object","properties":{"lastUpdated":{"format":"date-time","type":"string"},"id":{"type":"number","description":"The unique numeric identifier of the asset."},"type":{"type":"string","description":"The type of asset.","enum":["PLAYLIST","SCHEDULE","MEDIA","SCREEN","SCREEN_GROUP"]},"name":{"type":"string","description":"The display name of the asset."}},"required":["id","type","name"]},"AssetUsageEdge":{"type":"object","properties":{"asset":{"description":"The asset at this node in the usage graph.","allOf":[{"$ref":"#/components/schemas/AssetUsageDetail"}]},"parent":{"description":"The parent asset that directly references `asset`. For example, if a\nmedia item is used inside a playlist, the playlist is the parent.","allOf":[{"$ref":"#/components/schemas/AssetUsageDetail"}]},"depth":{"type":"number","description":"The number of hops from the originally queried asset to this edge.\nA depth of `1` indicates an immediate parent, `2` a grandparent, and so on."}},"required":["asset","parent","depth"]},"WebsiteOptions":{"type":"object","properties":{"cookie":{"type":"string","description":"The cookie to use when accessing the website. \\\\","example":"cookieName=cookieValue"}}},"PowerBiOptions":{"type":"object","properties":{"pageName":{"type":"string","description":"The page to load when the Power BI report is opened."}}},"TableauOptions":{"type":"object","properties":{"viewId":{"type":"string","description":"The view to load when the Tableau report is opened."}}},"DesignOptions":{"type":"object","properties":{"overlay":{"type":"boolean","description":"Has the design been created to be used as an overlay? This setting affects\nhow the design is managed by players."},"templateId":{"type":"string","description":"The template id that the design is created from."},"backgroundVideoUrl":{"type":"string","description":"The background video to play behind the design. This video is assumed to\nbe a provided video that has already been uploaded into the CMS.","format":"uri"}},"required":["overlay","templateId"]},"WidgetOptions":{"type":"object","properties":{"viewMode":{"type":"string","description":"The view mode to use when rendering the widget. View modes include:\n* `DEFAULT` - The default view mode.\n* `OVERLAY` - The widget can be used as an overlay. It will be rendered in\nas a transparent overlay and can no longer be used as a standalone playlist\nitem.\n* `INTERACTIVE` - The widget can be used as an interactive widget. Use this\nto support kiosk-like widgets.","enum":["DEFAULT","OVERLAY","INTERACTIVE"]}},"required":["viewMode"]},"CanvaOptions":{"type":"object","properties":{"width":{"type":"number","description":"The export width in pixels.","minimum":1},"height":{"type":"number","description":"The export height in pixels.","minimum":1},"exportTarget":{"type":"string","description":"Whether the design should be exported as a static `IMAGE` or a `VIDEO`.","enum":["VIDEO","IMAGE"]},"duration":{"type":"number","description":"The duration in seconds to display the exported image for. Only applicable\nwhen `exportTarget` is `IMAGE`.","minimum":1}},"required":["width","height","exportTarget"]},"DocumentOptions":{"type":"object","properties":{"durationPerPage":{"type":"number","description":"The number of seconds each page of the document is displayed before\nadvancing to the next page.","minimum":1}},"required":["durationPerPage"]},"MediaCreateCommand":{"type":"object","properties":{"options":{"description":"Specific options related to the media type.","anyOf":[{"$ref":"#/components/schemas/WebsiteOptions"},{"$ref":"#/components/schemas/PowerBiOptions"},{"$ref":"#/components/schemas/TableauOptions"},{"$ref":"#/components/schemas/DesignOptions"},{"$ref":"#/components/schemas/WidgetOptions"},{"$ref":"#/components/schemas/CanvaOptions"},{"$ref":"#/components/schemas/DocumentOptions"}]},"origin":{"description":"The origin of the media item. This includes the type of media and where it\nis located.","allOf":[{"$ref":"#/components/schemas/Origin"}]},"name":{"type":"string","description":"The publicly visible name of the media item. This could be the file name or\na human-readable name.","maxLength":150},"folderId":{"type":"number","description":"The folder to store the media item in."},"tags":{"description":"An optional list of tag names to assign to the media item. The tags must\nhave already been created.","type":"array","items":{"type":"string"}}},"required":["origin","name","folderId"]},"MinimalMedia":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string","description":"The display name of the media item."},"folder":{"description":"The folder the media item is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]}},"required":["id","name","folder"]},"MediaUploadStartResponse":{"type":"object","properties":{"uploadUrl":{"type":"string"}},"required":["uploadUrl"]},"MediaUploadCompleteCommandDTO":{"type":"object","properties":{"uploadUrl":{"type":"string","description":"The upload URL that was returned by the `startUpload` response. This is\nused to identify which upload is being confirmed as complete.","format":"uri"},"contentType":{"type":"string","description":"The MIME type of the uploaded file (e.g. `image/jpeg`, `video/mp4`,\n`application/pdf`)."}},"required":["uploadUrl","contentType"]},"CanvaUpdateOptions":{"type":"object","properties":{"duration":{"type":"number","description":"The duration in seconds to display the exported image for. Only applicable\nwhen `exportTarget` is `IMAGE`.","minimum":1},"exportTarget":{"description":"Whether the design should be exported as a static `IMAGE` or a `VIDEO`.","enum":["VIDEO","IMAGE"],"type":"string"}}},"DocumentUpdateOptions":{"type":"object","properties":{"durationPerPage":{"type":"number","description":"The number of seconds each page of the document is displayed before\nadvancing to the next page.","minimum":1}}},"MediaUpdateCommandDTO":{"type":"object","properties":{"options":{"anyOf":[{"$ref":"#/components/schemas/CanvaUpdateOptions"},{"$ref":"#/components/schemas/DocumentUpdateOptions"}]},"name":{"type":"string","maxLength":150},"folderId":{"type":"number","description":"The folder to move the media item to."},"tags":{"description":"An optional list of tag names to assign to the media item. Replaces all\nexisting tags if provided. The tags must have already been created.","type":"array","items":{"type":"string"}}}},"Media":{"type":"object","properties":{"id":{"type":"number"},"origin":{"description":"The origin of the media item when it was uploaded.","allOf":[{"$ref":"#/components/schemas/Origin"}]},"name":{"type":"string","description":"The display name of the media item."},"folder":{"description":"The folder the media item is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"status":{"description":"The status of the media item. A media item not in a READY status will not\nbe publishable to screens.","enum":["CREATED","IMPORTING","UPLOADING","PROCESSING","READY","FAILED"],"type":"string"},"options":{"type":"object","description":"Any user-provided configuration options related to the media item."},"thumbnail":{"description":"The thumbnail image for the media item.","allOf":[{"$ref":"#/components/schemas/Thumbnail"}]},"durationInSeconds":{"type":"number","description":"The duration of the media item in seconds, if relevant."},"dimensions":{"description":"The dimensions of the media item in pixels, if relevant.","allOf":[{"$ref":"#/components/schemas/Dimensions"}]},"tags":{"description":"The tags assigned to this media item.","type":"array","items":{"type":"string"}},"created":{"format":"date-time","type":"string","description":"The UTC date and time the media was created."}},"required":["id","origin","name","folder","status","tags","created"]},"MediaLink":{"type":"object","properties":{"type":{"type":"string","description":"The link type - for example, a `DOWNLOAD` link, an `EDIT` link.","enum":["DOWNLOAD","EDIT","VIEW"]},"url":{"type":"string","description":"The link destination URL."},"sizeInBytes":{"type":"number","description":"The size in bytes of the file at the link destination URL.\nThis will only present known for `DOWNLOAD` links."}},"required":["type","url"]},"Metadata":{"type":"object","properties":{"tags":{"description":"An array of tags to assign to the screen.","type":"array","items":{"type":"string"}},"fields":{"type":"object","description":"Custom fields to assign to the screen."}},"required":["tags","fields"]},"ScreenPairCommand":{"type":"object","properties":{"pairingCode":{"type":"string","description":"The pairing code that is viewable on the screen."},"licenceNumber":{"type":"string","description":"The licence to assign to the screen. If not provided, then the next\navailable licence will be assigned."},"displayName":{"type":"string","description":"The screen name viewable in the CMS."},"ianaTimezone":{"type":"string","description":"The IANA timezone to assign to the screen."},"metadata":{"$ref":"#/components/schemas/Metadata"}},"required":["pairingCode","displayName","ianaTimezone"]},"MinimalScreen":{"type":"object","properties":{"identity":{"type":"string","description":"The short code that uniquely identifies the screen. Use this as the\n`identity` path parameter in screen-specific endpoints."},"displayName":{"type":"string","description":"The human-readable name of the screen as configured in the CMS."}},"required":["identity","displayName"]},"ScreenUpdateCommandDTO":{"type":"object","properties":{"displayName":{"type":"string","description":"The screen name viewable in the CMS."},"ianaTimezone":{"type":"string","description":"The IANA timezone to assign to the screen."},"metadata":{"$ref":"#/components/schemas/Metadata"}}},"MinimalLicence":{"type":"object","properties":{"licenceLevel":{"type":"string","description":"The licence tier level, which determines which features are available.","enum":["BASIC","ADVANCED","PRO","DEMO","TRIAL"]},"licenceNumber":{"type":"string","description":"The unique identifier for this licence (e.g. `FSN-XXXX-XXXX`)."},"term":{"type":"object","description":"The duration of the licence term as an ISO 8601 duration string\n(e.g. `P1Y` for annual, `P1M` for monthly)."},"expiresAt":{"format":"date-time","type":"string","description":"The UTC date and time when this licence expires."}},"required":["licenceLevel","licenceNumber","term","expiresAt"]},"MinimalScreenGroup":{"type":"object","properties":{"id":{"type":"number","description":"The ID of the screen group."},"name":{"type":"string","description":"The name of the screen group."}},"required":["id","name"]},"Configuration":{"type":"object","properties":{"displayName":{"type":"string","description":"The screen name viewable in the CMS."},"ianaTimezone":{"type":"string","description":"The assigned IANA timezone for this screen."},"metadata":{"description":"Metadata about the screen.","allOf":[{"$ref":"#/components/schemas/Metadata"}]},"licence":{"description":"The screen's assigned licence.","allOf":[{"$ref":"#/components/schemas/MinimalLicence"}]},"groups":{"description":"Groups that the screen is a member of.","type":"array","items":{"$ref":"#/components/schemas/MinimalScreenGroup"}}},"required":["displayName","ianaTimezone","metadata","groups"]},"OperatingSystem":{"type":"object","properties":{"name":{"type":"string","description":"The operating system name, such as Windows, BrightSign, Android, etc.\nThis will almost always typically mirror the `runtime`."},"version":{"type":"string","description":"The operating system version. This will typically be the major version -\nfor example, Windows would have versions 10 or 11; BrightSign has OS\nversions 8, 9, Android has 5 through 13, etc."},"build":{"type":"string","description":"Qualifying information about the operating system build. This might be\na Windows patch, or a firmware version, or the user agent, etc."}},"required":["name","version"]},"Memory":{"type":"object","properties":{"bytesAvailable":{"type":"number","description":"The number of bytes of RAM available to the device."},"bytesTotal":{"type":"number","description":"The number of bytes of RAM in total on the device."}},"required":["bytesAvailable","bytesTotal"]},"SystemInfo":{"type":"object","properties":{"brand":{"type":"string","description":"The device brand, such as Philips, Samsung, or LG."},"model":{"type":"string","description":"The device model, such as BDL4050D or QMC."},"os":{"description":"The device operating system version-related information.","allOf":[{"$ref":"#/components/schemas/OperatingSystem"}]},"serialNumber":{"type":"string","description":"The device serial number. This serial number is typically unique to the\nbrand and model."},"memory":{"description":"The most recent reported memory usage from the device.","allOf":[{"$ref":"#/components/schemas/Memory"}]},"cpuPercent":{"type":"number","description":"The most recent reported CPU usage from the device as an aggregated\npercentage. The specifics of how this is calculated will vary depending on\nthe device and its operating system.\n\nThe range will be between 0 and 100."},"temperatureCelsius":{"type":"object","description":"The most recent reported temperature from the device per source."}}},"Display":{"type":"object","properties":{"dimensions":{"$ref":"#/components/schemas/Dimensions"},"orientation":{"type":"string","enum":["PORTRAIT","LANDSCAPE","PORTRAIT_FLIPPED","LANDSCAPE_FLIPPED"]}}},"Application":{"type":"object","properties":{"runtime":{"type":"string","enum":["ANDROID","TIZEN","BRIGHTSIGN","WEB","WEBOS","WINDOWS","LINUX"]},"version":{"type":"string"}},"required":["runtime","version"]},"Health":{"type":"object","properties":{"lastSeen":{"format":"date-time","type":"string","description":"The last time this device contacted our servers."},"connectivity":{"type":"string","description":"The connectivity status. This may be inferred from the `lastSeen` date if\nmore accurate information is not available.","enum":["ONLINE","OFFLINE"]}},"required":["connectivity"]},"DeviceReport":{"type":"object","properties":{"systemInfo":{"description":"The device system information such as memory, model, and serial number.","allOf":[{"$ref":"#/components/schemas/SystemInfo"}]},"display":{"description":"The device's display information such as dimensions and orientation.\nThe display may be built-in or external.","allOf":[{"$ref":"#/components/schemas/Display"}]},"application":{"description":"The signage application that is currently running on the device.","allOf":[{"$ref":"#/components/schemas/Application"}]},"capabilities":{"type":"array","description":"A capability maps to a specific feature or attribute of a device. In the\ncase of attributes, such as reading the model or brand, you should expect\nthat a device without the capability will not return this information under\nthe deviceReport property.","items":{"type":"string","enum":["DEVICE::MODEL","DEVICE::BRAND","DEVICE::SERIAL_NUMBER","DEVICE::MEMORY","DEVICE::CPU","DEVICE::TEMPERATURE","DEVICE::RESTART","DEVICE::SCREENSHOT","APP::UPLOAD_LOGS","APP::RESTART","APP::UPGRADE","APP::DOWNGRADE","APP::CLEAR_CACHE"]}},"health":{"description":"Aggregated indicators about the health of the device.","allOf":[{"$ref":"#/components/schemas/Health"}]}},"required":["application","capabilities","health"]},"Content":{"type":"object","properties":{"type":{"type":"string","description":"How this content was allocated to the screen — either published directly\n(`DIRECT`) or inherited from a screen group (`SCREEN_GROUP`).","enum":["DIRECT","SCREEN_GROUP"]},"source":{"type":"string","description":"The source of the content that is playing.","enum":["PLAYLIST","SCHEDULE","INTERACTIVE"]},"id":{"type":"number","description":"The ID of the content that is playing. For example, this would be a\nplaylist ID if the source were `PLAYLIST`."},"name":{"type":"string","description":"The name of the content that is playing. For example, this would be the\nplaylist name if the source were `PLAYLIST`."},"playingSince":{"format":"date-time","type":"string","description":"The date and time when the content started playing on the screen."}},"required":["type","source","id","name","playingSince"]},"State":{"type":"object","properties":{"type":{"type":"string","description":"The current state of the screen.","enum":["IDLE","UNKNOWN","UPDATING_APPLICATION","PLAYING_CONTENT"]},"reportedAt":{"format":"date-time","type":"string","description":"The UTC date and time when this state was last reported or computed."}},"required":["type","reportedAt"]},"Screen":{"type":"object","properties":{"identity":{"type":"string","description":"The short code that identifies the screen."},"configuration":{"description":"Configuration applied to the application running on the screen.","allOf":[{"$ref":"#/components/schemas/Configuration"}]},"deviceReport":{"description":"The most recent reported information from the device.","allOf":[{"$ref":"#/components/schemas/DeviceReport"}]},"content":{"description":"What content is the screen playing?","allOf":[{"$ref":"#/components/schemas/Content"}]},"state":{"description":"The reported or computed screen state. For example, a screen may be\nattempting an update or downloading content. At the time of writing, there\nare only a minimal number of state transitions supported.","allOf":[{"$ref":"#/components/schemas/State"}]},"permissions":{"type":"object","properties":{"read":{"type":"boolean"},"update":{"type":"boolean"},"delete":{"type":"boolean"}},"required":["read","update","delete"]}},"required":["identity","configuration","state","permissions"]},"Screenshot":{"type":"object","properties":{"url":{"type":"string","description":"The public URL of the screenshot that can be embedded in an <img/> tag.\nThis URL will expire. If long-term viewing is required, it should be either\ndownloaded or you can re-fetch the screenshot and get a new URL."},"takenAt":{"format":"date-time","type":"string","description":"The date and time that the screenshot was taken."}},"required":["url","takenAt"]},"CommandDispatchRequestDTO":{"type":"object","properties":{"type":{"enum":["TAKE_SCREENSHOT","UPGRADE_APPLICATION","CLEAR_CACHE"],"type":"string"},"payload":{"type":"object"}},"required":["type"]},"Command":{"type":"object","properties":{"id":{"type":"string"},"targetIdentity":{"type":"string"},"type":{"enum":["TAKE_SCREENSHOT","UPGRADE_APPLICATION","CLEAR_CACHE"],"type":"string"},"payload":{"type":"object"},"status":{"enum":["PENDING","IN_PROGRESS","COMPLETED","FAILED"],"type":"string"}},"required":["id","targetIdentity","type","status"]},"ScreenGroupCreateCommand":{"type":"object","properties":{"name":{"type":"string","description":"The name of the screen group that provides context about its purpose.","maxLength":250},"parentId":{"type":"number","nullable":true,"description":"The parent screen group ID. Set to null for top-level screen groups."},"screenIdentities":{"description":"The identities of the screens to assign to this group.","type":"array","items":{"type":"string"}}},"required":["name"]},"ScreenGroupUpdateCommandDTO":{"type":"object","properties":{"name":{"type":"string","description":"The name of the screen group that provides context about its purpose.","maxLength":250},"parentId":{"type":"number","nullable":true,"description":"The parent screen group ID. Set to null for top-level screen groups."},"screenIdentities":{"description":"The identities of the screens to assign to this group.","type":"array","items":{"type":"string"}}}},"ScreenGroupContent":{"type":"object","properties":{"source":{"type":"string","description":"The source of the content that is playing.","enum":["PLAYLIST","SCHEDULE","INTERACTIVE"]},"id":{"type":"number","description":"The ID of the content that is playing. For example, this would be a\nplaylist ID if the source were `PLAYLIST`."},"name":{"type":"string","description":"The name of the content that is playing. For example, this would be the\nplaylist name if the source were `PLAYLIST`."}},"required":["source","id","name"]},"ScreenGroupMember":{"type":"object","properties":{"identity":{"type":"string","description":"The identity (short code) of the screen."},"displayName":{"type":"string","description":"The display name of the screen."}},"required":["identity","displayName"]},"ScreenGroup":{"type":"object","properties":{"id":{"type":"number","description":"The ID of the screen group."},"name":{"type":"string","description":"The name of the screen group."},"parentId":{"type":"number","description":"The ID of the parent screen group. Absent for top-level screen groups."},"content":{"description":"What content has been published to the screen group?","allOf":[{"$ref":"#/components/schemas/ScreenGroupContent"}]},"screens":{"description":"The screens that are members of this group.","type":"array","items":{"$ref":"#/components/schemas/ScreenGroupMember"}},"permissions":{"type":"object","properties":{"read":{"type":"boolean"},"update":{"type":"boolean"},"delete":{"type":"boolean"}},"required":["read","update","delete"]}},"required":["id","name","screens","permissions"]},"ScreenGroupAddScreenCommand":{"type":"object","properties":{"identity":{"type":"string","description":"The identity of the screen to add to the group."}},"required":["identity"]},"AndPredicate":{"type":"object","properties":{"conditions":{"type":"array","minItems":1,"items":{"oneOf":[{"$ref":"#/components/schemas/AndPredicate"},{"$ref":"#/components/schemas/OrPredicate"},{"$ref":"#/components/schemas/NotPredicate"},{"$ref":"#/components/schemas/ScreenTagEqualsPredicate"},{"$ref":"#/components/schemas/DateRangePredicate"}]}},"type":{"enum":["AND","OR","NOT","SCREEN_TAG_EQUALS","DATE_RANGE"],"type":"string","default":"AND"}},"required":["conditions","type"]},"OrPredicate":{"type":"object","properties":{"conditions":{"type":"array","minItems":1,"items":{"oneOf":[{"$ref":"#/components/schemas/AndPredicate"},{"$ref":"#/components/schemas/OrPredicate"},{"$ref":"#/components/schemas/NotPredicate"},{"$ref":"#/components/schemas/ScreenTagEqualsPredicate"},{"$ref":"#/components/schemas/DateRangePredicate"}]}},"type":{"enum":["AND","OR","NOT","SCREEN_TAG_EQUALS","DATE_RANGE"],"type":"string","default":"OR"}},"required":["conditions","type"]},"NotPredicate":{"type":"object","properties":{"condition":{"oneOf":[{"$ref":"#/components/schemas/AndPredicate"},{"$ref":"#/components/schemas/OrPredicate"},{"$ref":"#/components/schemas/NotPredicate"},{"$ref":"#/components/schemas/ScreenTagEqualsPredicate"},{"$ref":"#/components/schemas/DateRangePredicate"}]},"type":{"enum":["AND","OR","NOT","SCREEN_TAG_EQUALS","DATE_RANGE"],"type":"string","default":"NOT"}},"required":["condition","type"]},"ScreenTagEqualsPredicate":{"type":"object","properties":{"type":{"enum":["AND","OR","NOT","SCREEN_TAG_EQUALS","DATE_RANGE"],"type":"string","default":"SCREEN_TAG_EQUALS"},"value":{"type":"string","maxLength":255}},"required":["type","value"]},"DateRangePredicate":{"type":"object","properties":{"type":{"enum":["AND","OR","NOT","SCREEN_TAG_EQUALS","DATE_RANGE"],"type":"string","default":"DATE_RANGE"},"startDate":{"type":"string","description":"The local date that this playlist item can start playing, in `YYYY-MM-DD`\nformat (e.g. `2025-03-15`). The date is evaluated in the timezone of the\nscreen."},"endDate":{"type":"string","description":"The local date that this playlist item must stop playing, in `YYYY-MM-DD`\nformat (e.g. `2025-12-31`). If omitted, the rule is active indefinitely.\nThe date is evaluated in the timezone of the screen."},"daysOfWeek":{"type":"array","description":"The days of the week that the playlist item should play. Must have at least\none day selected.","minItems":1,"items":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]}},"fromTime":{"type":"string","description":"The time that this playlist item will start playing, in 24-hour `HH:mm`\nformat (e.g. `09:00`). This is evaluated separately to the `startDate`\nand applies on each matching day of the week. The time is evaluated in\nthe timezone of the screen."},"toTime":{"type":"string","description":"The time that this playlist item will stop playing, in 24-hour `HH:mm`\nformat (e.g. `17:30`). This is evaluated separately to the `endDate`\nand applies on each matching day of the week. The time is evaluated in\nthe timezone of the screen."}},"required":["type","startDate","daysOfWeek","fromTime","toTime"]},"PlaylistItemOptions":{"type":"object","properties":{"rules":{"description":"The rules that must be met for this playlist item to be played.\n\n**IMPORTANT**: This item is for advanced usage only. Please reach out to\nsupport@fusionsignage.com.au if you plan to use it. Only certain\ncombinations of rule predicates are supported currently.","oneOf":[{"$ref":"#/components/schemas/AndPredicate"},{"$ref":"#/components/schemas/OrPredicate"},{"$ref":"#/components/schemas/NotPredicate"},{"$ref":"#/components/schemas/ScreenTagEqualsPredicate"},{"$ref":"#/components/schemas/DateRangePredicate"}]},"fitSetting":{"type":"string","description":"The fit setting to apply to the playlist item. Fit settings adjust how the\nmedia is rendered when the media size does not match the resolution of the\nscreen.\n\nFor best performance we strongly recommend you use the setting `FIT`.\n\nIf not set we will use the default settings configured against your\naccount.","enum":["FIT","FILL","STRETCH"]}}},"MediaPlaylistItemRequestDTO":{"type":"object","properties":{"type":{"enum":["MEDIA","SUB_PLAYLIST"],"type":"string","default":"MEDIA"},"mediaId":{"type":"number","description":"The ID of the media item."},"durationInSeconds":{"type":"number","description":"The duration (in seconds) that the item should play for before the playlist\nmoves to the next item. If not provided, the account's default playlist\nitem duration will be applied.\n\nThis value has no effect on video media. The actual length of the video\nwill always supersede this value."},"enabled":{"type":"boolean","description":"When false, the playlist item will be treated as if it does not exist."},"options":{"description":"Optional settings to apply to the playlist item.","allOf":[{"$ref":"#/components/schemas/PlaylistItemOptions"}]}},"required":["type","mediaId","enabled"]},"SubPlaylistPlaylistItemRequestDTO":{"type":"object","properties":{"type":{"enum":["MEDIA","SUB_PLAYLIST"],"type":"string","default":"SUB_PLAYLIST"},"playlistId":{"type":"number","description":"The ID of the sub-playlist."},"enabled":{"type":"boolean","description":"When false, the playlist item will be treated as if it does not exist."},"options":{"description":"Optional settings to apply to the playlist item.","allOf":[{"$ref":"#/components/schemas/PlaylistItemOptions"}]}},"required":["type","playlistId","enabled"]},"Overlay":{"type":"object","properties":{"mediaId":{"type":"number","description":"The ID of the media item to overlay over the playlist. Must be a media item\nof type DESIGN that has been configured as an overlay in Designer."},"fitSetting":{"type":"string","description":"The fit setting to apply to the playlist item. Fit settings adjust how the\nmedia is rendered when the media size does not match the resolution of the\nscreen.\n\nFor best performance we strongly recommend you use the setting `FIT`.","enum":["FIT","FILL","STRETCH"]}},"required":["mediaId"]},"PlaylistCreateCommand":{"type":"object","properties":{"items":{"type":"array","description":"The items to play in this playlist. These can be media items or another\nplaylist.\n\nThe order of items in this list determines the order they will be played.","items":{"oneOf":[{"$ref":"#/components/schemas/MediaPlaylistItemRequestDTO"},{"$ref":"#/components/schemas/SubPlaylistPlaylistItemRequestDTO"}]}},"name":{"type":"string","description":"The name of the playlist that provides context for the content or details\nabout its purpose.","maxLength":150},"folderId":{"type":"number","description":"The folder to store playlist in."},"overlay":{"description":"An optional overlay to apply to the playlist. The configured media will\noverlay the entire playlist. Use this to display logos, clocks, tickers\nthroughout your entire playlist.","allOf":[{"$ref":"#/components/schemas/Overlay"}]}},"required":["items","name","folderId"]},"MinimalPlaylist":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the playlist."},"name":{"type":"string","description":"The display name of the playlist."},"folder":{"description":"The folder this playlist is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]}},"required":["id","name","folder"]},"PlaylistUpdateCommandDTO":{"type":"object","properties":{"items":{"type":"array","description":"The items to play in this playlist. These can be media items or another\nplaylist.\n\nThe order of items in this list determines the order they will be played.","items":{"oneOf":[{"$ref":"#/components/schemas/MediaPlaylistItemRequestDTO"},{"$ref":"#/components/schemas/SubPlaylistPlaylistItemRequestDTO"}]}},"name":{"type":"string","description":"The name of the playlist that provides context for the content or details\nabout its purpose.","maxLength":150},"folderId":{"type":"number","description":"The folder to store playlist in."},"overlay":{"nullable":true,"description":"Pass `null` to remove the existing overlay.","type":"object","allOf":[{"$ref":"#/components/schemas/Overlay"}]}}},"ScreenTargets":{"type":"object","properties":{"identities":{"minItems":1,"type":"array","items":{"type":"string"}},"tags":{"minItems":1,"type":"array","items":{"type":"string"}},"groupIds":{"minItems":1,"type":"array","items":{"type":"number"}}}},"PlaylistPublishCommandDTO":{"type":"object","properties":{"targets":{"description":"The target screens to publish the playlist to. At least one of\n`identities`, `tags`, or `groupIds` must be provided.","allOf":[{"$ref":"#/components/schemas/ScreenTargets"}]}},"required":["targets"]},"PublishJobScreenState":{"type":"object","properties":{"identity":{"type":"string","description":"The identity of the screen this state entry belongs to."},"status":{"type":"string","description":"The current publish status for this screen.","enum":["PENDING","IN_PROGRESS","COMPLETED","FAILED"]},"updatedAt":{"format":"date-time","type":"string","description":"The UTC date and time when this screen's status was last updated."}},"required":["identity","status","updatedAt"]},"PublishJob":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of this publish job. Use this with\n`GET /publish/{id}` to poll for status."},"status":{"description":"The overall status of the publish job. A job is only `COMPLETED` when\nevery targeted screen has been successfully updated.","enum":["PENDING","IN_PROGRESS","COMPLETED","FAILED"],"type":"string"},"createdAt":{"format":"date-time","type":"string","description":"The UTC date and time when the publish job was created."},"updatedAt":{"format":"date-time","type":"string","description":"The UTC date and time when the publish job was last updated."},"screens":{"description":"The per-screen publish states. Each entry reflects the publish status for\nan individual screen in the targeted set.","type":"array","items":{"$ref":"#/components/schemas/PublishJobScreenState"}}},"required":["id","status","createdAt","updatedAt","screens"]},"PlaylistItem":{"type":"object","properties":{"type":{"type":"string","enum":["MEDIA","SUB_PLAYLIST"]},"enabled":{"type":"boolean","description":"When false, the playlist item will be treated as if it does not exist."},"options":{"description":"Optional settings to apply to the playlist item.","allOf":[{"$ref":"#/components/schemas/PlaylistItemOptions"}]}},"required":["type","enabled"]},"Playlist":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the playlist."},"name":{"type":"string","description":"The display name of the playlist."},"folder":{"description":"The folder this playlist is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"items":{"description":"The ordered list of items in this playlist. Items are played in sequence.\nEach item is either a media item (`MEDIA`) or a nested sub-playlist\n(`SUB_PLAYLIST`).","type":"array","items":{"$ref":"#/components/schemas/PlaylistItem"}},"overlay":{"description":"An optional overlay applied to the entire playlist (e.g. a logo or ticker).","allOf":[{"$ref":"#/components/schemas/Overlay"}]},"permissions":{"type":"object","properties":{"update":{"type":"boolean"},"delete":{"type":"boolean"}},"required":["update","delete"]}},"required":["id","name","folder","items","permissions"]},"Event":{"type":"object","properties":{"playlistId":{"type":"number","description":"The ID of the playlist that will be played during this event."},"startDate":{"type":"string","description":"The local date that the playlist will start playing, in `YYYY-MM-DD`\nformat (e.g. `2025-03-15`). The date is evaluated in the timezone of the\nscreen."},"endDate":{"type":"string","description":"The local date that the playlist will stop playing, in `YYYY-MM-DD`\nformat (e.g. `2025-12-31`). If omitted, the event recurs indefinitely.\nThe date is evaluated in the timezone of the screen."},"daysOfWeek":{"type":"array","description":"The days of the week that the playlist will play. Must have at least\none day selected.","minItems":1,"items":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]}},"fromTime":{"type":"string","description":"The local time that this playlist will start playing, in 24-hour `HH:mm`\nformat (e.g. `09:00`). This is evaluated separately to the `startDate`\nand applies on each matching day of the week. The time is evaluated in\nthe timezone of the screen."},"toTime":{"type":"string","description":"The local time that this playlist will stop playing, in 24-hour `HH:mm`\nformat (e.g. `17:30`). This is evaluated separately to the `endDate` and\napplies on each matching day of the week. The time is evaluated in the\ntimezone of the screen."}},"required":["playlistId","startDate","daysOfWeek","fromTime","toTime"]},"ScheduleCreateCommand":{"type":"object","properties":{"defaultPlaylistId":{"type":"number","description":"The ID of the playlist that will be played when no event is currently\nactive."},"name":{"type":"string","description":"The name of the schedule that provides context for the content or details\nabout its purpose.","maxLength":250},"folderId":{"type":"number","description":"The folder to store the schedule in."},"events":{"description":"A list of events associated with the schedule. Each event represents a\nspecific playlist to be displayed at a particular date and time","type":"array","items":{"$ref":"#/components/schemas/Event"}}},"required":["name","folderId","events"]},"MinimalSchedule":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the schedule."},"name":{"type":"string","description":"The display name of the schedule."},"folder":{"description":"The folder this schedule is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]}},"required":["id","name","folder"]},"ScheduleUpdateCommandDTO":{"type":"object","properties":{"name":{"type":"string","description":"The name of the schedule that provides context for the content or details\nabout its purpose.","maxLength":250},"folderId":{"type":"number","description":"The folder to store the schedule in."},"events":{"description":"A list of events associated with the schedule. Each event represents a\nspecific playlist to be displayed at a particular date and time","type":"array","items":{"$ref":"#/components/schemas/Event"}},"defaultPlaylistId":{"type":"number","nullable":true,"description":"The ID of the playlist that will be played when no event is currently\nactive. Set to null to clear out an existing default playlist."}}},"SchedulePublishCommandDTO":{"type":"object","properties":{"targets":{"description":"The target screens to publish the schedule to. At least one of\n`identities`, `tags`, or `groupIds` must be provided.","allOf":[{"$ref":"#/components/schemas/ScreenTargets"}]}},"required":["targets"]},"SelectableEvent":{"type":"object","properties":{"startDate":{"type":"string","description":"The local date that the playlist will start playing, in `YYYY-MM-DD`\nformat (e.g. `2025-03-15`). The date is evaluated in the timezone of the\nscreen."},"endDate":{"type":"string","description":"The local date that the playlist will stop playing, in `YYYY-MM-DD`\nformat (e.g. `2025-12-31`). If omitted, the event recurs indefinitely.\nThe date is evaluated in the timezone of the screen."},"daysOfWeek":{"description":"The days of the week that the playlist will play. Must have at least\none day selected.","minItems":1,"type":"array","items":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]}},"fromTime":{"type":"string","description":"The local time that this playlist will start playing, in 24-hour `HH:mm`\nformat (e.g. `09:00`). This is evaluated separately to the `startDate`\nand applies on each matching day of the week. The time is evaluated in\nthe timezone of the screen."},"toTime":{"type":"string","description":"The local time that this playlist will stop playing, in 24-hour `HH:mm`\nformat (e.g. `17:30`). This is evaluated separately to the `endDate` and\napplies on each matching day of the week. The time is evaluated in the\ntimezone of the screen."},"playlist":{"$ref":"#/components/schemas/MinimalPlaylist"}},"required":["startDate","daysOfWeek","fromTime","toTime","playlist"]},"Schedule":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the schedule."},"name":{"type":"string","description":"The display name of the schedule."},"folder":{"description":"The folder this schedule is stored in.","allOf":[{"$ref":"#/components/schemas/MinimalFolder"}]},"events":{"description":"The time-based events associated with this schedule. Each event defines\na playlist to play during a specific date/time window.","type":"array","items":{"$ref":"#/components/schemas/SelectableEvent"}},"defaultPlaylist":{"description":"The playlist to play when no event is currently active.","allOf":[{"$ref":"#/components/schemas/MinimalPlaylist"}]},"permissions":{"type":"object","properties":{"update":{"type":"boolean"},"delete":{"type":"boolean"}},"required":["update","delete"]}},"required":["id","name","folder","events","permissions"]},"TagCreateCommand":{"type":"object","properties":{"name":{"type":"string","description":"The name for the new tag. Must be unique within the company."}},"required":["name"]},"MinimalTag":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the tag."},"name":{"type":"string","description":"The tag name. Tag names are unique within a company."}},"required":["id","name"]},"Tag":{"type":"object","properties":{"id":{"type":"number","description":"The unique numeric identifier of the tag."},"name":{"type":"string","description":"The tag name. Tag names are unique within a company."},"createdAt":{"format":"date-time","type":"string","description":"The UTC date and time the tag was created."},"usageCount":{"type":"number","description":"The number of screens and media items this tag is assigned to."}},"required":["id","name","createdAt","usageCount"]},"TagUpdateCommand":{"type":"object","properties":{"name":{"type":"string","description":"The name for the new tag. Must be unique within the company."}},"required":["name"]},"ProofOfPlaySummaryRow":{"type":"object","properties":{"media":{"description":"The media item that was played.","allOf":[{"$ref":"#/components/schemas/MinimalMedia"}]},"screen":{"description":"The screen that played the media.\nPresent when `groupBy` includes `SCREEN`.","allOf":[{"$ref":"#/components/schemas/MinimalScreen"}]},"playlist":{"nullable":true,"description":"The playlist the media was playing from.\nPresent when `groupBy` includes `PLAYLIST`.\n`null` when the media was played outside of a playlist (e.g. interactive or overlay).","type":"object","allOf":[{"$ref":"#/components/schemas/MinimalPlaylist"}]},"date":{"type":"string","description":"The local calendar date on the screen when playback occurred, formatted as `YYYY-MM-DD`.\nWhen results span multiple screens in different timezones, each play event\nis assigned to a date based on that screen's configured timezone.\nPresent when `groupBy` includes `DATE`."},"playCount":{"type":"number","description":"Total number of play events for this combination of dimensions."},"durationMs":{"type":"number","description":"Total playback duration for this combination of dimensions, in milliseconds."}},"required":["media","playCount","durationMs"]},"ProofOfPlaySummary":{"type":"object","properties":{"totalPlayCount":{"type":"number","description":"Total play count across all rows in the result set."},"totalDurationMs":{"type":"number","description":"Total playback duration across all rows in the result set, in milliseconds."},"data":{"description":"Aggregated summary rows.","type":"array","items":{"$ref":"#/components/schemas/ProofOfPlaySummaryRow"}}},"required":["totalPlayCount","totalDurationMs","data"]},"ProofOfPlayDetail":{"type":"object","properties":{"id":{"type":"number","description":"Internal numeric identifier of this play event."},"media":{"description":"The media that was played.","allOf":[{"$ref":"#/components/schemas/MinimalMedia"}]},"screen":{"description":"The screen that played the media.","allOf":[{"$ref":"#/components/schemas/MinimalScreen"}]},"playlist":{"nullable":true,"description":"The playlist the media was playing from.\n`null` when the media was played outside of a playlist (e.g. interactive or overlay).","type":"object","allOf":[{"$ref":"#/components/schemas/MinimalPlaylist"}]},"playedAt":{"format":"date-time","type":"string","description":"UTC timestamp when this play event occurred."},"durationMs":{"type":"number","description":"Duration of this individual play event, in milliseconds."}},"required":["id","media","screen","playlist","playedAt","durationMs"]}}}}