{ "openapi": "3.1.0", "info": { "title": "Strom API", "description": "REST and WebSocket API for the Strom pipeline engine", "contact": { "name": "Per Enstedt", "email": "per.enstedt@eyevinn.se" }, "license": { "name": "MIT OR Apache-2.0" }, "version": "0.4.13-dev4" }, "paths": { "/api/auth/status": { "get": { "tags": [ "auth" ], "summary": "Get authentication status", "operationId": "auth_status_handler", "responses": { "200": { "description": "Current authentication status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthStatusResponse" } } } } } } }, "/api/blocks": { "get": { "tags": [ "blocks" ], "summary": "List all block definitions (built-in + user-defined).", "operationId": "list_blocks", "responses": { "200": { "description": "List all blocks", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockListResponse" } } } } } }, "post": { "tags": [ "blocks" ], "summary": "Create a new user-defined block.", "operationId": "create_block", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateBlockRequest" } } }, "required": true }, "responses": { "201": { "description": "Block created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/blocks/categories": { "get": { "tags": [ "blocks" ], "summary": "Get all block categories.", "operationId": "get_categories", "responses": { "200": { "description": "List of block categories", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockCategoriesResponse" } } } } } } }, "/api/blocks/{id}": { "get": { "tags": [ "blocks" ], "summary": "Get a specific block definition by ID.", "operationId": "get_block", "parameters": [ { "name": "id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Block found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockResponse" } } } }, "404": { "description": "Block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "put": { "tags": [ "blocks" ], "summary": "Update an existing user-defined block.", "operationId": "update_block", "parameters": [ { "name": "id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockDefinition" } } }, "required": true }, "responses": { "200": { "description": "Block updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BlockResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "blocks" ], "summary": "Delete a user-defined block.", "operationId": "delete_block", "parameters": [ { "name": "id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Block deleted" }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/client-log": { "post": { "tags": [ "whip" ], "summary": "Receive client-side log messages from any browser page (WHIP, WHEP, clocks, …).", "description": "Accepts a JSON array of log entries and writes them to the server log\nprefixed with `[CLIENT]` so they can be correlated with server-side events.", "operationId": "client_log", "responses": { "204": { "description": "Log entries accepted" } } } }, "/api/discovery/announced": { "get": { "tags": [ "discovery" ], "summary": "List streams being announced by this Strom instance.", "operationId": "list_announced", "responses": { "200": { "description": "List of announced streams", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AnnouncedStreamResponse" } } } } } } } }, "/api/discovery/devices": { "get": { "tags": [ "discovery" ], "summary": "List all discovered devices.", "operationId": "list_devices", "parameters": [ { "name": "category", "in": "query", "description": "Filter by category", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of discovered devices", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DeviceResponse" } } } } } } } }, "/api/discovery/devices/refresh": { "post": { "tags": [ "discovery" ], "summary": "Refresh discovered devices (trigger re-scan).", "operationId": "refresh_devices", "responses": { "200": { "description": "Devices refreshed" } } } }, "/api/discovery/devices/status": { "get": { "tags": [ "discovery" ], "summary": "Get device discovery status.", "operationId": "device_status", "responses": { "200": { "description": "Device discovery status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeviceDiscoveryStatus" } } } } } } }, "/api/discovery/devices/{id}": { "get": { "tags": [ "discovery" ], "summary": "Get a specific device by ID.", "operationId": "get_device", "parameters": [ { "name": "id", "in": "path", "description": "Device ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Device details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeviceResponse" } } } }, "404": { "description": "Device not found" } } } }, "/api/discovery/ndi/refresh": { "post": { "tags": [ "discovery" ], "summary": "Refresh NDI sources (trigger re-scan).", "operationId": "refresh_ndi_sources", "responses": { "200": { "description": "NDI sources refreshed" } } } }, "/api/discovery/ndi/sources": { "get": { "tags": [ "discovery" ], "summary": "List all discovered NDI sources.", "operationId": "list_ndi_sources", "responses": { "200": { "description": "List of discovered NDI sources", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DeviceResponse" } } } } } } } }, "/api/discovery/ndi/status": { "get": { "tags": [ "discovery" ], "summary": "Get NDI discovery status.", "operationId": "ndi_status", "responses": { "200": { "description": "NDI discovery status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NdiDiscoveryStatus" } } } } } } }, "/api/discovery/streams": { "get": { "tags": [ "discovery" ], "summary": "List all discovered AES67 streams.", "operationId": "list_streams", "responses": { "200": { "description": "List of discovered streams", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DiscoveredStreamResponse" } } } } } } } }, "/api/discovery/streams/{id}": { "get": { "tags": [ "discovery" ], "summary": "Get a specific discovered stream by ID.", "operationId": "get_stream", "parameters": [ { "name": "id", "in": "path", "description": "Stream ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Stream details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DiscoveredStreamResponse" } } } }, "404": { "description": "Stream not found" } } } }, "/api/discovery/streams/{id}/sdp": { "get": { "tags": [ "discovery" ], "summary": "Get the raw SDP for a discovered stream.", "operationId": "get_stream_sdp", "parameters": [ { "name": "id", "in": "path", "description": "Stream ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SDP content", "content": { "application/sdp": { "schema": { "type": "string" } } } }, "404": { "description": "Stream not found" } } } }, "/api/elements": { "get": { "tags": [ "elements" ], "summary": "List all available GStreamer elements.", "operationId": "list_elements", "responses": { "200": { "description": "List of available GStreamer elements", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ElementListResponse" } } } } } } }, "/api/elements/{name}": { "get": { "tags": [ "elements" ], "summary": "Get detailed information about a specific element type.\nThis endpoint triggers lazy loading of element properties.\nProperties are introspected on-demand and cached for future requests.", "operationId": "get_element_info", "parameters": [ { "name": "name", "in": "path", "description": "Element type name (e.g., 'videotestsrc')", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Element information with properties", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ElementInfoResponse" } } } }, "404": { "description": "Element not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/elements/{name}/pads": { "get": { "tags": [ "elements" ], "summary": "Get pad properties for a specific element type.\nThis endpoint introspects pad properties on-demand for better safety.", "operationId": "get_element_pad_properties", "parameters": [ { "name": "name", "in": "path", "description": "Element type name (e.g., 'audiomixer')", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Element information with pad properties", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ElementInfoResponse" } } } }, "404": { "description": "Element not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows": { "get": { "tags": [ "flows" ], "summary": "List all flows.", "operationId": "list_flows", "responses": { "200": { "description": "List all flows", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowListResponse" } } } } } }, "post": { "tags": [ "flows" ], "summary": "Create a new flow.", "operationId": "create_flow", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Flow" } } }, "required": true }, "responses": { "201": { "description": "Flow created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/animate": { "post": { "tags": [ "flows" ], "summary": "Animate a single input's position and/or size.", "description": "Smoothly animates the specified input from its current position/size\nto the target values over the specified duration.", "operationId": "animate_input", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID (e.g., 'comp_1')", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnimateInputRequest" } } }, "required": true }, "responses": { "200": { "description": "Animation started successfully" }, "400": { "description": "Invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/background": { "post": { "tags": [ "flows" ], "summary": "Set or clear the background source on a vision mixer block.", "operationId": "set_background", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetBackgroundRequest" } } }, "required": true }, "responses": { "200": { "description": "Background source set/cleared", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetBackgroundResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/dsk": { "post": { "tags": [ "flows" ], "summary": "Toggle a DSK (Downstream Keyer) layer on a vision mixer block.", "operationId": "toggle_dsk", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DskToggleRequest" } } }, "required": true }, "responses": { "200": { "description": "DSK toggled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DskToggleResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/ftb": { "post": { "tags": [ "flows" ], "summary": "Toggle Fade to Black on a vision mixer block.", "operationId": "fade_to_black", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FadeToBlackRequest" } } }, "required": true }, "responses": { "200": { "description": "FTB toggled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FadeToBlackResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/loudness/reset": { "post": { "tags": [ "flows" ], "summary": "Reset accumulated loudness measurements on an EBU R128 meter block.", "operationId": "reset_loudness", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Loudness measurements reset" }, "400": { "description": "Failed to reset", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/multiview-endpoint": { "get": { "tags": [ "vision-mixer" ], "summary": "Get the multiview WHEP endpoint for a vision mixer block.\nGET /api/flows/{flow_id}/blocks/{block_id}/multiview-endpoint", "operationId": "get_multiview_endpoint", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Multiview endpoint info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MultiviewEndpointResponse" } } } }, "404": { "description": "Flow or block not found" } } } }, "/api/flows/{flow_id}/blocks/{block_id}/overlay-alpha": { "post": { "tags": [ "flows" ], "summary": "Set the multiview overlay alpha on a vision mixer block.", "operationId": "set_overlay_alpha", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OverlayAlphaRequest" } } }, "required": true }, "responses": { "200": { "description": "Overlay alpha set", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OverlayAlphaResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/player/control": { "post": { "tags": [ "media_player" ], "summary": "Control the media player (play, pause, stop, next, previous).", "operationId": "control_player", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlayerControlRequest" } } }, "required": true }, "responses": { "200": { "description": "Action performed" }, "400": { "description": "Action failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Player not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/player/goto": { "post": { "tags": [ "media_player" ], "summary": "Go to a specific file in the playlist.", "operationId": "goto_file", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GotoRequest" } } }, "required": true }, "responses": { "200": { "description": "Goto performed" }, "400": { "description": "Goto failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Player not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/player/playlist": { "post": { "tags": [ "media_player" ], "summary": "Set the playlist for a media player block.", "operationId": "set_playlist", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetPlaylistRequest" } } }, "required": true }, "responses": { "200": { "description": "Playlist set" }, "404": { "description": "Flow or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/player/seek": { "post": { "tags": [ "media_player" ], "summary": "Seek to a position in the current file.", "operationId": "seek_player", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SeekRequest" } } }, "required": true }, "responses": { "200": { "description": "Seek performed" }, "400": { "description": "Seek failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Player not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/player/state": { "get": { "tags": [ "media_player" ], "summary": "Get the current state of a media player block.", "operationId": "get_player_state", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Player state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlayerStateResponse" } } } }, "404": { "description": "Player not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/preview": { "post": { "tags": [ "flows" ], "summary": "Select a preview source on a vision mixer block.", "operationId": "select_preview", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Vision mixer block instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SelectPreviewRequest" } } }, "required": true }, "responses": { "200": { "description": "Preview source selected", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SelectPreviewResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/recorder/split": { "post": { "tags": [ "flows" ], "summary": "Force an immediate file split on a recorder block.", "operationId": "recorder_split_now", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "File split triggered" }, "400": { "description": "Failed to trigger split (e.g. ts_passthrough mode)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/sdp": { "get": { "tags": [ "flows" ], "summary": "Generate SDP for a specific block in a flow.", "description": "Returns the SDP (Session Description Protocol) data for AES67 output blocks.\nThis SDP can be used by receivers to connect to the audio stream.", "operationId": "get_block_sdp", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SDP generated successfully", "content": { "application/sdp": {} } }, "400": { "description": "Block type does not support SDP", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/blocks/{block_id}/transition": { "post": { "tags": [ "flows" ], "summary": "Trigger a scene transition on a compositor block.", "description": "Animates the transition between two inputs on a compositor/mixer block.\nSupported transition types:\n- `cut`: Instant switch (no animation)\n- `fade`: Cross-fade via alpha blending\n- `slide_left`: New input slides in from the right\n- `slide_right`: New input slides in from the left\n- `slide_up`: New input slides in from the bottom\n- `slide_down`: New input slides in from the top", "operationId": "trigger_transition", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID (e.g., 'comp_1')", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TriggerTransitionRequest" } } }, "required": true }, "responses": { "200": { "description": "Transition triggered successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TransitionResponse" } } } }, "400": { "description": "Invalid transition parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/elements/{element_id}/pads/{pad_name}/properties": { "get": { "tags": [ "flows" ], "summary": "Get current property values from a pad in a running element.", "description": "Returns all readable properties and their current values from a specific pad\non an element in a running pipeline. This is useful for elements like compositor\nwhere you need to control individual sink pad properties (alpha, xpos, ypos, zorder).", "operationId": "get_pad_properties", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "element_id", "in": "path", "description": "Element instance ID", "required": true, "schema": { "type": "string" } }, { "name": "pad_name", "in": "path", "description": "Pad name (e.g., sink_0, sink_1)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Pad properties retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PadPropertiesResponse" } } } }, "404": { "description": "Flow not running, element not found, or pad not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "flows" ], "summary": "Update a property on a pad in a running pipeline element.", "description": "Allows live modification of pad properties while the pipeline is running.\nThis is essential for elements like compositor, glvideomixer, and audiomixer\nwhere you need to control individual input pad properties.\nCommon pad properties include:\n- alpha: Opacity/transparency (0.0 to 1.0)\n- xpos, ypos: Position in pixels\n- width, height: Size in pixels\n- zorder: Layer order (higher values are on top)", "operationId": "update_pad_property", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "element_id", "in": "path", "description": "Element instance ID", "required": true, "schema": { "type": "string" } }, { "name": "pad_name", "in": "path", "description": "Pad name (e.g., sink_0, sink_1)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePadPropertyRequest" } } }, "required": true }, "responses": { "200": { "description": "Pad property updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PadPropertiesResponse" } } } }, "400": { "description": "Property cannot be changed in current state or invalid value", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running, element not found, or pad not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{flow_id}/elements/{element_id}/properties": { "get": { "tags": [ "flows" ], "summary": "Get current property values from a running element.", "description": "Returns all readable properties and their current values from an element\nin a running pipeline. The pipeline must be started for this endpoint to work.", "operationId": "get_element_properties", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "element_id", "in": "path", "description": "Element instance ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Properties retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ElementPropertiesResponse" } } } }, "404": { "description": "Flow not running or element not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "flows" ], "summary": "Update a property on a running pipeline element.", "description": "Allows live modification of element properties while the pipeline is running.\nOnly properties marked as mutable in the current pipeline state can be updated.\nThe property mutability flags (mutable_in_playing, etc.) can be checked via\nthe element info endpoint.", "operationId": "update_element_property", "parameters": [ { "name": "flow_id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "element_id", "in": "path", "description": "Element instance ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePropertyRequest" } } }, "required": true }, "responses": { "200": { "description": "Property updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ElementPropertiesResponse" } } } }, "400": { "description": "Property cannot be changed in current state or invalid value", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not running or element not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}": { "get": { "tags": [ "flows" ], "summary": "Get a specific flow by ID.", "operationId": "get_flow", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Flow found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "put": { "tags": [ "flows" ], "summary": "Update an existing flow (PUT alias).", "description": "This is an alias for the POST update endpoint, provided for RESTful API conventions.", "operationId": "update_flow_put", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Flow" } } }, "required": true }, "responses": { "200": { "description": "Flow updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "flows" ], "summary": "Update an existing flow.", "operationId": "update_flow", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Flow" } } }, "required": true }, "responses": { "200": { "description": "Flow updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "flows" ], "summary": "Delete a flow.", "operationId": "delete_flow", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Flow deleted" }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/blocks/{block_id}/thumbnail": { "get": { "tags": [ "flows" ], "summary": "Get a thumbnail image from a block's video tap.", "description": "Works with any block that exposes thumbnail tee elements, including\n`builtin.thumbnail` (index 0) and compositor blocks (one per input).\nThe first request activates the thumbnail branch; subsequent requests\nare served from cache.", "operationId": "get_block_thumbnail", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } }, { "name": "block_id", "in": "path", "description": "Block instance ID (e.g., 'b0')", "required": true, "schema": { "type": "string" } }, { "name": "index", "in": "query", "description": "Tap index (default 0, e.g. compositor input index)", "required": false, "schema": { "type": "integer", "minimum": 0 } } ], "responses": { "200": { "description": "JPEG thumbnail image", "content": { "image/jpeg": {} } }, "404": { "description": "Flow not running or block not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "504": { "description": "Frame capture timed out (retry shortly)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/debug": { "get": { "tags": [ "flows" ], "summary": "Get debug information for a running flow.", "description": "Returns pipeline timing information including base_time, clock_time, and\nrunning_time. This is useful for debugging AES67/RFC 7273 RTP timestamp\nissues where precise clock synchronization is critical.", "operationId": "get_flow_debug_info", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Debug information retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowDebugInfo" } } } }, "404": { "description": "Flow not running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/debug-graph": { "get": { "tags": [ "flows" ], "summary": "Generate a debug DOT/SVG graph for a flow's pipeline.", "description": "This endpoint generates a GraphViz DOT graph of the GStreamer pipeline\nand converts it to SVG format. The SVG is returned directly and can be\nviewed in a browser.", "operationId": "debug_graph", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SVG debug graph of the pipeline", "content": { "image/svg+xml": {} } }, "404": { "description": "Flow not found or not running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to generate graph (Graphviz not installed)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/dynamic-pads": { "get": { "tags": [ "flows" ], "summary": "Get runtime dynamic pads for a flow.", "description": "Returns information about dynamic pads (like decodebin outputs) that were\ncreated at runtime and auto-linked to tees. These pads can be connected\nto other elements in the UI.", "operationId": "get_dynamic_pads", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Dynamic pads information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicPadsResponse" } } } }, "404": { "description": "Flow not found or not running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/latency": { "get": { "tags": [ "flows" ], "summary": "Get pipeline latency for a running flow.", "description": "Returns the latency information for a running pipeline. The flow must be\nstarted and in PLAYING state for latency information to be available.", "operationId": "get_flow_latency", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Latency retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LatencyResponse" } } } }, "404": { "description": "Flow not running or latency not available", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/pad-caps": { "get": { "tags": [ "flows" ], "summary": "Get negotiated caps for all pads in a running flow's pipeline.", "description": "Returns a JSON map of element_name → [(pad_name, direction, caps_string)].\nUseful for debugging caps negotiation failures.", "operationId": "get_flow_pad_caps", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Pad caps for all elements" }, "404": { "description": "Flow not running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/probes": { "get": { "tags": [ "probes" ], "summary": "List active probes on a flow.", "operationId": "list_probes", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Active probes", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActiveProbesResponse" } } } }, "404": { "description": "Flow not found or not running" } } }, "post": { "tags": [ "probes" ], "summary": "Activate a buffer age probe on a pad.", "operationId": "activate_probe", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActivateProbeRequest" } } }, "required": true }, "responses": { "200": { "description": "Probe activated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProbeResponse" } } } }, "400": { "description": "Invalid request" }, "404": { "description": "Flow not found or not running" } } } }, "/api/flows/{id}/probes/{probe_id}": { "delete": { "tags": [ "probes" ], "summary": "Deactivate a probe.", "operationId": "deactivate_probe", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID", "required": true, "schema": { "type": "string" } }, { "name": "probe_id", "in": "path", "description": "Probe ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Probe deactivated" }, "404": { "description": "Flow or probe not found" } } } }, "/api/flows/{id}/properties": { "patch": { "tags": [ "flows" ], "summary": "Update flow properties (description, clock type, etc.).", "description": "Updates the configuration properties of a flow. The flow must be stopped\nto change certain properties like the clock type.", "operationId": "update_flow_properties", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateFlowPropertiesRequest" } } }, "required": true }, "responses": { "200": { "description": "Properties updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/rtp-stats": { "get": { "tags": [ "flows" ], "summary": "Get runtime statistics for a flow's pipeline.", "description": "Returns RTP statistics from running pipeline elements, such as jitterbuffer\nstatistics for AES67 input blocks. The flow must be started and running\nfor statistics to be available.", "operationId": "get_flow_rtp_stats", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "RTP statistics retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowStatsResponse" } } } }, "404": { "description": "Flow not running or no RTP statistics available", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/start": { "post": { "tags": [ "flows" ], "summary": "Start a flow (pipeline).", "operationId": "start_flow", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Flow started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/stop": { "post": { "tags": [ "flows" ], "summary": "Stop a flow (pipeline).", "operationId": "stop_flow", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Flow stopped", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlowResponse" } } } }, "404": { "description": "Flow not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/flows/{id}/webrtc-stats": { "get": { "tags": [ "flows" ], "summary": "Get WebRTC statistics from a running flow.", "description": "Returns statistics from all webrtcbin elements in the pipeline, including\nthose nested in bins like whepclientsrc and whipclientsink. Stats include\nRTP stream information, ICE connection state, and raw stats data.", "operationId": "get_webrtc_stats", "parameters": [ { "name": "id", "in": "path", "description": "Flow ID (UUID)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "WebRTC statistics retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebRtcStatsResponse" } } } }, "404": { "description": "Flow not running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/gst-launch/export": { "post": { "tags": [ "gst-launch" ], "summary": "Export elements and links to gst-launch-1.0 syntax.", "operationId": "export_gst_launch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExportGstLaunchRequest" } } }, "required": true }, "responses": { "200": { "description": "Pipeline exported successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExportGstLaunchResponse" } } } }, "400": { "description": "Cannot export pipeline", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/gst-launch/parse": { "post": { "tags": [ "gst-launch" ], "summary": "Parse a gst-launch-1.0 pipeline string and extract elements and links.", "description": "This uses GStreamer's native pipeline parser to ensure complete compatibility\nwith the gst-launch-1.0 syntax.", "operationId": "parse_gst_launch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParseGstLaunchRequest" } } }, "required": true }, "responses": { "200": { "description": "Pipeline parsed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParseGstLaunchResponse" } } } }, "400": { "description": "Invalid pipeline syntax", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/gst-log-level": { "get": { "tags": [ "System" ], "summary": "Get the current GStreamer debug level filter", "operationId": "get_gst_log_level", "responses": { "200": { "description": "Current GStreamer debug level", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GstLogLevelResponse" } } } } } }, "put": { "tags": [ "System" ], "summary": "Set the GStreamer debug level filter at runtime", "operationId": "set_gst_log_level", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetGstLogLevelRequest" } } }, "required": true }, "responses": { "200": { "description": "GStreamer debug level updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GstLogLevelResponse" } } } }, "400": { "description": "Invalid filter string", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/ice-servers": { "get": { "tags": [ "whep" ], "summary": "GET /api/ice-servers - Get configured ICE servers for WebRTC connections.", "operationId": "get_ice_servers", "responses": { "200": { "description": "List of configured ICE servers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IceServersResponse" } } } } } } }, "/api/log-level": { "get": { "tags": [ "System" ], "summary": "Get the current log level filter", "operationId": "get_log_level", "responses": { "200": { "description": "Current log level", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LogLevelResponse" } } } } } }, "put": { "tags": [ "System" ], "summary": "Set the log level filter at runtime", "operationId": "set_log_level", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetLogLevelRequest" } } }, "required": true }, "responses": { "200": { "description": "Log level updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LogLevelResponse" } } } }, "400": { "description": "Invalid filter string", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/login": { "post": { "tags": [ "auth" ], "summary": "Login handler", "operationId": "login_handler", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginRequest" } } }, "required": true }, "responses": { "200": { "description": "Login attempt result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } }, "500": { "description": "Internal server error" } } } }, "/api/logout": { "post": { "tags": [ "auth" ], "summary": "Logout handler", "operationId": "logout_handler", "responses": { "200": { "description": "Logout successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } }, "500": { "description": "Internal server error" } } } }, "/api/mcp": { "get": { "tags": [ "mcp" ], "summary": "GET /api/mcp - Open SSE stream for server-initiated messages.", "description": "Opens a Server-Sent Events stream for receiving server-initiated\nJSON-RPC messages (notifications, requests from server).", "operationId": "mcp_get", "responses": { "200": { "description": "SSE stream for server-initiated messages", "content": { "text/event-stream": {} } }, "400": { "description": "Mcp-Session-Id header required" }, "401": { "description": "Authentication required" }, "403": { "description": "Invalid origin" }, "404": { "description": "Session not found" } } }, "post": { "tags": [ "mcp" ], "summary": "POST /api/mcp - Handle JSON-RPC requests.", "description": "Accepts JSON-RPC requests and returns either:\n- `application/json` for simple responses\n- `text/event-stream` for streaming responses (not implemented yet)\n\nThe `Mcp-Session-Id` header is assigned on initialize and required for subsequent requests.", "operationId": "mcp_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JsonRpcRequest" } } }, "required": true }, "responses": { "200": { "description": "JSON-RPC response", "content": { "application/json": {} } }, "202": { "description": "Notification accepted (no response body)" }, "400": { "description": "Invalid request or session required" }, "401": { "description": "Authentication required" }, "403": { "description": "Invalid origin (DNS rebinding protection)" } } }, "delete": { "tags": [ "mcp" ], "summary": "DELETE /api/mcp - Terminate a session.", "description": "Terminates the session identified by the `Mcp-Session-Id` header.", "operationId": "mcp_delete", "responses": { "204": { "description": "Session terminated successfully" }, "400": { "description": "Mcp-Session-Id header required" }, "401": { "description": "Authentication required" }, "403": { "description": "Invalid origin" }, "404": { "description": "Session not found" } } } }, "/api/media": { "get": { "tags": [ "Media" ], "summary": "List contents of a media directory.", "operationId": "list_media", "parameters": [ { "name": "path", "in": "query", "description": "Directory path relative to media root", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Directory listing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListMediaResponse" } } } }, "400": { "description": "Invalid path", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Directory not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/media/directory": { "post": { "tags": [ "Media" ], "summary": "Create a directory.", "operationId": "create_directory", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDirectoryRequest" } } }, "required": true }, "responses": { "200": { "description": "Directory created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaOperationResponse" } } } }, "400": { "description": "Invalid path", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Directory already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/media/directory/{path}": { "delete": { "tags": [ "Media" ], "summary": "Delete a directory (must be empty).", "operationId": "delete_directory", "parameters": [ { "name": "path", "in": "path", "description": "Directory path relative to media root", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Delete successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaOperationResponse" } } } }, "400": { "description": "Invalid path or directory not empty", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Directory not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/media/file/{path}": { "get": { "tags": [ "Media" ], "summary": "Download a file.", "operationId": "download_file", "parameters": [ { "name": "path", "in": "path", "description": "File path relative to media root", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "File content" }, "400": { "description": "Invalid path", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "Media" ], "summary": "Delete a file.", "operationId": "delete_file", "parameters": [ { "name": "path", "in": "path", "description": "File path relative to media root", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Delete successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaOperationResponse" } } } }, "400": { "description": "Invalid path", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/media/rename": { "post": { "tags": [ "Media" ], "summary": "Rename a file or directory.", "operationId": "rename_media", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RenameMediaRequest" } } }, "required": true }, "responses": { "200": { "description": "Rename successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaOperationResponse" } } } }, "400": { "description": "Invalid path or name", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File or directory not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/media/upload": { "post": { "tags": [ "Media" ], "summary": "Upload files to a directory.", "operationId": "upload_files", "parameters": [ { "name": "path", "in": "query", "description": "Directory path to upload to", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Upload successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaOperationResponse" } } } }, "400": { "description": "Invalid path or upload", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Upload failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/network/interfaces": { "get": { "tags": [ "Network" ], "summary": "List all network interfaces on the system.", "description": "Returns information about all network interfaces including name, MAC address,\nand IP addresses. Useful for selecting which interface to use for multicast\noperations (e.g., AES67 streams).", "operationId": "list_interfaces", "responses": { "200": { "description": "List of network interfaces", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NetworkInterfacesResponse" } } } } } } }, "/api/sources": { "get": { "tags": [ "flows" ], "summary": "Get available source flows for subscription.", "description": "Returns all flows that have InterOutput blocks, along with information\nabout whether each output is currently active (flow is running).\nThis scans all flow definitions, not just running flows.", "operationId": "get_available_sources", "responses": { "200": { "description": "List of available source flows", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AvailableSourcesResponse" } } } } } } }, "/api/system/clock": { "get": { "tags": [ "System" ], "summary": "Get system clock synchronization state", "description": "Returns the current kernel time-discipline state as reported by\n`ntp_adjtime(2)`. This includes the TAI-UTC offset, PLL status,\ncurrent offset being applied, and frequency adjustment — the same\ninformation used by chrony, ntpd and systemd-timesyncd.\n\nUseful for diagnosing flows that use `Realtime` or `Tai` pipeline\nclocks, where the accuracy depends on how the OS clock is being\nsynchronized.", "operationId": "get_system_clock", "responses": { "200": { "description": "System clock state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SystemClockInfo" } } } }, "500": { "description": "Failed to read system clock state" } } } }, "/api/version": { "get": { "tags": [ "System" ], "summary": "Get version and build information", "description": "Returns comprehensive version information including:\n- Package version from Cargo.toml\n- Git commit hash\n- Git tag (if on a tagged release)\n- Git branch name\n- Working directory status (dirty/clean)\n- Build timestamp", "operationId": "get_version", "responses": { "200": { "description": "Version information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SystemInfo" } } } } } } }, "/api/whep-streams": { "get": { "tags": [ "whep" ], "summary": "GET /api/whep-streams - List all active WHEP streams (JSON API).", "operationId": "list_whep_streams", "responses": { "200": { "description": "List of active WHEP streams", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WhepStreamsResponse" } } } } } } }, "/api/whip-endpoints": { "get": { "tags": [ "whip" ], "summary": "List active WHIP endpoints (public API, no auth required).", "operationId": "list_whip_endpoints", "responses": { "200": { "description": "List of active WHIP endpoints" } } } }, "/api/ws": { "get": { "tags": [ "websocket" ], "summary": "WebSocket endpoint for real-time bidirectional communication.", "description": "This endpoint establishes a WebSocket connection and:\n- Streams events to the client whenever flows are created, updated, deleted, started, or stopped\n- Sends ping messages every 15 seconds to keep the connection alive\n- Handles pong responses from the client\n\nExample usage from JavaScript:\n```javascript\nconst ws = new WebSocket('ws://localhost:3000/api/ws');\nws.onmessage = (event) => {\n const data = JSON.parse(event.data);\n console.log('Received event:', data);\n};\nws.onclose = () => console.log('Disconnected');\nws.onerror = (error) => console.error('WebSocket error:', error);\n```", "operationId": "websocket_handler", "responses": { "101": { "description": "WebSocket connection upgraded" }, "401": { "description": "Authentication required (use auth_token query param)" } } } }, "/whep/{endpoint_id}": { "post": { "tags": [ "whep" ], "summary": "Proxy POST requests to /whep/{endpoint_id}\nLooks up the internal port from WhepRegistry and forwards to localhost:{port}/whep/endpoint", "operationId": "whep_endpoint_proxy", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHEP endpoint identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "201": { "description": "WHEP session created, SDP answer returned", "content": { "application/sdp": {} } }, "404": { "description": "WHEP endpoint not found" }, "502": { "description": "Proxy error forwarding to internal WHEP server" } } }, "options": { "tags": [ "whep" ], "summary": "Handle OPTIONS preflight for /whep/{endpoint_id}", "operationId": "whep_endpoint_proxy_options", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHEP endpoint identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "CORS preflight response" } } } }, "/whep/{endpoint_id}/resource/{resource_id}": { "delete": { "tags": [ "whep" ], "summary": "Proxy DELETE requests to /whep/{endpoint_id}/resource/{resource_id}", "operationId": "whep_resource_proxy_delete", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHEP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHEP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "WHEP session deleted" }, "404": { "description": "WHEP endpoint not found" }, "502": { "description": "Proxy error forwarding to internal WHEP server" } } }, "options": { "tags": [ "whep" ], "summary": "Handle OPTIONS preflight for /whep/{endpoint_id}/resource/{resource_id}", "operationId": "whep_resource_proxy_options", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHEP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHEP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "CORS preflight response" } } }, "patch": { "tags": [ "whep" ], "summary": "Proxy PATCH requests to /whep/{endpoint_id}/resource/{resource_id} for ICE candidates", "operationId": "whep_resource_proxy_patch", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHEP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHEP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "ICE candidates accepted" }, "404": { "description": "WHEP endpoint not found" }, "502": { "description": "Proxy error forwarding to internal WHEP server" } } } }, "/whip/{endpoint_id}": { "post": { "tags": [ "whip" ], "summary": "Handle WHIP POST request (SDP offer from client).", "description": "Creates a new whipserversrc element for this session, proxies the SDP offer\nto it, and registers the session with the WhipSessionManager.", "operationId": "whip_post", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHIP endpoint identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "201": { "description": "WHIP session created, SDP answer returned", "content": { "application/sdp": {} } }, "404": { "description": "WHIP endpoint not found" }, "502": { "description": "Proxy error forwarding to internal WHIP server" }, "503": { "description": "WHIP element busy, retry in a moment" } } }, "options": { "tags": [ "whip" ], "summary": "Handle CORS preflight for WHIP endpoints.", "operationId": "whip_options", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHIP endpoint identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "CORS preflight response" } } } }, "/whip/{endpoint_id}/resource/{resource_id}": { "delete": { "tags": [ "whip" ], "summary": "Handle WHIP DELETE request (client disconnect).", "description": "Proxies the DELETE to the session's whipserversrc, then tears down the element\nand removes the session from the session manager.", "operationId": "whip_resource_delete", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHIP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHIP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "WHIP session deleted" }, "404": { "description": "WHIP endpoint or session not found" }, "502": { "description": "Proxy error forwarding to internal WHIP server" } } }, "options": { "tags": [ "whip" ], "summary": "Handle CORS preflight for WHIP resource endpoints.", "operationId": "whip_resource_options", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHIP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHIP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "CORS preflight response" } } }, "patch": { "tags": [ "whip" ], "summary": "Handle WHIP PATCH request (ICE trickle from client).", "description": "Looks up the session's port by resource_id and proxies the PATCH.", "operationId": "whip_resource_patch", "parameters": [ { "name": "endpoint_id", "in": "path", "description": "WHIP endpoint identifier", "required": true, "schema": { "type": "string" } }, { "name": "resource_id", "in": "path", "description": "WHIP resource/session identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "ICE candidates accepted" }, "404": { "description": "WHIP endpoint or session not found" }, "502": { "description": "Proxy error forwarding to internal WHIP server" } } } } }, "components": { "schemas": { "ActivateProbeRequest": { "type": "object", "description": "Request to activate a buffer age probe on a pad.", "required": [ "element_id" ], "properties": { "element_id": { "type": "string", "description": "Element ID to probe (standalone element or block ID)" }, "sample_interval": { "type": [ "integer", "null" ], "format": "int32", "description": "Measure every Nth buffer (default 1)", "minimum": 0 }, "timeout_secs": { "type": [ "integer", "null" ], "format": "int32", "description": "Auto-remove after this many seconds (default 60)", "minimum": 0 } } }, "ActiveProbesResponse": { "type": "object", "description": "Response listing active probes.", "required": [ "probes" ], "properties": { "probes": { "type": "array", "items": { "$ref": "#/components/schemas/ProbeInfo" }, "description": "List of active probes" } } }, "AnimateInputRequest": { "type": "object", "description": "Request to animate a single input's position/size.", "required": [ "input" ], "properties": { "duration_ms": { "type": "integer", "format": "int64", "description": "Animation duration in milliseconds", "minimum": 0 }, "height": { "type": [ "integer", "null" ], "format": "int32", "description": "Target height (optional)" }, "input": { "type": "integer", "description": "Input index (0-based)", "minimum": 0 }, "width": { "type": [ "integer", "null" ], "format": "int32", "description": "Target width (optional)" }, "xpos": { "type": [ "integer", "null" ], "format": "int32", "description": "Target X position (optional, keeps current if not specified)" }, "ypos": { "type": [ "integer", "null" ], "format": "int32", "description": "Target Y position (optional)" } } }, "AnnouncedStreamResponse": { "type": "object", "description": "Response for announced streams list.", "required": [ "flow_id", "block_id", "origin_ip", "sdp" ], "properties": { "announce_interface": { "type": [ "string", "null" ], "description": "Network interface the stream is announced on (None = all interfaces)." }, "block_id": { "type": "string" }, "flow_id": { "type": "string" }, "origin_ip": { "type": "string" }, "sdp": { "type": "string" } } }, "AuthStatusResponse": { "type": "object", "description": "Authentication status response.", "required": [ "authenticated", "auth_required", "methods" ], "properties": { "auth_required": { "type": "boolean", "description": "Whether authentication is required for this server" }, "authenticated": { "type": "boolean", "description": "Whether the current session is authenticated" }, "methods": { "type": "array", "items": { "type": "string" }, "description": "Available authentication methods (e.g., \"session\", \"api_key\")" } } }, "AvailableOutput": { "type": "object", "description": "Information about an available published output from a source flow.", "required": [ "name", "channel_name", "flow_name", "media_type", "is_active" ], "properties": { "channel_name": { "type": "string", "description": "Channel name for inter-pipeline communication (what InterInput blocks use)" }, "description": { "type": [ "string", "null" ], "description": "Description of the output" }, "flow_name": { "type": "string", "description": "Name of the flow that publishes this output" }, "is_active": { "type": "boolean", "description": "Whether the source flow is currently running (output is active)" }, "media_type": { "$ref": "#/components/schemas/MediaType", "description": "Media type (Audio, Video, Generic)" }, "name": { "type": "string", "description": "Name of the published output (block ID)" } } }, "AvailableSourcesResponse": { "type": "object", "description": "Response containing available source flows for subscription.", "required": [ "sources" ], "properties": { "sources": { "type": "array", "items": { "$ref": "#/components/schemas/SourceFlowInfo" }, "description": "List of flows that have published outputs" } } }, "BlockCategoriesResponse": { "type": "object", "description": "Response containing block categories", "required": [ "categories" ], "properties": { "categories": { "type": "array", "items": { "type": "string" } } } }, "BlockDefinition": { "type": "object", "description": "Block definition - metadata for creating block instances.\n\nNote: Built-in blocks use the BlockBuilder trait to create GStreamer elements directly.\nUser-defined blocks are not yet supported.", "required": [ "id", "name", "description", "category", "exposed_properties", "external_pads", "built_in" ], "properties": { "built_in": { "type": "boolean", "description": "Whether this is a built-in block (read-only) or user-defined" }, "category": { "type": "string", "description": "Category for organization (e.g., \"Inputs\", \"Outputs\", \"Codecs\")" }, "description": { "type": "string", "description": "Description of what this block does" }, "exposed_properties": { "type": "array", "items": { "$ref": "#/components/schemas/ExposedProperty" }, "description": "Exposed properties that users can configure" }, "external_pads": { "$ref": "#/components/schemas/ExternalPads", "description": "External pads exposed by this block" }, "id": { "type": "string", "description": "Unique identifier for this block definition" }, "name": { "type": "string", "description": "Human-readable name (e.g., \"AES67 Input\")" }, "ui_metadata": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BlockUIMetadata", "description": "Visual representation settings" } ] } } }, "BlockInstance": { "type": "object", "description": "Block instance in a flow", "required": [ "id", "block_definition_id", "properties", "position" ], "properties": { "block_definition_id": { "type": "string", "description": "Reference to the block definition" }, "computed_external_pads": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExternalPads", "description": "Computed external pads for this instance based on properties\nIf None, falls back to the pads from the block definition\nThis allows blocks to have dynamic pads based on their configuration" } ] }, "id": { "type": "string", "description": "Unique ID for this instance" }, "name": { "type": [ "string", "null" ], "description": "User-assigned name for this instance" }, "position": { "$ref": "#/components/schemas/Position", "description": "Position in the visual editor" }, "properties": { "type": "object", "description": "Property values for this instance", "additionalProperties": { "$ref": "#/components/schemas/PropertyValue" }, "propertyNames": { "type": "string" } }, "runtime_data": { "type": [ "object", "null" ], "description": "Runtime data (not persisted to storage, only available when flow is running)\nUsed for things like generated SDP for AES67 blocks", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } } } }, "BlockListResponse": { "type": "object", "description": "Response containing a list of blocks", "required": [ "blocks" ], "properties": { "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/BlockDefinition" } } } }, "BlockResponse": { "type": "object", "description": "Response containing a block definition", "required": [ "block" ], "properties": { "block": { "$ref": "#/components/schemas/BlockDefinition" } } }, "BlockStats": { "type": "object", "description": "Statistics for a single block instance.", "required": [ "block_instance_id", "block_definition_id", "block_name", "stats", "collected_at" ], "properties": { "block_definition_id": { "type": "string", "description": "The block definition ID (e.g., \"builtin.aes67_input\")" }, "block_instance_id": { "type": "string", "description": "The block instance ID" }, "block_name": { "type": "string", "description": "Human-readable block name" }, "collected_at": { "type": "integer", "format": "int64", "description": "Timestamp when these stats were collected (nanoseconds since epoch)", "minimum": 0 }, "stats": { "type": "array", "items": { "$ref": "#/components/schemas/Statistic" }, "description": "Collection of statistics for this block" } } }, "BlockUIMetadata": { "type": "object", "description": "UI metadata for block rendering", "properties": { "dark_fill_color": { "type": [ "string", "null" ], "description": "Fill/background color in dark mode (hex color)" }, "dark_stroke_color": { "type": [ "string", "null" ], "description": "Stroke/border color in dark mode (hex color)" }, "dark_text_color": { "type": [ "string", "null" ], "description": "Text color in dark mode (hex color)" }, "height": { "type": [ "number", "null" ], "format": "float", "description": "Height in the editor (in grid units)" }, "icon": { "type": [ "string", "null" ], "description": "Icon or visual identifier (emoji or name)" }, "light_fill_color": { "type": [ "string", "null" ], "description": "Fill/background color in light mode (hex color)" }, "light_stroke_color": { "type": [ "string", "null" ], "description": "Stroke/border color in light mode (hex color)" }, "light_text_color": { "type": [ "string", "null" ], "description": "Text color in light mode (hex color)" }, "width": { "type": [ "number", "null" ], "format": "float", "description": "Width in the editor (in grid units)" } } }, "ClientMessage": { "oneOf": [ { "type": "object", "description": "Subscribe to updates for a specific flow", "required": [ "flow_id", "type" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "subscribe" ] } } }, { "type": "object", "description": "Unsubscribe from updates for a specific flow", "required": [ "flow_id", "type" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "unsubscribe" ] } } }, { "type": "object", "description": "Ping to keep connection alive", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "ping" ] } } } ], "description": "Messages sent from client to server via WebSocket.", "discriminator": { "propertyName": "type" } }, "ClockSyncStatus": { "type": "string", "description": "Clock synchronization status.", "enum": [ "synced", "not_synced", "unknown" ] }, "CodecStats": { "type": "object", "description": "Codec statistics.", "properties": { "channels": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of channels (for audio)", "minimum": 0 }, "clock_rate": { "type": [ "integer", "null" ], "format": "int32", "description": "Clock rate in Hz", "minimum": 0 }, "mime_type": { "type": [ "string", "null" ], "description": "Codec MIME type (e.g., \"audio/opus\", \"video/VP8\")" }, "payload_type": { "type": [ "integer", "null" ], "format": "int32", "description": "Payload type number", "minimum": 0 } } }, "CpuAffinity": { "type": "string", "description": "CPU affinity strategy for GStreamer streaming threads.\n\nControls whether pipeline threads are pinned to a single CPU core\nfor better cache locality and reduced context switches.", "enum": [ "off", "single_core" ] }, "CreateBlockRequest": { "type": "object", "description": "Request to create a new block definition (currently not supported for user-defined blocks)", "required": [ "name", "description", "category", "exposed_properties", "external_pads" ], "properties": { "category": { "type": "string" }, "description": { "type": "string" }, "exposed_properties": { "type": "array", "items": { "$ref": "#/components/schemas/ExposedProperty" } }, "external_pads": { "$ref": "#/components/schemas/ExternalPads" }, "name": { "type": "string" }, "ui_metadata": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BlockUIMetadata" } ] } } }, "CreateDirectoryRequest": { "type": "object", "description": "Request to create a directory.", "required": [ "path" ], "properties": { "path": { "type": "string", "description": "Path for new directory (relative to media root)" } } }, "DeviceCategory": { "type": "string", "description": "Device category for filtering.", "enum": [ "audiosource", "audiosink", "videosource", "networksource", "other" ] }, "DeviceCountByCategory": { "type": "object", "description": "Device counts by category.", "required": [ "audio_source", "audio_sink", "video_source", "network_source", "other" ], "properties": { "audio_sink": { "type": "integer", "minimum": 0 }, "audio_source": { "type": "integer", "minimum": 0 }, "network_source": { "type": "integer", "minimum": 0 }, "other": { "type": "integer", "minimum": 0 }, "video_source": { "type": "integer", "minimum": 0 } } }, "DeviceDiscoveryStatus": { "type": "object", "description": "Device discovery status response.", "required": [ "running", "ndi_available", "device_count", "by_category" ], "properties": { "by_category": { "$ref": "#/components/schemas/DeviceCountByCategory", "description": "Number of devices by category." }, "device_count": { "type": "integer", "description": "Total number of discovered devices.", "minimum": 0 }, "ndi_available": { "type": "boolean", "description": "Whether NDI device provider is available." }, "running": { "type": "boolean", "description": "Whether device discovery is running." } } }, "DeviceResponse": { "type": "object", "description": "API response for a discovered device.", "required": [ "id", "name", "device_class", "category", "provider", "properties", "first_seen_secs_ago", "last_seen_secs_ago" ], "properties": { "category": { "$ref": "#/components/schemas/DeviceCategory", "description": "Device category." }, "device_class": { "type": "string", "description": "Device class (e.g., \"Audio/Source\", \"Video/Source\", \"Source/Network\")." }, "first_seen_secs_ago": { "type": "integer", "format": "int64", "description": "Seconds since first discovery.", "minimum": 0 }, "id": { "type": "string", "description": "Unique ID for this device." }, "last_seen_secs_ago": { "type": "integer", "format": "int64", "description": "Seconds since last seen.", "minimum": 0 }, "name": { "type": "string", "description": "Display name of the device." }, "properties": { "type": "object", "description": "Additional properties from the device.", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "provider": { "type": "string", "description": "Provider that discovered this device." } } }, "DiscoveredStreamResponse": { "type": "object", "description": "API response for a discovered AES67 stream.", "required": [ "id", "name", "source", "multicast_address", "port", "channels", "sample_rate", "encoding", "origin_host", "first_seen_secs_ago", "last_seen_secs_ago", "ttl_secs" ], "properties": { "channels": { "type": "integer", "format": "int32", "minimum": 0 }, "encoding": { "type": "string" }, "first_seen_secs_ago": { "type": "integer", "format": "int64", "minimum": 0 }, "id": { "type": "string" }, "last_seen_secs_ago": { "type": "integer", "format": "int64", "minimum": 0 }, "multicast_address": { "type": "string" }, "name": { "type": "string" }, "origin_host": { "type": "string" }, "port": { "type": "integer", "format": "int32", "minimum": 0 }, "received_on_interface": { "type": [ "string", "null" ], "description": "Network interface the stream was discovered on (for SAP)." }, "sample_rate": { "type": "integer", "format": "int32", "minimum": 0 }, "source": { "type": "string" }, "ttl_secs": { "type": "integer", "format": "int64", "minimum": 0 } } }, "DskToggleRequest": { "type": "object", "description": "Request to toggle a DSK (Downstream Keyer) layer on a vision mixer block.", "required": [ "dsk", "enabled" ], "properties": { "dsk": { "type": "integer", "description": "DSK layer number (1 or 2, 1-based)", "minimum": 0 }, "enabled": { "type": "boolean", "description": "Enable or disable the DSK layer" } } }, "DskToggleResponse": { "type": "object", "description": "Response after toggling a DSK layer.", "required": [ "message", "dsk", "enabled" ], "properties": { "dsk": { "type": "integer", "description": "DSK layer number (1-based)", "minimum": 0 }, "enabled": { "type": "boolean" }, "message": { "type": "string" } } }, "DynamicPadsResponse": { "type": "object", "description": "Response containing runtime dynamic pads information.", "required": [ "pads" ], "properties": { "pads": { "type": "object", "description": "Map of element_id -> {pad_name -> tee_element_name}\nThese are pads that appeared at runtime without defined links.", "additionalProperties": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "propertyNames": { "type": "string" } } } }, "Element": { "type": "object", "description": "Represents a GStreamer element instance in a flow.", "required": [ "id", "element_type", "position" ], "properties": { "element_type": { "type": "string", "description": "GStreamer element type (e.g., \"videotestsrc\", \"x264enc\", \"filesink\")" }, "id": { "$ref": "#/components/schemas/String", "description": "Unique identifier for this element instance" }, "pad_properties": { "type": "object", "description": "Pad properties (pad_name -> property_name -> value)", "additionalProperties": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/PropertyValue" }, "propertyNames": { "type": "string" } }, "propertyNames": { "type": "string" } }, "position": { "type": "array", "items": { "type": "number", "format": "float" }, "description": "Display position in the visual editor (x, y)" }, "properties": { "type": "object", "description": "Element properties as key-value pairs", "additionalProperties": { "$ref": "#/components/schemas/PropertyValue" }, "propertyNames": { "type": "string" } } } }, "ElementInfo": { "type": "object", "description": "Information about a GStreamer element type (for discovery/palette).", "required": [ "name", "description", "category", "src_pads", "sink_pads", "properties" ], "properties": { "category": { "type": "string", "description": "Element category (e.g., \"Source\", \"Filter\", \"Sink\", \"Codec\")" }, "description": { "type": "string", "description": "Human-readable description" }, "name": { "type": "string", "description": "Element type name" }, "properties": { "type": "array", "items": { "$ref": "#/components/schemas/PropertyInfo" }, "description": "Available properties" }, "sink_pads": { "type": "array", "items": { "$ref": "#/components/schemas/PadInfo" }, "description": "Available sink pads" }, "src_pads": { "type": "array", "items": { "$ref": "#/components/schemas/PadInfo" }, "description": "Available source pads" } } }, "ElementInfoResponse": { "type": "object", "description": "Response containing detailed information about a specific element.", "required": [ "element" ], "properties": { "element": { "$ref": "#/components/schemas/ElementInfo" } } }, "ElementListResponse": { "type": "object", "description": "Response containing information about available elements.", "required": [ "elements" ], "properties": { "elements": { "type": "array", "items": { "$ref": "#/components/schemas/ElementInfo" } } } }, "ElementPropertiesResponse": { "type": "object", "description": "Response containing current property values from a running element.", "required": [ "element_id", "properties" ], "properties": { "element_id": { "type": "string", "description": "The element ID" }, "properties": { "type": "object", "description": "Current property values", "additionalProperties": { "$ref": "#/components/schemas/PropertyValue" }, "propertyNames": { "type": "string" } } } }, "EnumValue": { "type": "object", "description": "Enum value with optional label for display", "required": [ "value" ], "properties": { "label": { "type": [ "string", "null" ], "description": "Optional human-readable label for UI display" }, "value": { "type": "string", "description": "The actual value stored/used" } } }, "ErrorResponse": { "type": "object", "description": "Standard error response.", "required": [ "error" ], "properties": { "details": { "type": [ "string", "null" ] }, "error": { "type": "string" } } }, "ExportGstLaunchRequest": { "type": "object", "description": "Request to convert flow elements/links to gst-launch-1.0 syntax.", "required": [ "elements", "links" ], "properties": { "elements": { "type": "array", "items": { "$ref": "#/components/schemas/Element" }, "description": "Elements to export" }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "description": "Links between elements" } } }, "ExportGstLaunchResponse": { "type": "object", "description": "Response containing the gst-launch-1.0 pipeline string.", "required": [ "pipeline" ], "properties": { "pipeline": { "type": "string", "description": "The generated gst-launch-1.0 pipeline string" } } }, "ExposedProperty": { "type": "object", "description": "Property exposed by a block to the outside", "required": [ "name", "label", "description", "property_type", "mapping" ], "properties": { "default_value": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PropertyValue", "description": "Default value" } ] }, "description": { "type": "string", "description": "Description for users" }, "label": { "type": "string", "description": "Human-readable label for display in UI (e.g., \"Auth Token\" instead of \"auth_token\")" }, "live": { "type": "boolean", "description": "Whether this property updates the pipeline in real-time without requiring a flow save.\nLive properties show a LIVE badge in the UI and send updates directly to running elements." }, "mapping": { "$ref": "#/components/schemas/PropertyMapping", "description": "Mapping to internal element property" }, "name": { "type": "string", "description": "Name of the exposed property (used as key)" }, "property_type": { "$ref": "#/components/schemas/PropertyType", "description": "Type of property" } } }, "ExternalPad": { "type": "object", "required": [ "name", "media_type", "internal_element_id", "internal_pad_name" ], "properties": { "internal_element_id": { "type": "string", "description": "Which internal element and pad this maps to" }, "internal_pad_name": { "type": "string" }, "label": { "type": [ "string", "null" ], "description": "Optional display label (shown in graph editor)" }, "media_type": { "$ref": "#/components/schemas/MediaType", "description": "Media type (audio, video, generic)" }, "name": { "type": "string", "description": "External name for this pad" } } }, "ExternalPads": { "type": "object", "description": "External pads that the block exposes", "required": [ "inputs", "outputs" ], "properties": { "inputs": { "type": "array", "items": { "$ref": "#/components/schemas/ExternalPad" }, "description": "Input pads (mapped to internal element pads)" }, "outputs": { "type": "array", "items": { "$ref": "#/components/schemas/ExternalPad" }, "description": "Output pads (mapped to internal element pads)" } } }, "FadeToBlackRequest": { "type": "object", "description": "Request to toggle Fade to Black on a vision mixer block.", "required": [ "duration_ms" ], "properties": { "duration_ms": { "type": "integer", "format": "int64", "description": "Duration in milliseconds (0 = instant)", "minimum": 0 } } }, "FadeToBlackResponse": { "type": "object", "description": "Response after toggling Fade to Black.", "required": [ "message", "active" ], "properties": { "active": { "type": "boolean" }, "message": { "type": "string" } } }, "Flow": { "type": "object", "description": "A complete GStreamer pipeline definition.\n\nA flow represents a named, configured GStreamer pipeline that can be\nstarted, stopped, and persisted.", "required": [ "id", "name" ], "properties": { "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/BlockInstance" }, "description": "Block instances in this flow" }, "elements": { "type": "array", "items": { "$ref": "#/components/schemas/Element" }, "description": "Elements in this flow" }, "gst_state": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PipelineState", "description": "Raw GStreamer pipeline state, exposed for diagnostics.\n\nPrefer [`running`](Self::running) for logic and display." } ] }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this flow" }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "description": "Links between element pads and/or block external pads" }, "name": { "type": "string", "description": "Human-readable name" }, "properties": { "$ref": "#/components/schemas/FlowProperties", "description": "Flow configuration properties" }, "running": { "type": "boolean", "description": "Whether the pipeline is actively running (data flowing).\n\nThis is the field most callers should use. It is `true` when the\nGStreamer pipeline is in `Playing` *or* in `Paused` due to an\nasync element that has not yet completed its transition." } } }, "FlowDebugInfo": { "type": "object", "description": "Debug information for a running flow's pipeline.\nProvides detailed timing, clock, and state information for troubleshooting.", "required": [ "flow_id", "flow_name" ], "properties": { "base_time_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Pipeline base_time in nanoseconds (reference point for running_time calculation)", "minimum": 0 }, "clock_time_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Current clock time in nanoseconds", "minimum": 0 }, "clock_type": { "type": [ "string", "null" ], "description": "Clock type being used (e.g., \"PTP\", \"Monotonic\", \"Realtime\")" }, "element_count": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of elements in the pipeline", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid", "description": "The flow ID" }, "flow_name": { "type": "string", "description": "The flow name" }, "is_live": { "type": [ "boolean", "null" ], "description": "Whether this is a live pipeline" }, "latency_formatted": { "type": [ "string", "null" ], "description": "Human-readable latency" }, "latency_max_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum pipeline latency in nanoseconds", "minimum": 0 }, "latency_min_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Minimum pipeline latency in nanoseconds", "minimum": 0 }, "pipeline_state": { "type": [ "string", "null" ], "description": "Pipeline state (Playing, Paused, etc.)" }, "ptp_grandmaster": { "type": [ "string", "null" ], "description": "PTP grandmaster clock ID (only if using PTP clock)" }, "running_time_formatted": { "type": [ "string", "null" ], "description": "Human-readable running_time (how long the pipeline has been playing)" }, "running_time_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Current running time in nanoseconds (clock_time - base_time)", "minimum": 0 } } }, "FlowListResponse": { "type": "object", "description": "Response containing a list of flows.", "required": [ "flows" ], "properties": { "flows": { "type": "array", "items": { "$ref": "#/components/schemas/Flow" } } } }, "FlowProperties": { "type": "object", "description": "Flow configuration properties.", "properties": { "auto_restart": { "type": "boolean", "description": "Whether this flow should be automatically restarted when the backend starts\n(set to true when starting a flow, false when manually stopping it)" }, "clock_sync_status": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ClockSyncStatus", "description": "Clock synchronization status (updated by backend for running pipelines)" } ] }, "clock_type": { "$ref": "#/components/schemas/GStreamerClockType", "description": "GStreamer clock type to use for this flow" }, "cpu_affinity": { "$ref": "#/components/schemas/CpuAffinity", "description": "CPU affinity for GStreamer streaming threads\nSingleCore pins all threads to one core for better cache locality" }, "created_at": { "type": [ "string", "null" ], "description": "Timestamp when the flow was created\nISO 8601 format with timezone" }, "description": { "type": [ "string", "null" ], "description": "Human-readable description (multiline text)" }, "direct_media_timing": { "type": [ "boolean", "null" ], "description": "Force direct media timing (`base_time=0`, `start_time=NONE`) so buffer\nPTS corresponds to absolute pipeline-clock time.\n\n- `Some(true)`: explicitly on.\n- `Some(false)`: explicitly off.\n- `None` (default): follow the clock-type default — `true` for `Ptp`\n (AES67 contract, RFC 7273 `mediaclk:direct=0`), `false` otherwise.\n\nUse this for narrow pipelines where every element cooperates with\nwall-clock timing (PTP+AES67, or TAI disciplined by `ptp4l`/`phc2sys`\nfeeding AES67 with TAI timestamps). Avoid for general pipelines\n(MPEG-TS demuxers, RTP jitter buffers, WHEP session sinks) that assume\n`running_time` starts near 0." }, "ephemeral": { "type": "boolean", "description": "When true, the flow is not persisted to storage. Useful for temporary or\nAPI-created flows that should not survive a server restart." }, "last_modified": { "type": [ "string", "null" ], "description": "Timestamp when the flow was last modified (any change to flow config)\nISO 8601 format with timezone" }, "ntp_info": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/NtpInfo", "description": "NTP clock information (updated by backend when clock_type is NTP)" } ] }, "ntp_port": { "type": [ "integer", "null" ], "format": "int32", "description": "NTP server port (only used when clock_type is NTP). Defaults to 123.", "minimum": 0 }, "ntp_server": { "type": [ "string", "null" ], "description": "NTP server address (hostname or IP, only used when clock_type is NTP)\nIf not set but clock_type is NTP, will signal as \"ntp=/traceable/\"" }, "ptp_domain": { "type": [ "integer", "null" ], "format": "int32", "description": "PTP domain (0-255, only used when clock_type is PTP)", "minimum": 0 }, "ptp_info": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PtpInfo", "description": "PTP clock information (updated by backend when clock_type is PTP)" } ] }, "started_at": { "type": [ "string", "null" ], "description": "Timestamp when the flow was started (entered Playing state)\nISO 8601 format with timezone (e.g., \"2024-01-15T14:30:00+01:00\")\nNone if the flow has never been started or is currently stopped" }, "thread_priority": { "$ref": "#/components/schemas/ThreadPriority", "description": "Thread priority for GStreamer streaming threads\nDefault is High (elevated but not realtime)" }, "thread_priority_status": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ThreadPriorityStatus", "description": "Status of thread priority configuration (updated by backend when pipeline starts)" } ] } } }, "FlowResponse": { "type": "object", "description": "Response containing a single flow.", "required": [ "flow" ], "properties": { "flow": { "$ref": "#/components/schemas/Flow" } } }, "FlowStatsResponse": { "type": "object", "description": "Response containing statistics for a running flow.", "required": [ "flow_id", "flow_name", "blocks", "collected_at" ], "properties": { "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/BlockStats" }, "description": "Statistics for each block in the flow" }, "collected_at": { "type": "integer", "format": "int64", "description": "Timestamp when stats were collected (nanoseconds since UNIX epoch)", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid", "description": "The flow ID" }, "flow_name": { "type": "string", "description": "The flow name" } } }, "GStreamerClockType": { "type": "string", "description": "GStreamer clock type selection.\n\nMaps to GStreamer's clock implementations:\n- `Monotonic`: SystemClock with GST_CLOCK_TYPE_MONOTONIC (default)\n- `Realtime`: SystemClock with GST_CLOCK_TYPE_REALTIME (UTC wall clock)\n- `Tai`: SystemClock with GST_CLOCK_TYPE_TAI (linear atomic time, no leap seconds)\n- `Ptp`: PtpClock for IEEE 1588 PTP synchronization\n- `Ntp`: NtpClock for NTP synchronization", "enum": [ "monotonic", "realtime", "tai", "ptp", "ntp" ] }, "GlRendererInfo": { "type": "object", "description": "OpenGL renderer information detected from GStreamer's GL context.", "required": [ "renderer", "version", "vendor", "glsl_version" ], "properties": { "glsl_version": { "type": "string", "description": "GLSL version string (e.g. \"4.60 NVIDIA\")" }, "renderer": { "type": "string", "description": "GL renderer string (e.g. \"NVIDIA GeForce RTX 3080/PCIe/SSE2\")" }, "vendor": { "type": "string", "description": "GL vendor string (e.g. \"NVIDIA Corporation\")" }, "version": { "type": "string", "description": "GL version string (e.g. \"4.6.0 NVIDIA 535.183.01\")" } } }, "GotoRequest": { "type": "object", "description": "Request to go to a specific file.", "required": [ "index" ], "properties": { "index": { "type": "integer", "description": "File index (0-based)", "minimum": 0 } } }, "GpuStats": { "type": "object", "description": "GPU statistics for a single GPU device.", "required": [ "index", "name", "utilization", "memory_utilization", "total_memory", "used_memory" ], "properties": { "index": { "type": "integer", "format": "int32", "description": "GPU device index", "minimum": 0 }, "memory_utilization": { "type": "number", "format": "float", "description": "Memory utilization percentage (0-100)" }, "name": { "type": "string", "description": "GPU device name" }, "power_usage": { "type": [ "number", "null" ], "format": "float", "description": "Power usage in watts (if available)" }, "temperature": { "type": [ "number", "null" ], "format": "float", "description": "Temperature in Celsius (if available)" }, "total_memory": { "type": "integer", "format": "int64", "description": "Total memory in bytes", "minimum": 0 }, "used_memory": { "type": "integer", "format": "int64", "description": "Used memory in bytes", "minimum": 0 }, "utilization": { "type": "number", "format": "float", "description": "GPU utilization percentage (0-100)" } } }, "GstLogLevelResponse": { "type": "object", "description": "Response for GStreamer debug level queries and updates.", "required": [ "current", "default" ], "properties": { "current": { "type": "string", "description": "The currently active GST_DEBUG filter string (e.g. \"*:2,webrtcbin:5\")" }, "default": { "type": "string", "description": "The default GST_DEBUG filter the server started with" } } }, "IceCandidateStats": { "type": "object", "description": "ICE candidate statistics.", "properties": { "local_address": { "type": [ "string", "null" ], "description": "Local candidate address" }, "local_candidate_type": { "type": [ "string", "null" ], "description": "Local candidate type (host, srflx, relay)" }, "local_port": { "type": [ "integer", "null" ], "format": "int32", "description": "Local candidate port", "minimum": 0 }, "local_protocol": { "type": [ "string", "null" ], "description": "Local candidate protocol (UDP/TCP)" }, "remote_address": { "type": [ "string", "null" ], "description": "Remote candidate address" }, "remote_candidate_type": { "type": [ "string", "null" ], "description": "Remote candidate type" }, "remote_port": { "type": [ "integer", "null" ], "format": "int32", "description": "Remote candidate port", "minimum": 0 }, "remote_protocol": { "type": [ "string", "null" ], "description": "Remote candidate protocol" }, "state": { "type": [ "string", "null" ], "description": "Connection state" } } }, "IceServer": { "type": "object", "description": "ICE server configuration for WebRTC.\nFor TURN servers, username and credential are extracted from the URL.", "required": [ "urls" ], "properties": { "credential": { "type": [ "string", "null" ], "description": "Credential for TURN server authentication" }, "urls": { "type": "string", "description": "ICE server URL (e.g., \"stun:stun.l.google.com:19302\")" }, "username": { "type": [ "string", "null" ], "description": "Username for TURN server authentication" } } }, "IceServersResponse": { "type": "object", "description": "Response structure for ICE servers endpoint.", "required": [ "ice_servers", "ice_transport_policy" ], "properties": { "ice_servers": { "type": "array", "items": { "$ref": "#/components/schemas/IceServer" }, "description": "List of ICE server configurations (STUN/TURN)" }, "ice_transport_policy": { "type": "string", "description": "ICE transport policy (\"all\" or \"relay\")" } } }, "Ipv4AddressInfo": { "type": "object", "description": "IPv4 address information.", "required": [ "address" ], "properties": { "address": { "type": "string", "description": "The IPv4 address" }, "broadcast": { "type": [ "string", "null" ], "description": "Broadcast address (if available)" }, "netmask": { "type": [ "string", "null" ], "description": "Network mask (if available)" } } }, "Ipv6AddressInfo": { "type": "object", "description": "IPv6 address information.", "required": [ "address" ], "properties": { "address": { "type": "string", "description": "The IPv6 address" }, "netmask": { "type": [ "string", "null" ], "description": "Network mask (if available)" } } }, "JsonRpcRequest": { "type": "object", "description": "JSON-RPC 2.0 Request.", "required": [ "jsonrpc", "method" ], "properties": { "id": {}, "jsonrpc": { "type": "string" }, "method": { "type": "string" }, "params": {} } }, "LatencyResponse": { "type": "object", "description": "Response containing pipeline latency information.", "required": [ "min_latency_ns", "max_latency_ns", "live", "min_latency_formatted", "max_latency_formatted" ], "properties": { "live": { "type": "boolean", "description": "Whether the pipeline is a live pipeline" }, "max_latency_formatted": { "type": "string", "description": "Maximum latency formatted as human-readable string" }, "max_latency_ns": { "type": "integer", "format": "int64", "description": "Maximum latency in nanoseconds", "minimum": 0 }, "min_latency_formatted": { "type": "string", "description": "Minimum latency formatted as human-readable string (e.g., \"10.5 ms\")" }, "min_latency_ns": { "type": "integer", "format": "int64", "description": "Minimum latency in nanoseconds", "minimum": 0 } } }, "Link": { "type": "object", "description": "A link between two element pads.\n\nFor API/serialization compatibility, this uses strings. Internally converted to ElementPadRef.", "required": [ "from", "to" ], "properties": { "from": { "type": "string", "description": "Source element and pad (format: \"element_id\" or \"element_id:pad_name\")" }, "to": { "type": "string", "description": "Destination element and pad (format: \"element_id\" or \"element_id:pad_name\")" } } }, "ListMediaResponse": { "type": "object", "description": "Response containing a directory listing.", "required": [ "current_path", "entries" ], "properties": { "current_path": { "type": "string", "description": "Current directory path (relative to media root)" }, "entries": { "type": "array", "items": { "$ref": "#/components/schemas/MediaFileEntry" }, "description": "Directory contents" }, "parent_path": { "type": [ "string", "null" ], "description": "Parent directory path (None if at root)" } } }, "LogLevelResponse": { "type": "object", "description": "Response for log level queries and updates.", "required": [ "current", "default" ], "properties": { "current": { "type": "string", "description": "The currently active log filter string (e.g. \"info,strom::api=debug\")" }, "default": { "type": "string", "description": "The default filter the server started with" } } }, "LoginRequest": { "type": "object", "description": "Login request payload.", "required": [ "username", "password" ], "properties": { "password": { "type": "string", "description": "Password for authentication" }, "username": { "type": "string", "description": "Username for authentication" } } }, "LoginResponse": { "type": "object", "description": "Login response.", "required": [ "success", "message" ], "properties": { "message": { "type": "string", "description": "Human-readable message describing the result" }, "success": { "type": "boolean", "description": "Whether the login was successful" } } }, "MediaFileEntry": { "type": "object", "description": "A file or directory entry in a media directory listing.", "required": [ "name", "path", "is_directory", "size", "modified" ], "properties": { "is_directory": { "type": "boolean", "description": "Whether this is a directory" }, "mime_type": { "type": [ "string", "null" ], "description": "MIME type (None for directories)" }, "modified": { "type": "integer", "format": "int64", "description": "Last modified timestamp (UNIX epoch seconds)", "minimum": 0 }, "name": { "type": "string", "description": "File or directory name" }, "path": { "type": "string", "description": "Full path relative to media root" }, "size": { "type": "integer", "format": "int64", "description": "File size in bytes (0 for directories)", "minimum": 0 } } }, "MediaOperationResponse": { "type": "object", "description": "Response for media operations.", "required": [ "success", "message" ], "properties": { "message": { "type": "string", "description": "Human-readable message" }, "success": { "type": "boolean", "description": "Whether the operation succeeded" } } }, "MediaType": { "type": "string", "description": "Media type classification for pads.", "enum": [ "Generic", "Audio", "Video" ] }, "MultiviewEndpointResponse": { "type": "object", "description": "Response for a vision mixer multiview endpoint query.", "required": [ "endpoint" ], "properties": { "endpoint": { "type": "string", "description": "WHEP endpoint path (e.g. \"/whep/my-endpoint\"), empty if not connected." } } }, "NdiDiscoveryStatus": { "type": "object", "description": "NDI discovery status response.", "required": [ "available", "source_count" ], "properties": { "available": { "type": "boolean", "description": "Whether NDI discovery is available (plugin installed)." }, "source_count": { "type": "integer", "description": "Number of discovered NDI sources.", "minimum": 0 } } }, "NetworkInterfaceInfo": { "type": "object", "description": "Information about a network interface.", "required": [ "name", "index", "ipv4_addresses", "ipv6_addresses", "is_loopback", "is_up" ], "properties": { "index": { "type": "integer", "format": "int32", "description": "Interface index", "minimum": 0 }, "ipv4_addresses": { "type": "array", "items": { "$ref": "#/components/schemas/Ipv4AddressInfo" }, "description": "IPv4 addresses assigned to this interface" }, "ipv6_addresses": { "type": "array", "items": { "$ref": "#/components/schemas/Ipv6AddressInfo" }, "description": "IPv6 addresses assigned to this interface" }, "is_loopback": { "type": "boolean", "description": "Whether this interface is a loopback interface" }, "is_up": { "type": "boolean", "description": "Whether this interface appears to be up (has addresses)" }, "mac_address": { "type": [ "string", "null" ], "description": "MAC address (if available)" }, "name": { "type": "string", "description": "Interface name (e.g., \"eth0\", \"enp0s3\")" } } }, "NetworkInterfacesResponse": { "type": "object", "description": "Response containing list of network interfaces.", "required": [ "interfaces" ], "properties": { "interfaces": { "type": "array", "items": { "$ref": "#/components/schemas/NetworkInterfaceInfo" }, "description": "List of network interfaces" } } }, "NtpInfo": { "type": "object", "description": "NTP clock information (GStreamer GstNtpClock / NetClientClock).\n\nPopulated at read-time from the running NtpClock instance. Values are snapshots\nfrom the clock's internal state at the moment the flow was queried.", "required": [ "server", "port", "synced", "minimum_update_interval_ns", "round_trip_limit_ns" ], "properties": { "last_update": { "type": [ "integer", "null" ], "format": "int64", "description": "Timestamp of last read (Unix seconds)", "minimum": 0 }, "minimum_update_interval_ns": { "type": "integer", "format": "int64", "description": "Minimum update interval between polls, in nanoseconds (from clock property)", "minimum": 0 }, "offset_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Current offset between external (server) and internal (local) clocks at\nthe calibration reference point, in nanoseconds. Positive = server ahead." }, "port": { "type": "integer", "format": "int32", "description": "Server port", "minimum": 0 }, "rate": { "type": [ "number", "null" ], "format": "double", "description": "Current calibration rate (external clock speed / local speed).\n1.0 = same speed, <1.0 = server slower than local, >1.0 = server faster." }, "round_trip_limit_ns": { "type": "integer", "format": "int64", "description": "Maximum RTT for accepted samples, in nanoseconds (from clock property)", "minimum": 0 }, "server": { "type": "string", "description": "Server hostname/IP the NtpClock is polling" }, "synced": { "type": "boolean", "description": "Whether the clock has collected enough observations to be considered stable" } } }, "OverlayAlphaRequest": { "type": "object", "description": "Request to set the multiview overlay alpha on a vision mixer block.", "required": [ "alpha" ], "properties": { "alpha": { "type": "number", "format": "double", "description": "Alpha value (0.0 = fully transparent, 1.0 = fully opaque)" } } }, "OverlayAlphaResponse": { "type": "object", "description": "Response after setting the multiview overlay alpha.", "required": [ "message", "alpha" ], "properties": { "alpha": { "type": "number", "format": "double" }, "message": { "type": "string" } } }, "PadInfo": { "type": "object", "description": "Information about an element pad.", "required": [ "name", "caps", "presence", "media_type" ], "properties": { "caps": { "type": "string", "description": "Pad capabilities (simplified)" }, "media_type": { "$ref": "#/components/schemas/MediaType", "description": "Media type classification" }, "name": { "type": "string", "description": "Pad name" }, "presence": { "$ref": "#/components/schemas/PadPresence", "description": "Pad presence type" }, "properties": { "type": "array", "items": { "$ref": "#/components/schemas/PropertyInfo" }, "description": "Properties available on this pad template" } } }, "PadPresence": { "type": "string", "description": "Pad presence type (static, dynamic, or request).", "enum": [ "Always", "Sometimes", "Request" ] }, "PadPropertiesResponse": { "type": "object", "description": "Response containing current property values from a pad.", "required": [ "element_id", "pad_name", "properties" ], "properties": { "element_id": { "type": "string", "description": "The element ID" }, "pad_name": { "type": "string", "description": "The pad name" }, "properties": { "type": "object", "description": "Current property values", "additionalProperties": { "$ref": "#/components/schemas/PropertyValue" }, "propertyNames": { "type": "string" } } } }, "ParseGstLaunchRequest": { "type": "object", "description": "Request to parse a gst-launch-1.0 pipeline string.", "required": [ "pipeline" ], "properties": { "pipeline": { "type": "string", "description": "The gst-launch-1.0 pipeline string to parse\nExample: \"videotestsrc pattern=ball ! videoconvert ! autovideosink\"" } } }, "ParseGstLaunchResponse": { "type": "object", "description": "Response containing parsed pipeline elements and links.", "required": [ "elements", "links" ], "properties": { "elements": { "type": "array", "items": { "$ref": "#/components/schemas/Element" }, "description": "Elements extracted from the parsed pipeline" }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "description": "Links between elements" } } }, "PipelineState": { "type": "string", "description": "GStreamer pipeline state.\n\nThese states correspond to the GStreamer GST_STATE enum.", "enum": [ "Null", "Ready", "Paused", "Playing" ] }, "PlayerAction": { "type": "string", "description": "Player control action.", "enum": [ "play", "pause", "stop", "next", "previous" ] }, "PlayerControlRequest": { "type": "object", "description": "Request to control the media player.", "required": [ "action" ], "properties": { "action": { "$ref": "#/components/schemas/PlayerAction" } } }, "PlayerState": { "type": "string", "description": "Playback state of a media player.", "enum": [ "playing", "paused", "stopped" ] }, "PlayerStateResponse": { "type": "object", "description": "Response with the current player state.", "required": [ "state", "position_ns", "duration_ns", "current_file_index", "total_files", "playlist", "loop_playlist" ], "properties": { "current_file": { "type": [ "string", "null" ], "description": "Current file path/URI" }, "current_file_index": { "type": "integer", "description": "Current file index (0-based)", "minimum": 0 }, "duration_ns": { "type": "integer", "format": "int64", "description": "Total duration in nanoseconds", "minimum": 0 }, "loop_playlist": { "type": "boolean", "description": "Whether playlist loops" }, "playlist": { "type": "array", "items": { "type": "string" }, "description": "Full playlist" }, "position_ns": { "type": "integer", "format": "int64", "description": "Current position in nanoseconds", "minimum": 0 }, "state": { "$ref": "#/components/schemas/PlayerState", "description": "Current playback state" }, "total_files": { "type": "integer", "description": "Total number of files in playlist", "minimum": 0 } } }, "Position": { "type": "object", "description": "Position in the visual editor", "required": [ "x", "y" ], "properties": { "x": { "type": "number", "format": "float" }, "y": { "type": "number", "format": "float" } } }, "ProbeInfo": { "type": "object", "description": "Information about an active probe.", "required": [ "probe_id", "element_id", "pad_name", "sample_count" ], "properties": { "element_id": { "type": "string", "description": "Element ID being probed" }, "pad_name": { "type": "string", "description": "Pad name being probed" }, "probe_id": { "type": "string", "description": "Unique probe ID" }, "sample_count": { "type": "integer", "format": "int64", "description": "Number of samples collected so far", "minimum": 0 } } }, "ProbeResponse": { "type": "object", "description": "Response after activating a probe.", "required": [ "probe_id" ], "properties": { "probe_id": { "type": "string", "description": "Unique probe ID" } } }, "PropertyInfo": { "type": "object", "description": "Information about an element property.", "required": [ "name", "description", "property_type" ], "properties": { "construct_only": { "type": "boolean", "description": "Property can only be set during construction" }, "controllable": { "type": "boolean", "description": "Property can be controlled over time with GstController" }, "default_value": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PropertyValue", "description": "Default value" } ] }, "description": { "type": "string", "description": "Human-readable description" }, "mutable_in_null": { "type": "boolean", "description": "Property can be changed in NULL state" }, "mutable_in_paused": { "type": "boolean", "description": "Property can be changed in PAUSED state" }, "mutable_in_playing": { "type": "boolean", "description": "Property can be changed in PLAYING state (live editing!)" }, "mutable_in_ready": { "type": "boolean", "description": "Property can be changed in READY state" }, "name": { "type": "string", "description": "Property name" }, "property_type": { "$ref": "#/components/schemas/PropertyType", "description": "Property type" }, "writable": { "type": "boolean", "description": "Property is writable" } } }, "PropertyMapping": { "type": "object", "description": "Maps an exposed property to one or more internal element properties", "required": [ "element_id", "property_name" ], "properties": { "element_id": { "type": "string", "description": "Which internal element's property to set" }, "property_name": { "type": "string", "description": "Property name on that element" }, "transform": { "type": [ "string", "null" ], "description": "Optional transformation (for future use)" } } }, "PropertyType": { "oneOf": [ { "type": "string", "enum": [ "string" ] }, { "type": "string", "enum": [ "multiline" ] }, { "type": "string", "enum": [ "int" ] }, { "type": "string", "enum": [ "uint" ] }, { "type": "string", "enum": [ "float" ] }, { "type": "string", "enum": [ "bool" ] }, { "type": "object", "required": [ "enum" ], "properties": { "enum": { "type": "object", "required": [ "values" ], "properties": { "values": { "type": "array", "items": { "$ref": "#/components/schemas/EnumValue" } } } } } }, { "type": "string", "description": "Network interface selector - frontend fetches available interfaces from API", "enum": [ "networkinterface" ] } ], "description": "Property type enumeration for exposed properties" }, "PropertyValue": { "oneOf": [ { "type": "string" }, { "type": "integer", "format": "int64" }, { "type": "integer", "format": "int64", "minimum": 0 }, { "type": "number", "format": "double" }, { "type": "boolean" } ], "description": "Property value that can be various types.\n\nGStreamer properties can be strings, numbers, booleans, enums, etc." }, "PtpInfo": { "type": "object", "description": "PTP clock information (IEEE 1588).\n\nContains detailed information about the PTP clock state including\ngrandmaster and master clock identities, and synchronization statistics.", "required": [ "domain", "synced" ], "properties": { "domain": { "type": "integer", "format": "int32", "description": "PTP domain currently in use by the running pipeline (0-255)", "minimum": 0 }, "grandmaster_clock_id": { "type": [ "string", "null" ], "description": "Grandmaster clock ID (EUI-64 format as hex string, e.g., \"00:11:22:FF:FE:33:44:55\")" }, "master_clock_id": { "type": [ "string", "null" ], "description": "Master clock ID (EUI-64 format as hex string)" }, "restart_needed": { "type": "boolean", "description": "True if configured domain differs from running domain (restart needed)" }, "stats": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PtpStats", "description": "PTP synchronization statistics (updated periodically)" } ] }, "synced": { "type": "boolean", "description": "Whether the clock is synchronized with a PTP master" } } }, "PtpStats": { "type": "object", "description": "PTP clock synchronization statistics.\n\nContains measurements from PTP clock synchronization including\npath delay, clock offset, and estimation quality.", "properties": { "clock_offset_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Clock offset/discontinuity in nanoseconds (positive = local clock ahead)\nThis is the correction being applied to keep clocks synchronized" }, "clock_rate": { "type": [ "number", "null" ], "format": "double", "description": "Clock rate ratio (local clock speed relative to PTP master)\n1.0 means clocks run at same speed, <1.0 means local is slower" }, "last_update": { "type": [ "integer", "null" ], "format": "int64", "description": "Timestamp of last statistics update (Unix timestamp in seconds)", "minimum": 0 }, "mean_path_delay_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Mean path delay to master clock in nanoseconds", "minimum": 0 }, "r_squared": { "type": [ "number", "null" ], "format": "double", "description": "R-squared value of clock estimation regression (0.0-1.0, higher is better)\nValues close to 1.0 indicate stable, accurate synchronization" } } }, "RenameMediaRequest": { "type": "object", "description": "Request to rename a file or directory.", "required": [ "old_path", "new_name" ], "properties": { "new_name": { "type": "string", "description": "New name (just the filename, not full path)" }, "old_path": { "type": "string", "description": "Current path (relative to media root)" } } }, "RtpStreamStats": { "type": "object", "description": "RTP stream statistics (inbound or outbound).", "properties": { "bitrate": { "type": [ "integer", "null" ], "format": "int64", "description": "Bitrate in bits per second (calculated)", "minimum": 0 }, "bytes": { "type": [ "integer", "null" ], "format": "int64", "description": "Total bytes sent/received", "minimum": 0 }, "codec": { "type": [ "string", "null" ], "description": "Codec being used" }, "fraction_lost": { "type": [ "number", "null" ], "format": "double", "description": "Fraction of packets lost in last interval (0.0-1.0, inbound only)" }, "jitter": { "type": [ "number", "null" ], "format": "double", "description": "Jitter in seconds (inbound only)" }, "media_type": { "type": [ "string", "null" ], "description": "Media type (audio or video)" }, "packets": { "type": [ "integer", "null" ], "format": "int64", "description": "Total packets sent/received", "minimum": 0 }, "packets_lost": { "type": [ "integer", "null" ], "format": "int64", "description": "Packets lost (inbound only)" }, "round_trip_time": { "type": [ "number", "null" ], "format": "double", "description": "Round-trip time in seconds" }, "ssrc": { "type": [ "integer", "null" ], "format": "int32", "description": "Stream identifier", "minimum": 0 } } }, "SeekRequest": { "type": "object", "description": "Request to seek to a position.", "required": [ "position_ns" ], "properties": { "position_ns": { "type": "integer", "format": "int64", "description": "Position in nanoseconds", "minimum": 0 } } }, "SelectPreviewRequest": { "type": "object", "description": "Request to select a preview source on a vision mixer block.", "required": [ "input" ], "properties": { "input": { "type": "integer", "description": "Index of the input to set as preview (0-based)", "minimum": 0 }, "multi": { "type": "boolean", "description": "If true, toggle the input in/out of the current PVW group (shift+click).\nIf false (default), replace the PVW group with just this input." } } }, "SelectPreviewResponse": { "type": "object", "description": "Response after selecting a preview source.", "required": [ "message", "preview_input", "program_input", "preview_inputs", "program_inputs" ], "properties": { "message": { "type": "string" }, "preview_input": { "type": "integer", "description": "First source in the PVW group (backward compat).", "minimum": 0 }, "preview_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 }, "description": "Full ordered PVW source group." }, "program_input": { "type": "integer", "description": "First source in the PGM group (backward compat).", "minimum": 0 }, "program_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 }, "description": "Full ordered PGM source group." } } }, "ServerMessage": { "oneOf": [ { "type": "object", "description": "Pipeline state has changed", "required": [ "flow_id", "state", "type" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "state": { "$ref": "#/components/schemas/PipelineState" }, "type": { "type": "string", "enum": [ "state_change" ] } } }, { "type": "object", "description": "An error occurred", "required": [ "message", "type" ], "properties": { "flow_id": { "type": [ "string", "null" ] }, "message": { "type": "string" }, "type": { "type": "string", "enum": [ "error" ] } } }, { "type": "object", "description": "A warning message", "required": [ "message", "type" ], "properties": { "flow_id": { "type": [ "string", "null" ] }, "message": { "type": "string" }, "type": { "type": "string", "enum": [ "warning" ] } } }, { "type": "object", "description": "Informational message", "required": [ "message", "type" ], "properties": { "message": { "type": "string" }, "type": { "type": "string", "enum": [ "info" ] } } } ], "description": "Messages sent from server to client via WebSocket.", "discriminator": { "propertyName": "type" } }, "SetBackgroundRequest": { "type": "object", "description": "Request to set or clear the background source on a vision mixer block.", "properties": { "input": { "type": [ "integer", "null" ], "description": "Source index to use as background (0-based), or null to clear.", "minimum": 0 } } }, "SetBackgroundResponse": { "type": "object", "description": "Response after setting/clearing the background source.", "required": [ "message" ], "properties": { "background_input": { "type": [ "integer", "null" ], "description": "Current background source index, or null if none.", "minimum": 0 }, "message": { "type": "string" } } }, "SetGstLogLevelRequest": { "type": "object", "description": "Request to change the GStreamer debug level at runtime.", "required": [ "filter" ], "properties": { "filter": { "type": "string", "description": "The new GST_DEBUG filter string (e.g. \"*:2,webrtcbin:5\")" } } }, "SetLogLevelRequest": { "type": "object", "description": "Request to change the log level at runtime.", "required": [ "filter" ], "properties": { "filter": { "type": "string", "description": "The new log filter string (e.g. \"info,strom::api=debug\")" } } }, "SetPlaylistRequest": { "type": "object", "description": "Request to set the playlist.", "required": [ "files" ], "properties": { "files": { "type": "array", "items": { "type": "string" }, "description": "List of file URIs (e.g., \"file:///path/to/video.mp4\")" } } }, "SourceFlowInfo": { "type": "object", "description": "Information about a flow that has published outputs.", "required": [ "flow_id", "flow_name", "outputs" ], "properties": { "flow_id": { "type": "string", "format": "uuid", "description": "The flow ID" }, "flow_name": { "type": "string", "description": "The flow name" }, "outputs": { "type": "array", "items": { "$ref": "#/components/schemas/AvailableOutput" }, "description": "Available outputs from this flow" } } }, "StatMetadata": { "type": "object", "description": "Metadata about a statistic.", "required": [ "display_name", "description" ], "properties": { "category": { "type": [ "string", "null" ], "description": "Category for grouping in UI (e.g., \"RTP\", \"Buffer\", \"Network\")" }, "description": { "type": "string", "description": "Description of what this statistic measures" }, "display_name": { "type": "string", "description": "Human-readable name for display" }, "unit": { "type": [ "string", "null" ], "description": "Unit of measurement (e.g., \"packets\", \"ms\", \"bytes\")" } } }, "StatValue": { "oneOf": [ { "type": "object", "description": "Counter - monotonically increasing value (e.g., packets received)", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "Counter" ] }, "value": { "type": "integer", "format": "int64", "description": "Counter - monotonically increasing value (e.g., packets received)", "minimum": 0 } } }, { "type": "object", "description": "Gauge - value that can go up or down (e.g., buffer level)", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "Gauge" ] }, "value": { "type": "integer", "format": "int64", "description": "Gauge - value that can go up or down (e.g., buffer level)" } } }, { "type": "object", "description": "Float value (e.g., average jitter)", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "Float" ] }, "value": { "type": "number", "format": "double", "description": "Float value (e.g., average jitter)" } } }, { "type": "object", "description": "Boolean flag (e.g., is_synced)", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "Bool" ] }, "value": { "type": "boolean", "description": "Boolean flag (e.g., is_synced)" } } }, { "type": "object", "description": "String value (e.g., current SSRC)", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "String" ] }, "value": { "type": "string", "description": "String value (e.g., current SSRC)" } } }, { "type": "object", "description": "Duration in nanoseconds", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "DurationNs" ] }, "value": { "type": "integer", "format": "int64", "description": "Duration in nanoseconds", "minimum": 0 } } }, { "type": "object", "description": "Timestamp in nanoseconds since epoch", "required": [ "value", "type" ], "properties": { "type": { "type": "string", "enum": [ "TimestampNs" ] }, "value": { "type": "integer", "format": "int64", "description": "Timestamp in nanoseconds since epoch", "minimum": 0 } } } ], "description": "A single statistic value with metadata." }, "Statistic": { "type": "object", "description": "A statistic with its current value and metadata.", "required": [ "id", "value", "metadata" ], "properties": { "id": { "type": "string", "description": "Unique identifier for this statistic within the block" }, "metadata": { "$ref": "#/components/schemas/StatMetadata", "description": "Metadata about this statistic" }, "value": { "$ref": "#/components/schemas/StatValue", "description": "Current value" } } }, "String": { "type": "string" }, "StromEvent": { "oneOf": [ { "type": "object", "description": "A flow was created", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow was created", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "FlowCreated" ] } } }, { "type": "object", "description": "A flow was updated", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow was updated", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "FlowUpdated" ] } } }, { "type": "object", "description": "A flow was deleted", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow was deleted", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "FlowDeleted" ] } } }, { "type": "object", "description": "A flow was started", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow was started", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "FlowStarted" ] } } }, { "type": "object", "description": "A flow was stopped", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow was stopped", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "FlowStopped" ] } } }, { "type": "object", "description": "A flow's state changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow's state changed", "required": [ "flow_id", "state" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "state": { "type": "string" } } }, "type": { "type": "string", "enum": [ "FlowStateChanged" ] } } }, { "type": "object", "description": "Pipeline error occurred", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Pipeline error occurred", "required": [ "flow_id", "error" ], "properties": { "error": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "source": { "type": [ "string", "null" ] } } }, "type": { "type": "string", "enum": [ "PipelineError" ] } } }, { "type": "object", "description": "Pipeline warning message", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Pipeline warning message", "required": [ "flow_id", "warning" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "source": { "type": [ "string", "null" ] }, "warning": { "type": "string" } } }, "type": { "type": "string", "enum": [ "PipelineWarning" ] } } }, { "type": "object", "description": "Pipeline info message", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Pipeline info message", "required": [ "flow_id", "message" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "message": { "type": "string" }, "source": { "type": [ "string", "null" ] } } }, "type": { "type": "string", "enum": [ "PipelineInfo" ] } } }, { "type": "object", "description": "Pipeline reached end of stream", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Pipeline reached end of stream", "required": [ "flow_id" ], "properties": { "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "PipelineEos" ] } } }, { "type": "object", "description": "Element property was changed on a running pipeline", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Element property was changed on a running pipeline", "required": [ "flow_id", "element_id", "property_name", "value" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "property_name": { "type": "string" }, "value": { "$ref": "#/components/schemas/PropertyValue" } } }, "type": { "type": "string", "enum": [ "PropertyChanged" ] } } }, { "type": "object", "description": "Pad property was changed on a running pipeline", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Pad property was changed on a running pipeline", "required": [ "flow_id", "element_id", "pad_name", "property_name", "value" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "pad_name": { "type": "string" }, "property_name": { "type": "string" }, "value": { "$ref": "#/components/schemas/PropertyValue" } } }, "type": { "type": "string", "enum": [ "PadPropertyChanged" ] } } }, { "type": "object", "description": "Ping event to keep connection alive", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "Ping" ] } } }, { "type": "object", "description": "Audio level meter data from GStreamer level element", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Audio level meter data from GStreamer level element", "required": [ "flow_id", "element_id", "rms", "peak", "decay" ], "properties": { "decay": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "Decay values in dB for each channel" }, "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "peak": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "Peak values in dB for each channel" }, "rms": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "RMS values in dB for each channel" } } }, "type": { "type": "string", "enum": [ "MeterData" ] } } }, { "type": "object", "description": "Audio spectrum analyzer data from GStreamer spectrum element", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Audio spectrum analyzer data from GStreamer spectrum element", "required": [ "flow_id", "element_id", "magnitudes" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "magnitudes": { "type": "array", "items": { "type": "array", "items": { "type": "number", "format": "float" } }, "description": "Magnitude values in dB per channel, each inner Vec is one channel's frequency bands" } } }, "type": { "type": "string", "enum": [ "SpectrumData" ] } } }, { "type": "object", "description": "EBU R128 loudness measurement data from GStreamer ebur128level element", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "EBU R128 loudness measurement data from GStreamer ebur128level element", "required": [ "flow_id", "element_id", "momentary", "true_peak" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "integrated": { "type": [ "number", "null" ], "format": "double", "description": "Integrated (global) loudness in LUFS (from start)" }, "loudness_range": { "type": [ "number", "null" ], "format": "double", "description": "Loudness range in LU" }, "momentary": { "type": "number", "format": "double", "description": "Momentary loudness in LUFS (400ms window)" }, "shortterm": { "type": [ "number", "null" ], "format": "double", "description": "Short-term loudness in LUFS (3s window)" }, "true_peak": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "True peak per channel in dBTP" } } }, "type": { "type": "string", "enum": [ "LoudnessData" ] } } }, { "type": "object", "description": "Audio latency measurement data from GStreamer audiolatency element", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Audio latency measurement data from GStreamer audiolatency element", "required": [ "flow_id", "element_id", "last_latency_us", "average_latency_us" ], "properties": { "average_latency_us": { "type": "integer", "format": "int64", "description": "Running average latency in microseconds (last 5 measurements)" }, "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "last_latency_us": { "type": "integer", "format": "int64", "description": "Last measured latency in microseconds" } } }, "type": { "type": "string", "enum": [ "LatencyData" ] } } }, { "type": "object", "description": "System monitoring statistics (CPU and GPU)", "required": [ "data", "type" ], "properties": { "data": { "$ref": "#/components/schemas/SystemStats", "description": "System monitoring statistics (CPU and GPU)" }, "type": { "type": "string", "enum": [ "SystemStats" ] } } }, { "type": "object", "description": "Thread CPU statistics for GStreamer streaming threads", "required": [ "data", "type" ], "properties": { "data": { "$ref": "#/components/schemas/ThreadStats", "description": "Thread CPU statistics for GStreamer streaming threads" }, "type": { "type": "string", "enum": [ "ThreadStats" ] } } }, { "type": "object", "description": "PTP clock statistics for a flow", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "PTP clock statistics for a flow", "required": [ "flow_id", "domain", "synced" ], "properties": { "clock_offset_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Clock offset/correction in nanoseconds" }, "clock_rate": { "type": [ "number", "null" ], "format": "double", "description": "Clock rate ratio (local vs master)" }, "domain": { "type": "integer", "format": "int32", "description": "PTP domain", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid" }, "grandmaster_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Grandmaster clock ID (EUI-64 identifier)", "minimum": 0 }, "master_id": { "type": [ "integer", "null" ], "format": "int64", "description": "Master clock ID (EUI-64 identifier)", "minimum": 0 }, "mean_path_delay_ns": { "type": [ "integer", "null" ], "format": "int64", "description": "Mean path delay to master in nanoseconds", "minimum": 0 }, "r_squared": { "type": [ "number", "null" ], "format": "double", "description": "R-squared (clock estimation quality, 0.0-1.0)" }, "synced": { "type": "boolean", "description": "Whether clock is synchronized" } } }, "type": { "type": "string", "enum": [ "PtpStats" ] } } }, { "type": "object", "description": "A flow's published output became available (flow started)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow's published output became available (flow started)", "required": [ "source_flow_id", "output_name", "channel_name" ], "properties": { "channel_name": { "type": "string" }, "output_name": { "type": "string" }, "source_flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "SourceOutputAvailable" ] } } }, { "type": "object", "description": "A flow's published output became unavailable (flow stopped)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A flow's published output became unavailable (flow stopped)", "required": [ "source_flow_id", "output_name" ], "properties": { "output_name": { "type": "string" }, "source_flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "SourceOutputUnavailable" ] } } }, { "type": "object", "description": "Subscription connection status changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Subscription connection status changed", "required": [ "consumer_flow_id", "source_flow_id", "output_name", "connected" ], "properties": { "connected": { "type": "boolean" }, "consumer_flow_id": { "type": "string", "format": "uuid" }, "output_name": { "type": "string" }, "source_flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "SubscriptionStatusChanged" ] } } }, { "type": "object", "description": "Quality of Service statistics (aggregated buffer drop info)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Quality of Service statistics (aggregated buffer drop info)", "required": [ "flow_id", "element_id", "element_name", "event_count", "avg_proportion", "min_proportion", "max_proportion", "avg_jitter", "total_processed", "is_falling_behind" ], "properties": { "avg_jitter": { "type": "integer", "format": "int64", "description": "Average jitter in nanoseconds" }, "avg_proportion": { "type": "number", "format": "double", "description": "Average proportion (< 1.0 = falling behind)" }, "block_id": { "type": [ "string", "null" ], "description": "Block ID if element is inside a block, None if standalone element" }, "element_id": { "type": "string", "description": "Element ID (standalone element ID or block ID if element is in block)" }, "element_name": { "type": "string", "description": "Full GStreamer element name (e.g., \"block_id:element_type\" or \"element_id\")" }, "event_count": { "type": "integer", "format": "int64", "description": "Number of QoS events in aggregation period", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid" }, "internal_element_type": { "type": [ "string", "null" ], "description": "Internal element type if part of a block (e.g., \"videoconvert\")" }, "is_falling_behind": { "type": "boolean", "description": "Whether pipeline is falling behind (avg_proportion < 1.0)" }, "max_proportion": { "type": "number", "format": "double", "description": "Maximum proportion seen" }, "min_proportion": { "type": "number", "format": "double", "description": "Minimum proportion seen" }, "total_processed": { "type": "integer", "format": "int64", "description": "Total buffers processed", "minimum": 0 } } }, "type": { "type": "string", "enum": [ "QoSStats" ] } } }, { "type": "object", "description": "A new AES67 stream was discovered via SAP or mDNS", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A new AES67 stream was discovered via SAP or mDNS", "required": [ "stream_id", "name", "source" ], "properties": { "name": { "type": "string" }, "source": { "type": "string", "description": "Discovery source: \"sap\" or \"mdns\"" }, "stream_id": { "type": "string" } } }, "type": { "type": "string", "enum": [ "StreamDiscovered" ] } } }, { "type": "object", "description": "A discovered stream was updated (re-announced)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A discovered stream was updated (re-announced)", "required": [ "stream_id" ], "properties": { "stream_id": { "type": "string" } } }, "type": { "type": "string", "enum": [ "StreamUpdated" ] } } }, { "type": "object", "description": "A discovered stream expired or was deleted", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A discovered stream expired or was deleted", "required": [ "stream_id" ], "properties": { "stream_id": { "type": "string" } } }, "type": { "type": "string", "enum": [ "StreamRemoved" ] } } }, { "type": "object", "description": "Media player position update (periodic)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Media player position update (periodic)", "required": [ "flow_id", "block_id", "position_ns", "duration_ns", "current_file_index", "total_files" ], "properties": { "block_id": { "type": "string" }, "current_file_index": { "type": "integer", "description": "Current file index (0-based)", "minimum": 0 }, "duration_ns": { "type": "integer", "format": "int64", "description": "Total duration in nanoseconds", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid" }, "position_ns": { "type": "integer", "format": "int64", "description": "Current position in nanoseconds", "minimum": 0 }, "total_files": { "type": "integer", "description": "Total number of files in playlist", "minimum": 0 } } }, "type": { "type": "string", "enum": [ "MediaPlayerPosition" ] } } }, { "type": "object", "description": "Media player state changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Media player state changed", "required": [ "flow_id", "block_id", "state" ], "properties": { "block_id": { "type": "string" }, "current_file": { "type": [ "string", "null" ], "description": "Current file path (if any)" }, "flow_id": { "type": "string", "format": "uuid" }, "state": { "$ref": "#/components/schemas/PlayerState", "description": "Playback state" } } }, "type": { "type": "string", "enum": [ "MediaPlayerStateChanged" ] } } }, { "type": "object", "description": "A transition was triggered on a compositor block", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A transition was triggered on a compositor block", "required": [ "flow_id", "block_instance_id", "from_input", "to_input", "transition_type", "duration_ms" ], "properties": { "block_instance_id": { "type": "string" }, "duration_ms": { "type": "integer", "format": "int64", "minimum": 0 }, "flow_id": { "type": "string", "format": "uuid" }, "from_input": { "type": "integer", "minimum": 0 }, "to_input": { "type": "integer", "minimum": 0 }, "transition_type": { "type": "string" } } }, "type": { "type": "string", "enum": [ "TransitionTriggered" ] } } }, { "type": "object", "description": "Audio analyzer waveform and vectorscope data from appsink", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Audio analyzer waveform and vectorscope data from appsink", "required": [ "flow_id", "element_id", "waveform_l_min", "waveform_l_max", "waveform_r_min", "waveform_r_max", "vectorscope_l", "vectorscope_r" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "vectorscope_l": { "type": "string", "description": "Vectorscope L channel samples (base64-encoded i8 samples)" }, "vectorscope_r": { "type": "string", "description": "Vectorscope R channel samples (base64-encoded i8 samples)" }, "waveform_l_max": { "type": "string", "description": "Waveform max values per column for L channel (base64-encoded i8 samples)" }, "waveform_l_min": { "type": "string", "description": "Waveform min values per column for L channel (base64-encoded i8 samples)" }, "waveform_r_max": { "type": "string", "description": "Waveform max values per column for R channel (base64-encoded i8 samples)" }, "waveform_r_min": { "type": "string", "description": "Waveform min values per column for R channel (base64-encoded i8 samples)" } } }, "type": { "type": "string", "enum": [ "AudioAnalyzerData" ] } } }, { "type": "object", "description": "Recorder block started writing a new file", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Recorder block started writing a new file", "required": [ "flow_id", "block_id", "filename" ], "properties": { "block_id": { "type": "string" }, "filename": { "type": "string", "description": "Full path to the file currently being written" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "RecorderFileChanged" ] } } }, { "type": "object", "description": "Recorder block reached its configured max duration and requests the flow to stop", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Recorder block reached its configured max duration and requests the flow to stop", "required": [ "flow_id", "block_id" ], "properties": { "block_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "RecorderAutoStop" ] } } }, { "type": "object", "description": "Buffer age warning (buffer is older than threshold)", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Buffer age warning (buffer is older than threshold)", "required": [ "flow_id", "element_id", "pad_name", "age_ms", "threshold_ms" ], "properties": { "age_ms": { "type": "integer", "format": "int64", "description": "Buffer age in milliseconds", "minimum": 0 }, "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "pad_name": { "type": "string" }, "threshold_ms": { "type": "integer", "format": "int64", "description": "Threshold that was exceeded, in milliseconds", "minimum": 0 } } }, "type": { "type": "string", "enum": [ "BufferAgeWarning" ] } } }, { "type": "object", "description": "Manual buffer age probe measurement", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Manual buffer age probe measurement", "required": [ "flow_id", "probe_id", "element_id", "pad_name", "age_ms", "sample_number" ], "properties": { "age_ms": { "type": "integer", "format": "int64", "description": "Buffer age in milliseconds", "minimum": 0 }, "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "pad_name": { "type": "string" }, "probe_id": { "type": "string" }, "sample_number": { "type": "integer", "format": "int64", "description": "Sequential sample number", "minimum": 0 } } }, "type": { "type": "string", "enum": [ "BufferAgeProbe" ] } } }, { "type": "object", "description": "A manual buffer age probe was activated", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A manual buffer age probe was activated", "required": [ "flow_id", "probe_id", "element_id", "pad_name" ], "properties": { "element_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "pad_name": { "type": "string" }, "probe_id": { "type": "string" } } }, "type": { "type": "string", "enum": [ "BufferAgeProbeActivated" ] } } }, { "type": "object", "description": "A manual buffer age probe was deactivated", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "A manual buffer age probe was deactivated", "required": [ "flow_id", "probe_id", "reason" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "probe_id": { "type": "string" }, "reason": { "type": "string", "description": "Reason: \"manual\", \"timeout\", \"flow_stopped\"" } } }, "type": { "type": "string", "enum": [ "BufferAgeProbeDeactivated" ] } } }, { "type": "object", "description": "Vision mixer PVW/PGM state changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Vision mixer PVW/PGM state changed", "required": [ "flow_id", "block_id", "preview_input", "program_input", "preview_inputs", "program_inputs" ], "properties": { "block_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" }, "preview_input": { "type": "integer", "description": "First source in PVW group (backward compat).", "minimum": 0 }, "preview_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 }, "description": "Full ordered PVW source group." }, "program_input": { "type": "integer", "description": "First source in PGM group (backward compat).", "minimum": 0 }, "program_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 }, "description": "Full ordered PGM source group." } } }, "type": { "type": "string", "enum": [ "VisionMixerStateChanged" ] } } }, { "type": "object", "description": "Vision mixer DSK layer toggled", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Vision mixer DSK layer toggled", "required": [ "flow_id", "block_id", "dsk", "enabled" ], "properties": { "block_id": { "type": "string" }, "dsk": { "type": "integer", "description": "DSK layer number (1-based)", "minimum": 0 }, "enabled": { "type": "boolean" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "VisionMixerDskChanged" ] } } }, { "type": "object", "description": "Vision mixer multiview overlay alpha changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Vision mixer multiview overlay alpha changed", "required": [ "flow_id", "block_id", "alpha" ], "properties": { "alpha": { "type": "number", "format": "double" }, "block_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "VisionMixerOverlayAlphaChanged" ] } } }, { "type": "object", "description": "Vision mixer Fade to Black state changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Vision mixer Fade to Black state changed", "required": [ "flow_id", "block_id", "active" ], "properties": { "active": { "type": "boolean" }, "block_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "VisionMixerFtbChanged" ] } } }, { "type": "object", "description": "Vision mixer background source changed", "required": [ "data", "type" ], "properties": { "data": { "type": "object", "description": "Vision mixer background source changed", "required": [ "flow_id", "block_id" ], "properties": { "background_input": { "type": [ "integer", "null" ], "description": "Background source index, or null if cleared.", "minimum": 0 }, "block_id": { "type": "string" }, "flow_id": { "type": "string", "format": "uuid" } } }, "type": { "type": "string", "enum": [ "VisionMixerBackgroundChanged" ] } } } ], "description": "Event types that can be broadcast to all connected clients.", "discriminator": { "propertyName": "type" } }, "SystemClockInfo": { "type": "object", "description": "System clock synchronization information.\n\nReads the kernel's `ntp_adjtime()` state (same information used by chrony,\nntpd, systemd-timesyncd, etc.) and reports how the system clock is being\ndisciplined. Relevant for flows using Realtime or TAI pipeline clocks.", "required": [ "tai_offset_sec", "state", "synchronized", "pll_active", "offset_ns", "frequency_ppm", "max_error_us", "est_error_us" ], "properties": { "est_error_us": { "type": "integer", "format": "int64", "description": "Estimated error, in microseconds." }, "frequency_ppm": { "type": "number", "format": "double", "description": "Current frequency adjustment in parts-per-million." }, "last_update": { "type": [ "integer", "null" ], "format": "int64", "description": "Timestamp when this info was read (Unix seconds).", "minimum": 0 }, "max_error_us": { "type": "integer", "format": "int64", "description": "Maximum error estimate, in microseconds." }, "offset_ns": { "type": "integer", "format": "int64", "description": "Current time offset being applied to the clock, in nanoseconds." }, "pll_active": { "type": "boolean", "description": "Whether PLL discipline is active (STA_PLL)." }, "state": { "type": "string", "description": "High-level state from `ntp_adjtime()` return value.\nOne of: `ok`, `ins` (leap insert pending), `del`, `oop`, `wait`, `error` (unsynced)." }, "synchronized": { "type": "boolean", "description": "Whether the kernel considers the clock synchronized (STA_UNSYNC not set)." }, "tai_offset_sec": { "type": "integer", "format": "int32", "description": "TAI - UTC offset in seconds (typically 37 as of 2026).\nSet by the clock sync daemon so that `CLOCK_TAI` is correct." } } }, "SystemInfo": { "type": "object", "description": "Server system information: version, build, runtime environment, and host details.", "required": [ "version", "git_hash", "git_tag", "git_branch", "git_dirty", "build_timestamp" ], "properties": { "build_id": { "type": "string", "description": "Unique build ID (UUID) generated at compile time" }, "build_timestamp": { "type": "string", "description": "Build timestamp (ISO 8601 format)" }, "git_branch": { "type": "string", "description": "Git branch name" }, "git_dirty": { "type": "boolean", "description": "Whether the working directory had uncommitted changes" }, "git_hash": { "type": "string", "description": "Git commit hash (short)" }, "git_tag": { "type": "string", "description": "Git tag (if on a tagged commit)" }, "gstreamer_version": { "type": "string", "description": "GStreamer runtime version" }, "hostname": { "type": "string", "description": "Server hostname (for generating external URLs)" }, "in_docker": { "type": "boolean", "description": "Whether running inside a Docker container" }, "os_info": { "type": "string", "description": "Operating system name and version" }, "process_started_at": { "type": "string", "description": "When the Strom server process was started (ISO 8601 format with timezone)" }, "system_boot_time": { "type": "string", "description": "When the system was booted (ISO 8601 format with timezone)" }, "version": { "type": "string", "description": "Package version from Cargo.toml" } } }, "SystemStats": { "type": "object", "description": "System monitoring statistics.", "required": [ "cpu_usage", "num_cores", "total_memory", "used_memory", "gpu_stats", "timestamp" ], "properties": { "cpu_usage": { "type": "number", "format": "float", "description": "CPU usage percentage (0-100)" }, "gl_renderer": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/GlRendererInfo", "description": "OpenGL renderer info from GStreamer (if available)" } ] }, "gpu_stats": { "type": "array", "items": { "$ref": "#/components/schemas/GpuStats" }, "description": "GPU statistics (if available)" }, "num_cores": { "type": "integer", "description": "Number of CPU cores available to this process (cgroup-aware)", "minimum": 0 }, "timestamp": { "type": "integer", "format": "int64", "description": "Timestamp of the measurement" }, "total_memory": { "type": "integer", "format": "int64", "description": "Total system memory in bytes", "minimum": 0 }, "used_memory": { "type": "integer", "format": "int64", "description": "Used system memory in bytes", "minimum": 0 } } }, "ThreadCpuStats": { "type": "object", "description": "CPU statistics for a single GStreamer streaming thread.", "required": [ "thread_id", "cpu_usage", "element_name", "flow_id" ], "properties": { "block_id": { "type": [ "string", "null" ], "description": "Block ID if the element is inside a block" }, "cpu_usage": { "type": "number", "format": "float", "description": "CPU usage percentage (0-100%)" }, "element_name": { "type": "string", "description": "Name of the GStreamer element that owns this thread" }, "flow_id": { "type": "string", "format": "uuid", "description": "Flow ID this thread belongs to" }, "pinned_cpus": { "type": [ "array", "null" ], "items": { "type": "integer", "minimum": 0 }, "description": "Logical CPUs this thread is pinned to (None if affinity is off).\nContains all sibling hyperthreads of the allocated physical core." }, "thread_id": { "type": "integer", "format": "int64", "description": "Native thread ID (OS-specific)", "minimum": 0 } } }, "ThreadPriority": { "type": "string", "description": "Thread priority level for GStreamer streaming threads.\n\nControls the scheduling priority of GStreamer's internal streaming threads.\nHigher priorities help ensure smooth media processing under system load.", "enum": [ "normal", "high", "realtime" ] }, "ThreadPriorityStatus": { "type": "object", "description": "Status of thread priority configuration for a running pipeline.", "required": [ "requested", "achieved", "threads_configured" ], "properties": { "achieved": { "type": "boolean", "description": "Whether the requested priority was successfully applied" }, "error": { "type": [ "string", "null" ], "description": "Error message if priority could not be set (empty if achieved)" }, "requested": { "$ref": "#/components/schemas/ThreadPriority", "description": "The requested thread priority level" }, "threads_configured": { "type": "integer", "format": "int32", "description": "Number of threads that had priority set", "minimum": 0 } } }, "ThreadStats": { "type": "object", "description": "Aggregated thread statistics for all GStreamer streaming threads.", "required": [ "threads", "timestamp" ], "properties": { "threads": { "type": "array", "items": { "$ref": "#/components/schemas/ThreadCpuStats" }, "description": "Statistics for all active streaming threads" }, "timestamp": { "type": "integer", "format": "int64", "description": "Timestamp when this snapshot was taken (Unix timestamp in milliseconds)" } } }, "TransitionResponse": { "type": "object", "description": "Response after triggering a transition.", "required": [ "message", "transition_type", "duration_ms" ], "properties": { "duration_ms": { "type": "integer", "format": "int64", "description": "Duration of the transition in milliseconds", "minimum": 0 }, "message": { "type": "string", "description": "Success message" }, "transition_type": { "type": "string", "description": "The type of transition that was triggered" } } }, "TransportStats": { "type": "object", "description": "Transport statistics.", "properties": { "bytes_received": { "type": [ "integer", "null" ], "format": "int64", "description": "Total bytes received", "minimum": 0 }, "bytes_sent": { "type": [ "integer", "null" ], "format": "int64", "description": "Total bytes sent", "minimum": 0 }, "packets_received": { "type": [ "integer", "null" ], "format": "int64", "description": "Total packets received", "minimum": 0 }, "packets_sent": { "type": [ "integer", "null" ], "format": "int64", "description": "Total packets sent", "minimum": 0 } } }, "TriggerTransitionRequest": { "type": "object", "description": "Request to trigger a transition on a compositor block.", "required": [ "from_input", "to_input" ], "properties": { "duration_ms": { "type": "integer", "format": "int64", "description": "Duration of the transition in milliseconds (ignored for \"cut\")", "minimum": 0 }, "from_input": { "type": "integer", "description": "Index of the currently active input (0-based)", "minimum": 0 }, "to_input": { "type": "integer", "description": "Index of the input to transition to (0-based)", "minimum": 0 }, "transition_type": { "type": "string", "description": "Type of transition: \"cut\", \"fade\", \"slide_left\", \"slide_right\", \"slide_up\", \"slide_down\"" } } }, "UpdateFlowPropertiesRequest": { "type": "object", "description": "Request to update flow properties.", "required": [ "properties" ], "properties": { "properties": { "$ref": "#/components/schemas/FlowProperties" } } }, "UpdatePadPropertyRequest": { "type": "object", "description": "Request to update a property on a pad in a running pipeline.", "required": [ "property_name", "value" ], "properties": { "property_name": { "type": "string", "description": "The name of the property to update" }, "value": { "$ref": "#/components/schemas/PropertyValue", "description": "The new value for the property" } } }, "UpdatePropertyRequest": { "type": "object", "description": "Request to update a property on a running pipeline element.", "required": [ "property_name", "value" ], "properties": { "property_name": { "type": "string", "description": "The name of the property to update" }, "ramp_ms": { "type": [ "integer", "null" ], "format": "int32", "description": "Optional ramp duration in milliseconds. Currently honored for audio\n`volume`-element `volume` and `mute` updates — when set, `volume` is\ninterpolated per-sample over the given duration (anti-zipper / fade)\nand `mute=true` is preceded by a fade-out of the same length while\n`mute=false` is followed by a 0→pre_mute fade-in. Useful for\nbroadcast-style on-air / off-air route transitions (e.g. 500 ms).\nWhen omitted, a short default ramp is used for `volume`/`mute`; other\nproperties are set immediately.", "minimum": 0 }, "value": { "$ref": "#/components/schemas/PropertyValue", "description": "The new value for the property" } } }, "VisionMixerState": { "type": "object", "description": "Current state of a vision mixer block.", "required": [ "preview_input", "program_input", "preview_inputs", "program_inputs", "num_inputs", "input_labels" ], "properties": { "input_labels": { "type": "array", "items": { "type": "string" } }, "num_inputs": { "type": "integer", "minimum": 0 }, "preview_input": { "type": "integer", "minimum": 0 }, "preview_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 } }, "program_input": { "type": "integer", "minimum": 0 }, "program_inputs": { "type": "array", "items": { "type": "integer", "minimum": 0 } } } }, "WebRtcConnectionStats": { "type": "object", "description": "Stats for a single WebRTC connection (webrtcbin element).", "required": [ "inbound_rtp", "outbound_rtp", "codecs", "raw" ], "properties": { "codecs": { "type": "array", "items": { "$ref": "#/components/schemas/CodecStats" }, "description": "Codec statistics (keyed by codec ID)" }, "ice_candidates": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/IceCandidateStats", "description": "ICE candidate pair statistics" } ] }, "inbound_rtp": { "type": "array", "items": { "$ref": "#/components/schemas/RtpStreamStats" }, "description": "Inbound RTP stream statistics" }, "outbound_rtp": { "type": "array", "items": { "$ref": "#/components/schemas/RtpStreamStats" }, "description": "Outbound RTP stream statistics" }, "raw": { "type": "object", "description": "Raw stats as key-value pairs (for debugging/extensibility)", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "transport": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TransportStats", "description": "Transport statistics" } ] } } }, "WebRtcStats": { "type": "object", "description": "WebRTC statistics for a flow.", "required": [ "connections" ], "properties": { "connections": { "type": "object", "description": "Stats for each WebRTC connection (keyed by element name)", "additionalProperties": { "$ref": "#/components/schemas/WebRtcConnectionStats" }, "propertyNames": { "type": "string" } } } }, "WebRtcStatsResponse": { "type": "object", "description": "Response containing WebRTC statistics.", "required": [ "flow_id", "stats" ], "properties": { "flow_id": { "type": "string", "format": "uuid" }, "stats": { "$ref": "#/components/schemas/WebRtcStats" } } }, "WhepStreamInfo": { "type": "object", "description": "Response structure for a WHEP stream.", "required": [ "endpoint_id", "num_audio_tracks", "num_video_tracks" ], "properties": { "endpoint_id": { "type": "string", "description": "Unique identifier for the WHEP endpoint" }, "num_audio_tracks": { "type": "integer", "description": "Number of independent audio tracks exposed by this endpoint (0 = audio\ndisabled). Clients should add this many recvonly audio transceivers in\ntheir offer.", "minimum": 0 }, "num_video_tracks": { "type": "integer", "description": "Number of independent video tracks exposed by this endpoint (0 = video\ndisabled). Clients should add this many recvonly video transceivers in\ntheir offer.", "minimum": 0 } } }, "WhepStreamsResponse": { "type": "object", "description": "Response structure for the streams list endpoint.", "required": [ "streams" ], "properties": { "streams": { "type": "array", "items": { "$ref": "#/components/schemas/WhepStreamInfo" }, "description": "List of active WHEP streams" } } } } }, "tags": [ { "name": "flows", "description": "GStreamer flow management endpoints" }, { "name": "elements", "description": "GStreamer element discovery endpoints" }, { "name": "blocks", "description": "Reusable block management endpoints" }, { "name": "gst-launch", "description": "gst-launch-1.0 import/export endpoints" }, { "name": "Network", "description": "Network interface discovery endpoints" }, { "name": "System", "description": "System information endpoints" }, { "name": "Media", "description": "Media file management endpoints" }, { "name": "auth", "description": "Authentication endpoints" }, { "name": "whep", "description": "WHEP WebRTC playback endpoints" }, { "name": "whip", "description": "WHIP WebRTC ingest endpoints" }, { "name": "mcp", "description": "Model Context Protocol (MCP) endpoints" }, { "name": "discovery", "description": "AES67 stream and device discovery endpoints" }, { "name": "media_player", "description": "Media player control endpoints" }, { "name": "probes", "description": "Buffer age probe endpoints" }, { "name": "websocket", "description": "WebSocket real-time communication" } ] }