http://{core}:3002/api/v2. Every route also has a plain-text twin under /api/v2/plain/... that answers one flat value. See Plain-text routes.
The examples on this page use http://192.168.1.50:3002 as the Core address and vra_examp1etoken… as a placeholder device token. See Authentication and LAN access for the ways to send a token.
Conventions
- Reads answer
GET. - Control routes answer
GETandPOSTon the same path. Arguments go in the path or the query string, never in a request body, so a control route works from any device that can open a URL. - Control routes are idempotent.
/onon a signal that is already on, or/onairon a studio that is already on air, answersok:truewithout applying anything again. Prefer explicit/onand/offover/toggleon devices that cannot show the current state. - JSON bodies are compact, use snake_case keys and keep
nullvalues. Every body carriesok. Lists sit underitems. - Lookups by id are exact. Macro and automation names are matched case-insensitively. Signal identifiers are matched case-insensitively too (an exact id or identifier match wins first). Output slot keys are matched case-insensitively, output ids exactly. Cameras are found by id, by name (case-insensitively) or by number; angles and variables by id or by name (case-insensitively).
- Responses carry
Cache-Control: no-store.
Query parameters
A control route answers with the state read after the action. With
?wait=0 the body shows the state at the moment the call was accepted, so it can still be the old state.
Arguments are checked before the Core accepts the call, also with ?wait=0: an unknown signal, a disabled or OUTPUT signal, an unknown output, camera, angle or variable, or /on on a variable that is not BOOLEAN answers its error straight away instead of 202.
When a call ends in 504 timeout, an action that is still waiting its turn inside the Core is dropped, so a device that retries after the 504 does not apply it twice. An action that had already started completes.
System
Studio scope. Reads only.GET /api/v2 describes the API as the caller sees it: which features are on, how the caller authenticated (principal) and every endpoint with its methods, path, plain path and parameters.
State snapshot
GET /api/v2/state is the one call to poll when you need several values at once. rev is a fingerprint of the snapshot’s content, not a counter: it changes when anything in the snapshot changes and stays the same while nothing does. Compare it with the last value you saw and fetch the details only when it differs. Do not compare it for larger or smaller.
rev fits in 53 bits, so JavaScript, Companion and browsers hold it exactly. Comparing it as text, for example from the plain twin /api/v2/plain/state, works too.
programlists the titles of the programs on air.outputsholds the same items as/api/v2/outputs, withoutat.camerasholds{id, name, number, on_air, preview}per camera,variablesholds{id, name, value}per variable.- A section is
nullwhen the caller may not read that feature, or when it is not loaded yet. For a device pinned to another station than the one on the studio,automations,outputsandvariablesarenulltoo;macrosstays, like on the macro routes.
Health
healthy is false while the Core starts. Use the plain twin /api/v2/plain/health, which answers ok, for a monitoring check such as Zabbix.
Core
The Core instance state. Studio scope.active is true only for ACTIVE. Toggle turns any other state into ACTIVE. While the Core is STARTING, activate, deactivate and toggle answer 503 not_ready.
reload-config pulls the Core configuration from the cloud again. restart-apps restarts the VRA apps the Core manages on this machine.
Studio
The studio’s on-air status. Studio scope.stateis the number behind the status:0off air,1on air,2recording.activeistruefor on air and for recording.- Toggle: off air goes on air, on air or recording goes off air.
/studio/settakesvalue=onair,recordingoroffair. It also acceptson,off,0,1,2,trueandfalse. Anything else answers400 invalid_args.- While the Core is
STARTING, studio control answers503 not_ready.
Station
The station currently on the studio and its program schedule. Studio scope. Reads only.
Each program is
{id, reference_id, title, start, end, duration_ms, hosts:[{id, name}]}, with start and end in ISO 8601 UTC. previous is the program that was on air last, or null. The program routes answer 503 not_ready until the schedule is loaded.
Signals
The studio’s Signals, read from the Core’s live copy and written through the cloud. Studio scope.{id} is the signal id or its identifier.
One signal in the list, and the body of
GET /api/v2/signals/{id}:
changed_at is in epoch milliseconds. active is true when the value is true, a number other than 0, or a non-empty text.
Writing a signal
/on,/offand/togglework on BOOLEAN and INTEGER signals. INTEGER signals get1or0. Other types answer400 invalid_args./set?value=takestrue/false(also1/0,on/off,yes/no) for BOOLEAN, a whole number for INTEGER and any text for STRING.- Only enabled
INPUTsignals can be written. A disabled signal answers409 signal_disabled, anOUTPUTsignal answers403 read_only. - The Core waits until its copy of the signal shows the new value. No confirmation within 2 s answers
504 timeout. Without a studio MQTT connection the write answers503 not_ready.
Audio Director and Camera Assist
The two system signals have short routes. They behave like/api/v2/signals/audio-director/... and /api/v2/signals/camera-assist/....
A studio without the system signal answers
404 not_found.
Macros
The Macros of the station on the studio, as the Core has loaded them. Studio scope: the station guard does not apply to these routes, a device pinned to another station reaches them too, and the answers carry nostation block. A ?station= you add yourself is still checked, like on every route.
{id} is the macro id or its name. Names with spaces need URL encoding, for example Jingle%20in.
last_trigger_at is in epoch milliseconds, or null when the macro has not run. The macro routes answer 503 not_ready until the Core has loaded the station’s macros.
?wait=0 only changes the status code to 202.
Automations
The Automations of the station on the studio. Station scope. Reads only.{id} is the automation id or its name.
The state is
standby, activated, released or stopped.
Outputs
The Output Players (v2) of the studio, as they report themselves to the Core, and the commands they take. Station scope: these routes go through the station guard and every successful answer carriesstation: {id, name}. Output players of the previous generation are not covered.
{slot} is the output id or the slot key of the output, for example main. Slot keys are matched case-insensitively.
Reading outputs
One output, as in
items and the body of GET /api/v2/outputs/{slot}:
statusisstarting,on_air,dormant,faultoroffline.offlinemeans the player’s last report is older than 15 seconds.sceneis the switched scene on air, ornull.variantis{key, cause}ornull.playoutlists the output’s playout scenes.phaseisstandby,taking,on_air,returningorholding.bankis the active clip bank,clipthe clip on air{key, label, number},rundownthe rundown with the item marked next and the item on air.at,since_at: epoch milliseconds./sceneslists the scenes the output’s report names:{key, name, kind, on_air}, withkindswitched,baseorplayout. The full scene list of a show is in the show itself, not in the API.GET /api/v2/outputswith?station=lists only the outputs of that station.- An output that no player reports answers
404 not_found. Without the studio’s MQTT connection, or when the Core’s MQTT access carries no output topics, the output routes answer503 not_ready.
Controlling an output
Every control route sends one command to the output’s player and waits for its acknowledgement, 2 s by default (?timeout= changes it). The table names the player action each route sends.
?hold= takes 1/0, true/false, on/off or yes/no.
The rundown, clip and graphics routes act on one playout scene. Name it with ?scene=<key>. Without ?scene=, the Core uses the output’s playout scene when it has exactly one. An output with several playout scenes answers 400 invalid_args and lists them in scenes; an output without one answers 404 not_found.
ack is the player’s answer: ok, applied_tick (the tick of the player’s clock the command took effect on, or null) and the player’s own error code in error. With ?wait=0 the call answers 202 with "ack":null and "pending":true.
A refused command keeps the player’s answer in ack and maps its error code onto the API’s:
No answer usually means that no player plays the output: it is dormant or offline. A
504 does not withdraw the command, so a player that answers late can still apply it. Read /api/v2/outputs/{slot}/status before you send the command again.
Besides the station guard, ?station= is also held against the station of the output itself: an output that still plays another station’s show answers 409 station_mismatch, with expected and output_station_id.
Cameras
The studio’s cameras and their angles, with a tally, and the commands that cut to them. Studio scope.{id} is the camera id, its name or its number. Names are matched case-insensitively; a name that two cameras share answers 400 invalid_args, use the id or the number then. The number is the camera’s 1-based position in /api/v2/cameras.
Reading cameras
/api/v2/angles/{id} takes the angle id, or an angle name that only one camera has. Within one camera, use /api/v2/cameras/{id}/angles/{angle}/trigger.
One camera, as in items and the body of GET /api/v2/cameras/{id}:
coreis the switcher cut the camera stands for: the switcher input invalue.on_airandprevieware the tally:truewhile the camera’s input is on the program or preview bus of the live switcher. They arenullwhen the Core cannot tell: the camera’s cut is not a switcher cut, no switcher matches, or the switcher is offline. Keyers and picture-in-picture count as on air on switchers that report them.- An angle has no tally of its own. It cuts to its camera’s input.
- The camera routes answer
503 not_readyuntil the Core has loaded the camera list.
Controlling a camera
The Core does not move cameras itself. Every control route sends aCAMERA commando, which Camera Assist executes, and waits for Camera Assist’s acknowledgement, 5 s by default (?timeout= changes it).
Camera Assist acknowledges as soon as it found the camera or angle, before the PTZ move and framing are done. The answer reports that acknowledgement, not the end of the move.
action is cut, preview or trigger; angle is set for a trigger. ack is Camera Assist’s answer: ok and its own reason. With ?wait=0 the call answers 202 with "ack":null and "pending":true.
A refused command keeps Camera Assist’s answer in ack:
No answer usually means Camera Assist is not running. Read
/api/v2/cameras/{id}/on-air before you send the command again. While the Core starts, before it can send commandos, the control routes answer 503 not_ready.
Moving a camera to an angle without cutting to it, like Go to base position in VRA Cloud, is not available through the API yet.
Variables
The variables of the station on the studio, as the cloud publishes them to the Core. Station scope: these routes go through the station guard and every successful answer carriesstation: {id, name}.
{name} is the variable id or its name. Names are matched case-insensitively.
Reading variables
valueis the stored text, ornullwhen the variable has no value. A BOOLEAN variable storesTRUEorFALSE.- The plain value is the text, empty when there is no value. BOOLEAN variables answer
1or0. - The Core reads the values the cloud publishes for the station. Without the studio’s MQTT connection, or before the first values arrived, the variable routes answer
503 not_ready.
Writing a variable
The Core writes variables through VRA Cloud, which stays the owner of the values. A write therefore needs the Core’s internet connection, also when the panel is on the studio network.
- Only the station’s own user input variables of type TEXT, LONG_TEXT, BOOLEAN, NUMBER or OPTIONS can be written. Other variables, including variables shared by every station of the broadcaster, answer
403 read_only. /on,/offand/toggleonly work on BOOLEAN variables. Other types answer400 invalid_args; use/set?value=.- The cloud checks the value against the variable’s type:
A value can be at most 255 characters, or the character limit set on a text variable. A value that does not fit answers
400 invalid_args.
value is the value as the cloud stored it. confirmed is true when the Core’s copy showed the new value within 2 s. A write the cloud accepted answers ok:true also when confirmed is false; the value then arrives a moment later. With ?wait=0 the call answers 202 with "pending":true and the value as sent.
The Core sends the station it is on with every write, and the cloud refuses the write when another station holds the studio by then. See Station safety.
Legacy routes
The routes of Core v1, under/api/..., are listed on Legacy routes.