openapi: 3.0.3 info: title: Video Shader Toys Control API version: 0.1.0 description: | REST API exposed by the local Video Shader Toys control server. The API is intended for local control tools and the bundled React UI. All mutating endpoints return a small action result object. Successful mutating requests also broadcast the latest runtime state over the `/ws` WebSocket. WebSocket state streaming is not described by OpenAPI; connect to `ws://127.0.0.1:{port}/ws` to receive full runtime state JSON messages whenever state changes. servers: - url: http://127.0.0.1:8080 description: Default local control server tags: - name: State description: Runtime state and status. - name: Layers description: Layer stack control. - name: Stack Presets description: Save and recall layer stack presets. - name: Runtime description: Runtime actions. paths: /api/state: get: tags: [State] summary: Get current runtime state operationId: getRuntimeState responses: "200": description: Current runtime state. content: application/json: schema: $ref: "#/components/schemas/RuntimeState" /api/layers/add: post: tags: [Layers] summary: Add a layer using a shader package operationId: addLayer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddLayerRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/remove: post: tags: [Layers] summary: Remove a layer operationId: removeLayer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LayerIdRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/move: post: tags: [Layers] summary: Move a layer by direction description: Moves a layer up or down by one or more positions, depending on the signed direction value. operationId: moveLayer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MoveLayerRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/reorder: post: tags: [Layers] summary: Move a layer to an absolute index operationId: reorderLayer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ReorderLayerRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/set-bypass: post: tags: [Layers] summary: Set layer bypass state operationId: setLayerBypass requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SetBypassRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/set-shader: post: tags: [Layers] summary: Change the shader package used by a layer operationId: setLayerShader requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SetShaderRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/update-parameter: post: tags: [Layers] summary: Update a layer parameter value operationId: updateLayerParameter requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateParameterRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/layers/reset-parameters: post: tags: [Layers] summary: Reset a layer's parameters to shader defaults operationId: resetLayerParameters requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LayerIdRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/stack-presets/save: post: tags: [Stack Presets] summary: Save the current layer stack as a preset operationId: saveStackPreset requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PresetNameRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/stack-presets/load: post: tags: [Stack Presets] summary: Load a layer stack preset operationId: loadStackPreset requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PresetNameRequest" responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/reload: post: tags: [Runtime] summary: Reload shaders description: Rescans the shader library, re-reads manifests, queues shader compilation, and refreshes shader availability/errors. If a changed shader fails, the previous working stack remains active where possible. operationId: reloadShaders requestBody: required: false content: application/json: schema: type: object additionalProperties: false responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" /api/screenshot: post: tags: [Runtime] summary: Queue a PNG screenshot of the final output render target description: Captures the next completed output render target and writes it under `runtime/screenshots/`. operationId: queueScreenshot requestBody: required: false content: application/json: schema: type: object additionalProperties: false responses: "200": $ref: "#/components/responses/ActionOk" "400": $ref: "#/components/responses/ActionError" components: responses: ActionOk: description: Action succeeded. content: application/json: schema: $ref: "#/components/schemas/ActionResponse" example: ok: true ActionError: description: Action failed or request JSON was invalid. content: application/json: schema: $ref: "#/components/schemas/ActionResponse" example: ok: false error: Unknown layer id. schemas: ActionResponse: type: object required: [ok] properties: ok: type: boolean error: type: string description: Present when the request fails or when the runtime returns a diagnostic. additionalProperties: false AddLayerRequest: type: object required: [shaderId] properties: shaderId: type: string example: studio-color additionalProperties: false LayerIdRequest: type: object required: [layerId] properties: layerId: type: string example: layer-1 additionalProperties: false MoveLayerRequest: type: object required: [layerId, direction] properties: layerId: type: string direction: type: integer description: Signed movement direction. Negative moves toward the top of the stack; positive moves toward the bottom. example: -1 additionalProperties: false ReorderLayerRequest: type: object required: [layerId, targetIndex] properties: layerId: type: string targetIndex: type: integer minimum: 0 example: 0 additionalProperties: false SetBypassRequest: type: object required: [layerId, bypass] properties: layerId: type: string bypass: type: boolean additionalProperties: false SetShaderRequest: type: object required: [layerId, shaderId] properties: layerId: type: string shaderId: type: string example: vhs additionalProperties: false UpdateParameterRequest: type: object required: [layerId, parameterId, value] properties: layerId: type: string parameterId: type: string example: brightness value: description: Parameter value. Type depends on the shader parameter definition. oneOf: - type: number - type: boolean - type: string - type: array items: type: number example: 1.25 additionalProperties: false PresetNameRequest: type: object required: [presetName] properties: presetName: type: string example: live-show-look additionalProperties: false RuntimeState: type: object properties: app: $ref: "#/components/schemas/AppState" runtime: $ref: "#/components/schemas/RuntimeStatus" video: $ref: "#/components/schemas/VideoStatus" decklink: $ref: "#/components/schemas/DeckLinkStatus" videoIO: $ref: "#/components/schemas/VideoIOStatus" performance: $ref: "#/components/schemas/PerformanceStatus" shaders: type: array items: $ref: "#/components/schemas/ShaderSummary" stackPresets: type: array items: type: string layers: type: array items: $ref: "#/components/schemas/LayerState" AppState: type: object properties: serverPort: type: number oscPort: type: number autoReload: type: boolean maxTemporalHistoryFrames: type: number enableExternalKeying: type: boolean inputVideoFormat: type: string inputFrameRate: type: string outputVideoFormat: type: string outputFrameRate: type: string RuntimeStatus: type: object properties: layerCount: type: number compileSucceeded: type: boolean compileMessage: type: string VideoStatus: type: object properties: hasSignal: type: boolean width: type: number height: type: number modeName: type: string DeckLinkStatus: type: object deprecated: true description: Legacy DeckLink-specific status object. Prefer `videoIO` for new clients. properties: modelName: type: string supportsInternalKeying: type: boolean supportsExternalKeying: type: boolean keyerInterfaceAvailable: type: boolean externalKeyingRequested: type: boolean externalKeyingActive: type: boolean statusMessage: type: string VideoIOStatus: type: object properties: backend: type: string example: decklink modelName: type: string supportsInternalKeying: type: boolean supportsExternalKeying: type: boolean keyerInterfaceAvailable: type: boolean externalKeyingRequested: type: boolean externalKeyingActive: type: boolean statusMessage: type: string PerformanceStatus: type: object properties: frameBudgetMs: type: number renderMs: type: number smoothedRenderMs: type: number budgetUsedPercent: type: number completionIntervalMs: type: number smoothedCompletionIntervalMs: type: number maxCompletionIntervalMs: type: number lateFrameCount: type: number droppedFrameCount: type: number flushedFrameCount: type: number ShaderSummary: type: object properties: id: type: string name: type: string description: type: string category: type: string available: type: boolean description: False when the shader package exists but failed manifest or compile validation. error: type: string description: Error text for unavailable shader packages. temporal: $ref: "#/components/schemas/TemporalState" TemporalState: type: object properties: enabled: type: boolean historySource: type: string enum: [source, preLayerInput, none] requestedHistoryLength: type: number effectiveHistoryLength: type: number LayerState: type: object properties: id: type: string shaderId: type: string shaderName: type: string bypass: type: boolean temporal: $ref: "#/components/schemas/TemporalState" parameters: type: array items: $ref: "#/components/schemas/ParameterState" ParameterState: type: object properties: id: type: string label: type: string description: type: string description: Short helper text shown under the parameter label in the control UI. type: type: string enum: [float, vec2, color, bool, enum, text, trigger] defaultValue: description: Default parameter value from the shader manifest. oneOf: - type: number - type: boolean - type: string - type: array items: type: number min: type: array items: type: number max: type: array items: type: number step: type: array items: type: number options: type: array items: $ref: "#/components/schemas/ParameterOption" maxLength: type: number description: Maximum length for text parameters. font: type: string description: Font asset id used by text parameters, when declared. value: description: Current parameter value. oneOf: - type: number - type: boolean - type: string - type: array items: type: number ParameterOption: type: object properties: value: type: string label: type: string