openapi: 3.0.3 info: title: XC_VM System API version: "1.0.0" description: | Internal **System API** for the XC_VM panel — stream and VOD control, system statistics, directory browsing, log viewing, process management and EPG/nginx reloading. - **Controller:** `src/Public/Controllers/Api/InternalApiController.php` - **HTTP entry-point:** `/api.php` (routed by nginx to `Public/index.php` with `XC_API=internal`) - **Authentication:** `password` query parameter matching the `live_streaming_pass` configuration - **IP allow-list:** the requesting IP must be in `ServerRepository::getAllowedIPs()` **Request pattern:** ``` {protocol}://{host}:{port}/api.php?password=&action= ``` ## Error codes | Code | Description | | --- | --- | | `INVALID_API_PASSWORD` | Invalid API password | | `API_IP_NOT_ALLOWED` | IP address not allowed | The default response for an unrecognized action is `{ "result": false }`. servers: - url: '{protocol}://{host}:{port}' description: XC_VM server variables: protocol: default: http enum: [http, https] host: default: your-server.com description: Server IP or domain port: default: '80' description: HTTP port security: - ApiPassword: [] tags: - name: Streams description: Live stream and RTMP control - name: VOD description: Video-on-Demand control - name: Processes description: Process lifecycle management - name: System description: System statistics and maintenance - name: Files description: File download and directory browsing - name: Connections description: Active connection control paths: /api.php?action=view_log: get: tags: [Streams] summary: View stream log description: Returns the error log for a given stream or VOD. Checks `STREAMS_PATH` first, then falls back to `VOD_PATH`. parameters: - name: stream_id in: query required: true schema: { type: integer } description: ID of the stream to retrieve the log for responses: '200': description: Plain-text contents of `.errors` (empty if no log exists) content: text/plain: schema: { type: string } /api.php?action=streams_ramdisk: get: tags: [Streams] summary: Streams ramdisk usage description: Returns per-stream file sizes from the streams ramdisk directory. Has a 30-second time limit. responses: '200': description: Per-stream byte sizes content: application/json: schema: type: object properties: result: { type: boolean } streams: type: object additionalProperties: { type: integer } example: result: true streams: { "123": 4096000, "456": 2048000 } /api.php?action=stream: get: tags: [Streams] summary: Start / stop live streams description: Starts or stops live streams. When starting, a 50 ms delay is applied between each stream. parameters: - name: stream_ids in: query required: true description: List of stream IDs schema: { type: array, items: { type: integer } } - name: function in: query required: true description: Action to perform schema: { type: string, enum: [start, stop] } responses: '200': description: Result content: application/json: schema: { $ref: '#/components/schemas/ResultResponse' } /api.php?action=force_stream: get: tags: [Streams] summary: Force stream source description: Forces a stream to use a specific source by writing a force signal file. parameters: - name: stream_id in: query required: true schema: { type: integer } description: ID of the stream to force - name: force_id in: query required: true schema: { type: integer } description: ID of the source to force the stream to responses: '200': description: Result content: application/json: schema: { $ref: '#/components/schemas/ResultResponse' } /api.php?action=get_archive_files: get: tags: [Streams] summary: Get archive files description: Returns a list of `.ts` archive segment files for a given stream. parameters: - name: stream_id in: query required: true schema: { type: integer } responses: '200': description: Archive segment paths content: application/json: schema: type: object properties: result: { type: boolean } data: { type: array, items: { type: string } } example: result: true data: ["/path/to/archive/123/segment001.ts", "/path/to/archive/123/segment002.ts"] /api.php?action=probe: get: tags: [Streams] summary: Probe stream description: Probes a stream URL using FFprobe to retrieve media information. parameters: - name: url in: query required: true schema: { type: string } description: URL of the stream to probe - name: user_agent in: query required: false schema: { type: string } description: Custom User-Agent header - name: http_proxy in: query required: false schema: { type: string } description: HTTP proxy URL - name: cookies in: query required: false schema: { type: string } description: Cookie string to send with the request - name: headers in: query required: false schema: { type: string } description: Additional HTTP headers responses: '200': description: Media info content: application/json: schema: type: object properties: result: { type: boolean } data: { type: object } /api.php?action=rtmp_stats: get: tags: [Streams] summary: RTMP stats description: Returns local RTMP server statistics. responses: '200': description: RTMP statistics (XML/JSON depending on server) /api.php?action=rtmp_kill: get: tags: [Streams] summary: RTMP kill description: Drops an RTMP publisher connection by name via the nginx RTMP control interface. parameters: - name: name in: query required: true schema: { type: string } description: RTMP stream name to drop responses: '200': description: Result /api.php?action=vod: get: tags: [VOD] summary: Start / stop VOD streams description: Starts or stops Video-on-Demand streams. When starting, the stream is first stopped then either force-started or queued depending on `force`. parameters: - name: stream_ids in: query required: true description: List of stream IDs schema: { type: array, items: { type: integer } } - name: function in: query required: true description: Action to perform schema: { type: string, enum: [start, stop] } - name: force in: query required: false description: If true, starts immediately instead of queuing (start only) schema: { type: boolean } responses: '200': description: Result content: application/json: schema: { $ref: '#/components/schemas/ResultResponse' } /api.php?action=fpm_status: get: tags: [Processes] summary: FPM status description: Returns the PHP-FPM status page from the local server's HTTP broadcast port. responses: '200': description: PHP-FPM status page /api.php?action=kill_pid: get: tags: [Processes] summary: Kill process by PID description: Terminates a process by sending SIGKILL (signal 9) to the specified PID. parameters: - name: pid in: query required: true schema: { type: integer } description: Process ID to terminate responses: '200': description: Result content: application/json: schema: { $ref: '#/components/schemas/ResultResponse' } /api.php?action=pidsAreRunning: get: tags: [Processes] summary: Process lifecycle check description: Checks whether specified PIDs are currently running and match the expected program binary. parameters: - name: pids in: query required: true description: List of PIDs to verify schema: { type: array, items: { type: integer } } - name: program in: query required: true schema: { type: string } description: Expected program name responses: '200': description: Per-PID running state content: application/json: schema: type: object additionalProperties: { type: boolean } example: { "1234": true, "5678": false } /api.php?action=get_pids: get: tags: [Processes] summary: Get process list description: Returns a list of all running processes with details (from `ps -e`). responses: '200': description: Output lines from `ps -e` content: application/json: schema: { type: array, items: { type: string } } /api.php?action=kill_watch: get: tags: [Processes] summary: Kill watch processes description: Kills all running watch module processes (main PID and worker PIDs). responses: '200': description: Result /api.php?action=kill_plex: get: tags: [Processes] summary: Kill Plex processes description: Kills all running Plex module processes (main PID and worker PIDs). responses: '200': description: Result /api.php?action=stats: get: tags: [System] summary: System statistics description: Retrieves system statistics via `SystemInfo::getStats()`. responses: '200': description: System stats content: application/json: schema: { type: object } example: cpu: 8.32 cpu_cores: 56 cpu_avg: 8.86 cpu_name: "Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz" /api.php?action=reload_epg: get: tags: [System] summary: Reload EPG description: Triggers a background EPG reload by running `console.php cron:epg` asynchronously. responses: '200': description: Accepted (runs in background) /api.php?action=restore_images: get: tags: [System] summary: Restore images description: Triggers a background image restoration by running `console.php tools images` asynchronously. responses: '200': description: Accepted (runs in background) /api.php?action=reload_nginx: get: tags: [System] summary: Reload nginx description: Reloads both the RTMP nginx and the main nginx processes by sending them a reload signal. responses: '200': description: Result /api.php?action=free_temp: get: tags: [System] summary: Clear temporary folder description: Deletes all files in the `tmp/` directory and runs the cache cron job. responses: '200': description: Result /api.php?action=free_streams: get: tags: [System] summary: Clear streams folder description: Removes all files from the `content/streams/` directory. responses: '200': description: Result /api.php?action=get_free_space: get: tags: [System] summary: Get free disk space description: Returns disk usage information from `df -h`. responses: '200': description: Output lines from `df -h` content: application/json: schema: { type: array, items: { type: string } } /api.php?action=get_certificate_info: get: tags: [System] summary: Get certificate info description: Returns SSL/TLS certificate information via `DiagnosticsService::getCertificateInfo()`. responses: '200': description: Certificate info /api.php?action=watch_force: get: tags: [System] summary: Force watch cron description: Triggers a background watch cron job for a specific item. parameters: - name: id in: query required: true schema: { type: integer } description: Watch item ID responses: '200': description: Accepted (runs in background) /api.php?action=plex_force: get: tags: [System] summary: Force Plex cron description: Triggers a background Plex cron job for a specific item. parameters: - name: id in: query required: true schema: { type: integer } description: Plex item ID responses: '200': description: Accepted (runs in background) /api.php?action=getFile: get: tags: [Files] summary: Get file description: | Downloads the specified file. Supports HTTP range requests for partial content. Only allows files with specific extensions: `log`, `tar.gz`, `gz`, `zip`, `m3u8`, `mp4`, `mkv`, `avi`, `mpg`, `flv`, `3gp`, `m4v`, `wmv`, `mov`, `ts`, `srt`, `sub`, `sbv`, `jpg`, `png`, `bmp`, `jpeg`, `gif`, `tif`. parameters: - name: filename in: query required: true schema: { type: string } description: Path to the file responses: '200': description: File contents content: application/octet-stream: schema: { type: string, format: binary } '206': description: Partial content (when a `Range` header is supplied) /api.php?action=scandir_recursive: get: tags: [Files] summary: Recursive directory scan description: Recursively scans a directory using `find`, optionally filtering by file extension. Has a 30-second time limit. parameters: - name: dir in: query required: true schema: { type: string } description: URL-encoded path to the directory - name: allowed in: query required: false schema: { type: string } description: URL-encoded pipe-separated list of allowed extensions (e.g. `mp4|mkv`) responses: '200': description: File paths content: application/json: schema: { type: array, items: { type: string } } /api.php?action=scandir: get: tags: [Files] summary: Directory listing description: Lists files and subdirectories in a given directory, optionally filtering files by extension. Has a 30-second time limit. parameters: - name: dir in: query required: true schema: { type: string } description: URL-encoded path to the directory - name: allowed in: query required: false schema: { type: string } description: URL-encoded pipe-separated list of allowed file extensions (e.g. `mp4|mkv`) responses: '200': description: Directory contents content: application/json: schema: type: object properties: result: { type: boolean } dirs: { type: array, items: { type: string } } files: { type: array, items: { type: string } } example: result: true dirs: ["subdir1", "subdir2"] files: ["video.mp4", "movie.mkv"] /api.php?action=closeConnection: get: tags: [Connections] summary: Close connection description: Closes an active connection by its activity ID. parameters: - name: activity_id in: query required: true schema: { type: integer } description: Activity ID of the connection responses: '200': description: Result /api.php?action=redirect_connection: get: tags: [Connections] summary: Redirect connection description: Redirects a connection by writing a signal file identified by UUID. parameters: - name: uuid in: query required: true schema: { type: string } description: UUID identifying the connection - name: stream_id in: query required: true schema: { type: integer } description: Target stream ID responses: '200': description: Result /api.php?action=signal_send: get: tags: [Connections] summary: Send signal description: Sends a signal message to a connection identified by UUID. parameters: - name: message in: query required: true schema: { type: string } description: Signal message or command - name: uuid in: query required: true schema: { type: string } description: UUID identifying the connection responses: '200': description: Result components: securitySchemes: ApiPassword: type: apiKey in: query name: password description: API password matching the `live_streaming_pass` configuration. schemas: ResultResponse: type: object properties: result: { type: boolean } example: result: true