Switcher

Ergonomic control endpoints for the Switcher input — pick the PGM (on-air) and Preview (next) sources and take Preview to air with a cut, crossfade, or fade-to-black. All of this is also expressible through the generic /api/setproperty (set ForegroundInputName / BackgroundInputName) and /api/invokecommand (CutCommand / CrossfadeCommand / FadeToBlackCommand) — these routes are just a switcher-shaped convenience over the same operations.

Choosing the switcher. A project can contain several switchers. Identify one with target (GUID), targetname (its name), or targettype; discover them with /api/objects/list?type=SwitcherInput. If you omit all three, the project's single switcher is used automatically — but if there is more than one switcher (or none), the call returns 400 and you must name one. Selection is scoped to switchers, so a targetname/targettype that also matches a layer, target, or operator of the same name is not a conflict — only switchers are considered (a layer hosting the switcher is often named after it). A targetname matching more than one switcher is still a 400.

Every change made here is observable in real time via the switcher SSE topic (/api/events/subscribe?topics=switcher) or the dedicated WebSocket Switcher subscription ({ "Type": "Subscribe", "Content": "Switcher" }), both pre-filtered to switchers.

GET /api/switcher/program

Sets the switcher's foreground (PGM, on-air) source.

Parameters:

Parameter Required Description
target / targetname / targettype One of (or omit when the project has exactly one switcher) Which switcher
input One of input/inputid Source input name (a scene counts as an input)
inputid One of input/inputid Source input GUID, resolved to its name (use when names aren't unique)

Both input and inputid only ever match an input (a scene is itself an input) — layers, targets, and operators are deliberately ignored, so a name shared with one of those can never be selected as a switcher source.

Response: 200 OKProgram (PGM) set to: <name>. 400 if the target isn't a Switcher, or neither/both of input/inputid are given, or input/inputid doesn't resolve to an input.

GET /api/switcher/preview

Sets the switcher's background (Preview, next) source. Same parameters and responses as /api/switcher/program, applied to BackgroundInputName.

GET /api/switcher/cut

Hard cut between foreground (PGM) and background (Preview).

Parameters:

Parameter Required Description
target / targetname / targettype One of (or omit when the project has exactly one switcher) Which switcher

Response: 200 OKSwitcher cut performed.. 400 if the target isn't a Switcher or the command can't execute in the current state.

GET /api/switcher/crossfade

Crossfade between foreground and background over the configured crossfade duration.

Parameters:

Parameter Required Description
target / targetname / targettype One of (or omit when the project has exactly one switcher) Which switcher
durationms No Override the crossfade duration (ms, 0–5000) before transitioning

Response: 200 OKSwitcher crossfade performed.. 400 if the target isn't a Switcher or the command can't execute.

GET /api/switcher/fadetoblack

Fade the switcher output to or from black (FTB).

Parameters:

Parameter Required Description
target / targetname / targettype One of (or omit when the project has exactly one switcher) Which switcher
durationms No Override the FTB duration (ms, 0–5000) before fading

Response: 200 OKSwitcher fadetoblack performed.. 400 if the target isn't a Switcher or the command can't execute.

Examples

All examples assume the host localhost:44433; add ?apikey=<key> (or an apikey header) if your instance requires one.

Discover the switchers in the project:

GET /api/objects/list?type=SwitcherInput
→ [ { "Id": "7a2b…", "Name": "Main switcher", "Type": "SwitcherInput" } ]

Classic Preview → Take workflow (queue the next source on Preview, then dissolve it to air):

GET /api/switcher/preview?target=7a2b…&input=Camera 2
GET /api/switcher/crossfade?target=7a2b…&durationms=1000

Hard cut, then fade to black:

GET /api/switcher/cut?target=7a2b…
GET /api/switcher/fadetoblack?target=7a2b…&durationms=500

Put a source straight on air (PGM):

GET /api/switcher/program?target=7a2b…&input=Camera 1

Selecting the switcher different ways — by name, by GUID, or (single switcher only) omit it entirely:

GET /api/switcher/preview?targetname=Main switcher&input=Camera 2
GET /api/switcher/preview?target=7a2b…&input=Camera 2
GET /api/switcher/preview?input=Camera 2          # only one switcher in the project

Selecting the Preview/PGM source by GUID instead of name (handy when input names aren't unique):

GET /api/switcher/preview?target=7a2b…&inputid=9f3c…

Equivalent calls via the generic API (the routes above are just conveniences):

GET /api/setproperty?target=7a2b…&property=BackgroundInputName&value=Camera 2
GET /api/invokecommand?target=7a2b…&command=CrossfadeCommand

Subscribe to switcher changes over SSE (fires for every origin — API, Desktop, script, or the transition animation):

curl -N "http://localhost:44433/api/events/subscribe?topics=switcher"
event: switcher.modified
data: {"targetId":"7a2b…","targetName":"Main switcher","propertyName":"ForegroundInputName","value":"Camera 2"}

event: switcher.modified
data: {"targetId":"7a2b…","targetName":"Main switcher","propertyName":"BlendPercentage","value":62.5}

Subscribe over WebSocket (ws://localhost:8081/) — send, then receive PropertyChanged messages pre-filtered to switchers:

→ { "Type": "Subscribe", "Content": "Switcher" }
← { "Type": "System", "Content": "Switcher subscription confirmed" }
← { "Type": "PropertyChanged",
    "Content": "{\"ObjectId\":\"7a2b…\",\"ObjectName\":\"Main switcher\",\"PropertyName\":\"ForegroundInputName\",\"Value\":\"Camera 2\"}" }