mirror of
https://github.com/drakmor/ShadowMountPlus.git
synced 2026-10-22 14:42:27 -05:00
1982 lines
59 KiB
YAML
1982 lines
59 KiB
YAML
openapi: 3.1.2
|
|
info:
|
|
title: ShadowMount HTTP API
|
|
version: "1"
|
|
description: |
|
|
HTTP/JSON API exposed by the ShadowMountPlus payload. The service has no
|
|
authentication and should only be exposed on a trusted network.
|
|
servers:
|
|
- url: http://127.0.0.1:10101
|
|
description: Default loopback endpoint on the PS5
|
|
- url: http://{address}:{port}
|
|
description: Configured network endpoint
|
|
variables:
|
|
address:
|
|
default: 192.168.1.50
|
|
description: PS5 IPv4 address or hostname
|
|
port:
|
|
default: "10101"
|
|
description: Value of api_port
|
|
security: []
|
|
tags:
|
|
- name: Service
|
|
- name: Storage
|
|
- name: Scanner
|
|
- name: Manual sources
|
|
- name: Images
|
|
- name: Games
|
|
|
|
paths:
|
|
/:
|
|
options:
|
|
operationId: preflightIndex
|
|
summary: CORS preflight
|
|
tags: [Service]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
get:
|
|
operationId: getWebInterface
|
|
summary: Get the optional web interface
|
|
description: Serves /data/shadowmount/index.html when it is a regular file.
|
|
tags: [Service]
|
|
responses:
|
|
"200":
|
|
description: ShadowMount web interface
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/version:
|
|
options:
|
|
operationId: preflightVersion
|
|
summary: CORS preflight
|
|
tags: [Service]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getVersion
|
|
summary: Get API version and capabilities
|
|
tags: [Service]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/EmptyRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/VersionSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/images:
|
|
options:
|
|
operationId: preflightImages
|
|
summary: CORS preflight
|
|
tags: [Images]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: listImages
|
|
summary: Get the complete image snapshot
|
|
tags: [Images]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/EmptyRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ImagesSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/storage:
|
|
options:
|
|
operationId: preflightStorage
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getStorageSpace
|
|
summary: Get free space for mounted storage filesystems
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/EmptyRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/StorageSpaceSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/scan:
|
|
options:
|
|
operationId: preflightScan
|
|
summary: CORS preflight
|
|
tags: [Scanner]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: rescan
|
|
summary: Queue an immediate full rescan
|
|
description: Retry counters are preserved by default. With reset_attempts=true, all title registration/install-remount and path-owned image-mount retry counters are reset immediately before the requested scan starts. If game runtime mounts are busy, the request remains queued until scanning is safe.
|
|
tags: [Scanner]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/ScanRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ScanSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/manual/list:
|
|
options:
|
|
operationId: preflightListManualSources
|
|
summary: CORS preflight
|
|
tags: [Manual sources]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: listManualSources
|
|
summary: List direct game source paths from manual.lst
|
|
description: Entries identify individual game folders or images, not recursive scan roots. Comments and empty lines are omitted.
|
|
tags: [Manual sources]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/EmptyRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ManualListSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/manual/add:
|
|
options:
|
|
operationId: preflightAddManualSource
|
|
summary: CORS preflight
|
|
tags: [Manual sources]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: addManualSource
|
|
summary: Add a source path to manual.lst
|
|
tags: [Manual sources]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/ManualPathRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ManualUpdateSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/manual/remove:
|
|
options:
|
|
operationId: preflightRemoveManualSource
|
|
summary: CORS preflight
|
|
tags: [Manual sources]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: removeManualSource
|
|
summary: Remove all matching source lines from manual.lst
|
|
tags: [Manual sources]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/ManualPathRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/ManualUpdateSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/games:
|
|
options:
|
|
operationId: preflightGames
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: listGames
|
|
summary: Get the complete game snapshot
|
|
tags: [Games]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/GamesListRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/GamesSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/games/info:
|
|
options:
|
|
operationId: preflightGameInfo
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getGameInfo
|
|
summary: Get detailed metadata and size for a folder, image or installed PKG
|
|
tags: [Games]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/TitleRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/GameInfoSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/games/fakelib:
|
|
options:
|
|
operationId: preflightGameFakelib
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: setGameFakelib
|
|
summary: Set the fakelib mode or global overlay exclusion for a PS5 game on its next launch
|
|
tags: [Games]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [title_id]
|
|
oneOf:
|
|
- anyOf:
|
|
- required: [mode]
|
|
- required: [enabled]
|
|
not:
|
|
required: [ignore_global_fakelib]
|
|
- required: [ignore_global_fakelib]
|
|
not:
|
|
anyOf:
|
|
- required: [mode]
|
|
- required: [enabled]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
description: Must identify a PS5 game; homebrew uses its app.db platform.
|
|
mode:
|
|
type: string
|
|
enum: [default, full, emulators, disabled]
|
|
description: Default removes the title override; other modes override fakelib_default_mode. Takes precedence over enabled.
|
|
enabled:
|
|
type: boolean
|
|
description: Legacy alternative selecting explicit full when true or disabled when false.
|
|
ignore_global_fakelib:
|
|
type: boolean
|
|
description: Update only the global overlay exclusion. False removes it. Cannot be combined with mode or enabled.
|
|
responses:
|
|
"200":
|
|
description: Per-title policy saved; existing mounts are preserved
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [status, title_id, fakelib_mode, fakelib_mode_override, fakelib_default_mode, fakelib_enabled, fakelib_effective_enabled, ignore_global_fakelib, saved, applies_on_next_launch]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
fakelib_mode:
|
|
type: string
|
|
enum: [full, emulators, disabled]
|
|
fakelib_mode_override:
|
|
type: string
|
|
enum: [default, full, emulators, disabled]
|
|
fakelib_default_mode:
|
|
type: string
|
|
enum: [full, emulators, disabled]
|
|
fakelib_enabled:
|
|
type: boolean
|
|
fakelib_effective_enabled:
|
|
type: boolean
|
|
ignore_global_fakelib:
|
|
type: boolean
|
|
saved:
|
|
type: boolean
|
|
const: true
|
|
applies_on_next_launch:
|
|
type: boolean
|
|
const: true
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"507":
|
|
description: Title override list is full; configuration was not changed
|
|
|
|
/api/v1/games/icon:
|
|
get:
|
|
operationId: getGameIcon
|
|
summary: Stream a game icon or a cached 128x128 thumbnail
|
|
tags: [Games]
|
|
parameters:
|
|
- name: title_id
|
|
in: query
|
|
required: true
|
|
schema:
|
|
$ref: "#/components/schemas/TitleId"
|
|
- name: size
|
|
in: query
|
|
required: false
|
|
description: Generate and return the cached thumbnail variant
|
|
schema:
|
|
type: string
|
|
enum: [thumb]
|
|
responses:
|
|
"200":
|
|
description: PNG icon
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
image/png:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/settings:
|
|
options:
|
|
operationId: preflightGetSettings
|
|
summary: CORS preflight
|
|
tags: [Settings]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getSettings
|
|
summary: Read web-managed settings and recursive scan roots
|
|
tags: [Settings]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/EmptyRequest"
|
|
responses:
|
|
"200":
|
|
description: Current runtime settings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SettingsResponse"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/settings/update:
|
|
options:
|
|
operationId: preflightUpdateSettings
|
|
summary: CORS preflight
|
|
tags: [Settings]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: updateSettings
|
|
summary: Atomically update web-managed config.ini keys
|
|
description: Preserves unrelated keys and comments, then queues scanner-owned runtime reload.
|
|
tags: [Settings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SettingsUpdateRequest"
|
|
responses:
|
|
"200":
|
|
description: Settings saved and reload queued
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/debug-log:
|
|
options:
|
|
operationId: preflightGetDebugLog
|
|
summary: CORS preflight
|
|
tags: [Settings]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getDebugLog
|
|
summary: Read a bounded tail of debug.log
|
|
tags: [Settings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
max_bytes:
|
|
type: integer
|
|
minimum: 4096
|
|
maximum: 262144
|
|
default: 131072
|
|
responses:
|
|
"200":
|
|
description: Debug log tail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DebugLogResponse"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/kernel-log:
|
|
options:
|
|
operationId: preflightGetKernelLog
|
|
summary: CORS preflight
|
|
tags: [Settings]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getKernelLog
|
|
summary: Read recent events from the SDK log stream used by crash detection
|
|
description: Uses the sceKernelDebugGetSdkLogText snapshot shared with crash detection.
|
|
tags: [Settings]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
max_bytes:
|
|
type: integer
|
|
minimum: 4096
|
|
maximum: 262144
|
|
default: 131072
|
|
responses:
|
|
"200":
|
|
description: SDK kernel-log tail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/KernelLogResponse"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/games/move:
|
|
options:
|
|
operationId: preflightMoveGameSource
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: moveGameSource
|
|
summary: Move a game folder or backing image, including across filesystems
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/StorageDestinationRequest"
|
|
responses:
|
|
"202":
|
|
$ref: "#/components/responses/StorageJobAccepted"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"507":
|
|
$ref: "#/components/responses/InsufficientStorage"
|
|
|
|
/api/v1/games/copy:
|
|
options:
|
|
operationId: preflightCopyGameSource
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: copyGameSource
|
|
summary: Copy a game folder or backing image
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/StorageDestinationRequest"
|
|
responses:
|
|
"202":
|
|
$ref: "#/components/responses/StorageJobAccepted"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"507":
|
|
$ref: "#/components/responses/InsufficientStorage"
|
|
|
|
/api/v1/games/unpack:
|
|
options:
|
|
operationId: preflightUnpackGameImage
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: unpackGameImage
|
|
summary: Mount an image read-only and copy its game tree into a folder
|
|
tags: [Storage]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageUnpackRequest"
|
|
responses:
|
|
"202":
|
|
$ref: "#/components/responses/StorageJobAccepted"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
"507":
|
|
$ref: "#/components/responses/InsufficientStorage"
|
|
|
|
/api/v1/games/storage/status:
|
|
options:
|
|
operationId: preflightStorageJobStatus
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: getStorageJobStatus
|
|
summary: Get the current or last storage job
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/StorageJobStatusRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/StorageJobStatusSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/games/storage/cancel:
|
|
options:
|
|
operationId: preflightStorageJobCancel
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: cancelStorageJob
|
|
summary: Cancel an active storage job before its irreversible phase
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/StorageJobCancelRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/StorageJobStatusSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/games/delete:
|
|
options:
|
|
operationId: preflightDeleteGameSource
|
|
summary: CORS preflight
|
|
tags: [Storage]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: deleteGameSource
|
|
summary: Asynchronously delete a game folder or backing image
|
|
description: A confirmed request for a cached source that is already absent queues safe scanner reconciliation without starting a storage job or directly uninstalling the title. Absence may also mean disconnected storage. Permission and I/O errors remain failures.
|
|
tags: [Storage]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/StorageDeleteRequest"
|
|
responses:
|
|
"200":
|
|
description: Source already absent; library reconciliation queued
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MissingSourceResponse"
|
|
"202":
|
|
$ref: "#/components/responses/StorageJobAccepted"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/api/v1/games/mount:
|
|
options:
|
|
operationId: preflightMountGame
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: mountGame
|
|
summary: Mount a managed game
|
|
tags: [Games]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/MountRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/MountSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/games/unmount:
|
|
options:
|
|
operationId: preflightUnmountGame
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: unmountGame
|
|
summary: Unmount a managed game
|
|
tags: [Games]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/TitleRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/UnmountSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
/api/v1/games/uninstall:
|
|
options:
|
|
operationId: preflightUninstallGame
|
|
summary: CORS preflight
|
|
tags: [Games]
|
|
responses:
|
|
"204":
|
|
$ref: "#/components/responses/Preflight"
|
|
post:
|
|
operationId: uninstallGame
|
|
summary: Request game uninstallation
|
|
tags: [Games]
|
|
requestBody:
|
|
$ref: "#/components/requestBodies/TitleRequest"
|
|
responses:
|
|
"200":
|
|
$ref: "#/components/responses/UninstallSuccess"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Busy"
|
|
"411":
|
|
$ref: "#/components/responses/LengthRequired"
|
|
"413":
|
|
$ref: "#/components/responses/PayloadTooLarge"
|
|
"415":
|
|
$ref: "#/components/responses/UnsupportedMediaType"
|
|
"431":
|
|
$ref: "#/components/responses/HeadersTooLarge"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"501":
|
|
$ref: "#/components/responses/NotImplemented"
|
|
|
|
components:
|
|
requestBodies:
|
|
EmptyRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
example: {}
|
|
GamesListRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/GamesListRequest"
|
|
ScanRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ScanRequest"
|
|
TitleRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TitleRequest"
|
|
MountRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MountRequest"
|
|
ManualPathRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ManualPathRequest"
|
|
StorageDestinationRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageDestinationRequest"
|
|
StorageDeleteRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageDeleteRequest"
|
|
StorageJobStatusRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageJobStatusRequest"
|
|
StorageJobCancelRequest:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageJobCancelRequest"
|
|
|
|
headers:
|
|
AllowOrigin:
|
|
description: Browser origins allowed to access the API
|
|
schema:
|
|
type: string
|
|
const: "*"
|
|
AllowMethods:
|
|
description: Methods allowed by CORS preflight
|
|
schema:
|
|
type: string
|
|
const: GET, POST, OPTIONS
|
|
AllowHeaders:
|
|
description: Request headers allowed by CORS preflight
|
|
schema:
|
|
type: string
|
|
const: Content-Type
|
|
AllowPrivateNetwork:
|
|
description: Private Network Access permission
|
|
schema:
|
|
type: string
|
|
const: "true"
|
|
MaxAge:
|
|
description: Number of seconds for which the preflight may be cached
|
|
schema:
|
|
type: integer
|
|
const: 86400
|
|
|
|
responses:
|
|
Preflight:
|
|
description: CORS preflight accepted
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
Access-Control-Allow-Methods:
|
|
$ref: "#/components/headers/AllowMethods"
|
|
Access-Control-Allow-Headers:
|
|
$ref: "#/components/headers/AllowHeaders"
|
|
Access-Control-Allow-Private-Network:
|
|
$ref: "#/components/headers/AllowPrivateNetwork"
|
|
Access-Control-Max-Age:
|
|
$ref: "#/components/headers/MaxAge"
|
|
|
|
VersionSuccess:
|
|
description: API version and capabilities
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VersionResponse"
|
|
|
|
ImagesSuccess:
|
|
description: Complete image snapshot
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ImagesResponse"
|
|
|
|
StorageSpaceSuccess:
|
|
description: Capacity and free space for mounted storage filesystems
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageSpaceResponse"
|
|
|
|
GamesSuccess:
|
|
description: Complete game snapshot
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/GamesResponse"
|
|
|
|
GameInfoSuccess:
|
|
description: Detailed managed game metadata and physical source size
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/GameInfoResponse"
|
|
|
|
StorageJobAccepted:
|
|
description: Copy, move, delete or unpack job accepted for asynchronous execution
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageJobResponse"
|
|
|
|
StorageJobStatusSuccess:
|
|
description: Current or last copy, move, delete or unpack job status
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/StorageJobResponse"
|
|
|
|
ScanSuccess:
|
|
description: Full rescan queued
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ScanResponse"
|
|
|
|
ManualUpdateSuccess:
|
|
description: manual.lst update completed
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ManualUpdateResponse"
|
|
|
|
ManualListSuccess:
|
|
description: Parsed manual.lst source paths
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ManualListResponse"
|
|
|
|
MountSuccess:
|
|
description: Game mounted
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MountResponse"
|
|
|
|
UnmountSuccess:
|
|
description: Game unmounted
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UnmountResponse"
|
|
|
|
UninstallSuccess:
|
|
description: Game uninstallation was accepted by AppInstUtil
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UninstallResponse"
|
|
|
|
BadRequest:
|
|
description: Invalid HTTP request, JSON body or title ID
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
Forbidden:
|
|
description: The source or destination is not allowed
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
NotFound:
|
|
description: Managed title tracker was not found
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
Busy:
|
|
description: Runtime state does not currently permit the operation
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
example:
|
|
status: 16
|
|
error: Device busy
|
|
LengthRequired:
|
|
description: Content-Length is required
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
PayloadTooLarge:
|
|
description: JSON request body exceeds 4096 bytes
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
UnsupportedMediaType:
|
|
description: Content-Type is not application/json
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
HeadersTooLarge:
|
|
description: HTTP headers exceed 8192 bytes
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
InternalError:
|
|
description: Internal failure
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
NotImplemented:
|
|
description: Unsupported transfer encoding or runtime operation
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
|
|
InsufficientStorage:
|
|
description: The destination filesystem has insufficient free space
|
|
headers:
|
|
Access-Control-Allow-Origin:
|
|
$ref: "#/components/headers/AllowOrigin"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
|
|
schemas:
|
|
TitleId:
|
|
type: string
|
|
pattern: "^(CUSA|PPSA|LAPY|FAKE)[0-9]{5}$"
|
|
examples: [PPSA12345]
|
|
|
|
TitleRequest:
|
|
type: object
|
|
required: [title_id]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
|
|
GamesListRequest:
|
|
type: object
|
|
properties:
|
|
include_size:
|
|
type: boolean
|
|
default: false
|
|
description: Calculate every physical source size. Directory traversal can be slow.
|
|
|
|
ScanRequest:
|
|
type: object
|
|
properties:
|
|
reset_attempts:
|
|
type: boolean
|
|
default: false
|
|
description: Reset title install/mount and image-mount retry counters immediately before this requested full scan starts.
|
|
|
|
MountRequest:
|
|
type: object
|
|
required: [title_id]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
mode:
|
|
type: string
|
|
enum: [ro, rw, r/o, r/w]
|
|
description: Optional request-scoped mode for every image layer needed by this mount.
|
|
|
|
ManualPathRequest:
|
|
type: object
|
|
required: [path]
|
|
properties:
|
|
path:
|
|
type: string
|
|
pattern: "^/.+"
|
|
maxLength: 1023
|
|
|
|
StorageDestinationRequest:
|
|
type: object
|
|
required: [title_id, destination_dir]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
destination_dir:
|
|
type: string
|
|
pattern: "^/.+"
|
|
maxLength: 1023
|
|
description: Existing directory under a configured non-runtime scan root. The original source basename is preserved.
|
|
|
|
StorageDeleteRequest:
|
|
type: object
|
|
required: [title_id, confirm]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
confirm:
|
|
type: boolean
|
|
const: true
|
|
|
|
StorageUnpackRequest:
|
|
type: object
|
|
required: [title_id, destination_dir]
|
|
properties:
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
destination_dir:
|
|
type: string
|
|
pattern: "^/.+"
|
|
maxLength: 1023
|
|
description: Existing directory under a configured scan root. A TITLE_ID child directory is created.
|
|
delete_source:
|
|
type: boolean
|
|
default: false
|
|
description: Delete the backing image only after a complete copy and successful unmount.
|
|
|
|
StorageJobStatusRequest:
|
|
type: object
|
|
properties:
|
|
job_id:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
description: Omit to return the current or most recently completed job.
|
|
|
|
StorageJobCancelRequest:
|
|
type: object
|
|
required: [job_id]
|
|
properties:
|
|
job_id:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
|
|
SettingsUpdateRequest:
|
|
type: object
|
|
required: [debug, quiet_mode, update_emulators, allow_lan_access, fan_target_temperature, scan_paths]
|
|
properties:
|
|
debug:
|
|
type: boolean
|
|
quiet_mode:
|
|
type: boolean
|
|
update_emulators:
|
|
type: boolean
|
|
fakelib_default_mode:
|
|
type: string
|
|
enum: [full, emulators, disabled]
|
|
description: Mode inherited by games without an individual override. Initial default is full. Omission preserves the current value; changes apply on the next launch.
|
|
auto_update_ampr:
|
|
type: boolean
|
|
description: Download libSceAmpr.sprx updates from the configured GitHub release URL. Omission preserves the current value for compatibility with older web clients.
|
|
auto_remove_missing_games:
|
|
type: boolean
|
|
description: Remove app registrations whose source remains unavailable. Omission preserves the current value for compatibility with older web clients.
|
|
auto_remove_missing_delay_seconds:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 86400
|
|
description: Omission preserves the current value for compatibility with older web clients.
|
|
allow_lan_access:
|
|
type: boolean
|
|
description: Bind to 0.0.0.0 when true or 127.0.0.1 when false.
|
|
fan_target_temperature:
|
|
type: integer
|
|
description: Zero selects system control; otherwise 50 through 91 degrees Celsius.
|
|
oneOf:
|
|
- const: 0
|
|
- minimum: 50
|
|
maximum: 91
|
|
scan_paths:
|
|
type: array
|
|
description: Explicit custom roots only. An empty array restores compile-time defaults.
|
|
maxItems: 256
|
|
items:
|
|
type: string
|
|
pattern: "^/.+"
|
|
maxLength: 1023
|
|
|
|
SettingsResponse:
|
|
allOf:
|
|
- $ref: "#/components/schemas/SettingsUpdateRequest"
|
|
- type: object
|
|
required: [status, api_enabled, scan_path_count, fakelib_default_mode]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
api_enabled:
|
|
type: boolean
|
|
description: Whether the HTTP API is enabled in config.ini.
|
|
scan_path_count:
|
|
type: integer
|
|
minimum: 0
|
|
|
|
DebugLogResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, file_size, returned_bytes, truncated, content]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
file_size:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
returned_bytes:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 262144
|
|
truncated:
|
|
type: boolean
|
|
content:
|
|
type: string
|
|
|
|
KernelLogResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, total_bytes, returned_bytes, truncated, content]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
total_bytes:
|
|
type: integer
|
|
minimum: 0
|
|
returned_bytes:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 262144
|
|
truncated:
|
|
type: boolean
|
|
content:
|
|
type: string
|
|
|
|
VersionResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, api_version, shadowmount_version, capabilities]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
api_version:
|
|
type: integer
|
|
const: 1
|
|
shadowmount_version:
|
|
type: string
|
|
capabilities:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enum: [web_ui, storage_space, list_images, list_games, game_info, game_icon, mount_game, unmount_game, uninstall_game, move_game_source, copy_game_source, delete_game_source, unpack_game_image, storage_job_status, storage_job_cancel, list_manual_sources, add_manual_source, remove_manual_source, manage_settings, read_debug_log, read_kernel_log, rescan]
|
|
example: [web_ui, storage_space, list_images, list_games, game_info, game_icon, mount_game, unmount_game, uninstall_game, move_game_source, copy_game_source, delete_game_source, unpack_game_image, storage_job_status, storage_job_cancel, list_manual_sources, add_manual_source, remove_manual_source, manage_settings, read_debug_log, read_kernel_log, rescan]
|
|
|
|
StorageMount:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [source, mount_point, filesystem, total_bytes, free_bytes, available_bytes, used_bytes, read_only]
|
|
properties:
|
|
source:
|
|
type: string
|
|
mount_point:
|
|
type: string
|
|
pattern: "^/"
|
|
filesystem:
|
|
type: string
|
|
total_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
free_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
available_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
used_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
read_only:
|
|
type: boolean
|
|
|
|
StorageSpaceResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, count, destination_count, mounts, destinations]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
count:
|
|
type: integer
|
|
minimum: 0
|
|
destination_count:
|
|
type: integer
|
|
minimum: 0
|
|
mounts:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/StorageMount"
|
|
destinations:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/StorageDestination"
|
|
|
|
StorageDestination:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [path, source, mount_point, filesystem, total_bytes, free_bytes, available_bytes, used_bytes, read_only]
|
|
properties:
|
|
path:
|
|
type: string
|
|
pattern: "^/"
|
|
source:
|
|
type: string
|
|
mount_point:
|
|
type: string
|
|
pattern: "^/"
|
|
filesystem:
|
|
type: string
|
|
total_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
free_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
available_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
used_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
read_only:
|
|
type: boolean
|
|
|
|
Image:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- path
|
|
- mount_point
|
|
- size
|
|
- mtime_sec
|
|
- mtime_nsec
|
|
- unit_id
|
|
- backend
|
|
- complete
|
|
- source_available
|
|
- mapped
|
|
- mounted
|
|
properties:
|
|
path:
|
|
type: string
|
|
mount_point:
|
|
type: string
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
mtime_sec:
|
|
type: integer
|
|
format: int64
|
|
mtime_nsec:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 999999999
|
|
unit_id:
|
|
type: integer
|
|
minimum: -1
|
|
backend:
|
|
type: string
|
|
enum: [LVD, MD, UNKNOWN]
|
|
complete:
|
|
type: boolean
|
|
source_available:
|
|
type: boolean
|
|
mapped:
|
|
type: boolean
|
|
mounted:
|
|
type: boolean
|
|
|
|
ImagesResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, count, images]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
count:
|
|
type: integer
|
|
minimum: 0
|
|
images:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Image"
|
|
|
|
Game:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- path
|
|
- runtime_path
|
|
- source_type
|
|
- image_type
|
|
- platform
|
|
- title_id
|
|
- content_id
|
|
- title_name
|
|
- version
|
|
- last_access_time
|
|
- install_time
|
|
- icon_url
|
|
- app_db_size_bytes
|
|
- installed
|
|
- managed
|
|
- mounted
|
|
- image_backed
|
|
- source_available
|
|
- installed_pkg
|
|
- can_uninstall
|
|
- can_manage_source
|
|
- can_toggle_fakelib
|
|
- ignore_global_fakelib
|
|
- fakelib_mode
|
|
- fakelib_mode_override
|
|
- fakelib_default_mode
|
|
- fakelib_enabled
|
|
- fakelib_effective_enabled
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: Physical game folder, outer backing-image path or installed app.pkg.
|
|
runtime_path:
|
|
type: string
|
|
description: Runtime game directory used by ShadowMount; empty for installed PKGs.
|
|
source_type:
|
|
type: string
|
|
enum: [folder, image, pkg]
|
|
image_type:
|
|
type: string
|
|
enum: ["", ufs, exfatfs, pfs, pfsc, unknown]
|
|
platform:
|
|
type: string
|
|
enum: [ps4, ps5, unknown]
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
content_id:
|
|
type: string
|
|
title_name:
|
|
type: string
|
|
version:
|
|
type: string
|
|
description: AppInfoJson CONTENT_VERSION (PS5) or APP_VER (PS4), or an empty string when unavailable.
|
|
last_access_time:
|
|
type: string
|
|
description: AppInfoJson #_last_access_time value, falling back to app.db lastAccessTime, or an empty string.
|
|
install_time:
|
|
type: string
|
|
description: AppInfoJson #_install_time value, falling back to app.db installTime, or an empty string.
|
|
icon_url:
|
|
type: string
|
|
description: Relative URL of the icon endpoint, or an empty string.
|
|
app_db_size_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
installed:
|
|
type: boolean
|
|
managed:
|
|
type: boolean
|
|
mounted:
|
|
type: boolean
|
|
image_backed:
|
|
type: boolean
|
|
source_available:
|
|
type: boolean
|
|
installed_pkg:
|
|
type: boolean
|
|
can_uninstall:
|
|
type: boolean
|
|
can_manage_source:
|
|
type: boolean
|
|
description: False for installed PKGs; source mutations are forbidden.
|
|
can_toggle_fakelib:
|
|
type: boolean
|
|
description: True for PS5 games in PKGs, images and folders.
|
|
ignore_global_fakelib:
|
|
type: boolean
|
|
description: Whether this title excludes the global fakelib overlay; independent of its fakelib mode.
|
|
fakelib_mode:
|
|
type: string
|
|
enum: [full, emulators, disabled]
|
|
description: Resolved title mode after inheritance.
|
|
fakelib_mode_override:
|
|
type: string
|
|
enum: [default, full, emulators, disabled]
|
|
description: Explicit title mode or default to inherit fakelib_default_mode.
|
|
fakelib_default_mode:
|
|
type: string
|
|
enum: [full, emulators, disabled]
|
|
description: Current mode inherited by titles without an override.
|
|
fakelib_enabled:
|
|
type: boolean
|
|
description: Whether the resolved title mode enables fakelib; changes apply on the next launch.
|
|
fakelib_effective_enabled:
|
|
type: boolean
|
|
description: Per-title policy combined with the global backport_fakelib switch.
|
|
size_status:
|
|
type: integer
|
|
minimum: 0
|
|
description: errno-style result of optional physical size calculation.
|
|
size_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: Image file size, sum of folder files or installed PKG size from app.db (package file size when unavailable).
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
|
|
GamesResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, count, size_included, games]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
count:
|
|
type: integer
|
|
minimum: 0
|
|
size_included:
|
|
type: boolean
|
|
games:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Game"
|
|
|
|
GameInfoResponse:
|
|
allOf:
|
|
- $ref: "#/components/schemas/Game"
|
|
- type: object
|
|
required: [status, size_status]
|
|
|
|
StorageJobResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, job_id, operation, state, active, cancellable, cancel_requested, title_id, source_type, source, runtime_source, destination, delete_source, total_bytes, processed_bytes, total_files, processed_files, progress_percent, speed_bytes_per_second, elapsed_ms, affected_titles, result_status, result_error, result_error_reason, scan_queued]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
job_id:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
operation:
|
|
type: string
|
|
enum: ["", move, copy, delete, unpack]
|
|
state:
|
|
type: string
|
|
enum: [idle, preparing, measuring, transferring, deleting, finalizing, completed, failed, cancelled]
|
|
active:
|
|
type: boolean
|
|
cancellable:
|
|
type: boolean
|
|
cancel_requested:
|
|
type: boolean
|
|
title_id:
|
|
type: string
|
|
source_type:
|
|
type: string
|
|
enum: ["", folder, image]
|
|
source:
|
|
type: string
|
|
runtime_source:
|
|
type: string
|
|
destination:
|
|
type: string
|
|
description: Empty for delete jobs.
|
|
delete_source:
|
|
type: boolean
|
|
description: True only for unpack jobs that will remove the image after successful extraction.
|
|
total_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
processed_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
total_files:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
processed_files:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
progress_percent:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 100
|
|
speed_bytes_per_second:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: Average processed-byte rate since transfer or deletion began.
|
|
elapsed_ms:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
affected_titles:
|
|
type: integer
|
|
minimum: 0
|
|
result_status:
|
|
type: integer
|
|
minimum: 0
|
|
result_error:
|
|
type: string
|
|
description: English error text; localized clients should use result_error_reason when available.
|
|
result_error_reason:
|
|
$ref: "#/components/schemas/OperationErrorReason"
|
|
scan_queued:
|
|
type: boolean
|
|
|
|
ScanResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, queued, reset_attempts, scan_queued, scan_deferred, scan_deferred_reason]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
queued:
|
|
type: boolean
|
|
const: true
|
|
reset_attempts:
|
|
type: boolean
|
|
scan_queued:
|
|
type: boolean
|
|
const: true
|
|
scan_deferred:
|
|
type: boolean
|
|
description: Whether game runtime or rest mode prevents scanning at response time; queue acceptance does not mean scan completion.
|
|
scan_deferred_reason:
|
|
type: string
|
|
enum: ["", game_active, runtime_prepared, rest_mode]
|
|
|
|
ManualUpdateResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, path, present, changed]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
path:
|
|
type: string
|
|
present:
|
|
type: boolean
|
|
changed:
|
|
type: boolean
|
|
|
|
ManualListResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, count, paths]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
count:
|
|
type: integer
|
|
minimum: 0
|
|
paths:
|
|
type: array
|
|
items:
|
|
type: string
|
|
pattern: "^/.+"
|
|
|
|
MountResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, title_id, mounted, mode]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
mounted:
|
|
type: boolean
|
|
const: true
|
|
mode:
|
|
type: string
|
|
enum: [default, ro, rw]
|
|
|
|
UnmountResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, title_id, mounted]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
mounted:
|
|
type: boolean
|
|
const: false
|
|
|
|
UninstallResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, title_id, uninstall_requested, scan_queued, scan_deferred, scan_deferred_reason]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
uninstall_requested:
|
|
type: boolean
|
|
const: true
|
|
scan_queued:
|
|
type: boolean
|
|
description: Full synchronization was queued because the known source was absent before uninstall; retained sources are not immediately rediscovered.
|
|
scan_deferred:
|
|
type: boolean
|
|
scan_deferred_reason:
|
|
type: string
|
|
enum: ["", game_active, runtime_prepared, rest_mode]
|
|
|
|
MissingSourceResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, title_id, source_missing, scan_queued, scan_deferred, scan_deferred_reason]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
const: 0
|
|
title_id:
|
|
$ref: "#/components/schemas/TitleId"
|
|
source_missing:
|
|
type: boolean
|
|
const: true
|
|
scan_queued:
|
|
type: boolean
|
|
const: true
|
|
scan_deferred:
|
|
type: boolean
|
|
scan_deferred_reason:
|
|
type: string
|
|
enum: ["", game_active, runtime_prepared, rest_mode]
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, error]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
minimum: 1
|
|
description: Positive errno value
|
|
error:
|
|
type: string
|
|
error_reason:
|
|
$ref: "#/components/schemas/OperationErrorReason"
|
|
|
|
OperationErrorReason:
|
|
type: string
|
|
description: Stable reason code for localized operation errors; empty for generic errno failures.
|
|
enum: ["", rest_mode, game_active, install_pending, runtime_prepared, scanner_busy, runtime_busy, title_unmount_busy, image_unmount_busy, unpack_mounted, storage_busy, storage_unavailable]
|