Skip to main content
All routes live under 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 GET and POST on 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. /on on a signal that is already on, or /onair on a studio that is already on air, answers ok:true without applying anything again. Prefer explicit /on and /off over /toggle on devices that cannot show the current state.
  • JSON bodies are compact, use snake_case keys and keep null values. Every body carries ok. Lists sit under items.
  • 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.
  • program lists the titles of the programs on air.
  • outputs holds the same items as /api/v2/outputs, without at. cameras holds {id, name, number, on_air, preview} per camera, variables holds {id, name, value} per variable.
  • A section is null when 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, outputs and variables are null too; macros stays, 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.
  • state is the number behind the status: 0 off air, 1 on air, 2 recording.
  • active is true for on air and for recording.
  • Toggle: off air goes on air, on air or recording goes off air.
  • /studio/set takes value=onair, recording or offair. It also accepts on, off, 0, 1, 2, true and false. Anything else answers 400 invalid_args.
  • While the Core is STARTING, studio control answers 503 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, /off and /toggle work on BOOLEAN and INTEGER signals. INTEGER signals get 1 or 0. Other types answer 400 invalid_args.
  • /set?value= takes true/false (also 1/0, on/off, yes/no) for BOOLEAN, a whole number for INTEGER and any text for STRING.
  • Only enabled INPUT signals can be written. A disabled signal answers 409 signal_disabled, an OUTPUT signal answers 403 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 answers 503 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 no station 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.
The trigger starts the macro and answers straight away. It does not wait for the macro to finish. ?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 carries station: {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}:
  • status is starting, on_air, dormant, fault or offline. offline means the player’s last report is older than 15 seconds.
  • scene is the switched scene on air, or null. variant is {key, cause} or null.
  • playout lists the output’s playout scenes. phase is standby, taking, on_air, returning or holding. bank is the active clip bank, clip the clip on air {key, label, number}, rundown the rundown with the item marked next and the item on air.
  • at, since_at: epoch milliseconds.
  • /scenes lists the scenes the output’s report names: {key, name, kind, on_air}, with kind switched, base or playout. The full scene list of a show is in the show itself, not in the API.
  • GET /api/v2/outputs with ?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 answer 503 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}:
  • core is the switcher cut the camera stands for: the switcher input in value.
  • on_air and preview are the tally: true while the camera’s input is on the program or preview bus of the live switcher. They are null when 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_ready until the Core has loaded the camera list.

Controlling a camera

The Core does not move cameras itself. Every control route sends a CAMERA 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 carries station: {id, name}. {name} is the variable id or its name. Names are matched case-insensitively.

Reading variables

  • value is the stored text, or null when the variable has no value. A BOOLEAN variable stores TRUE or FALSE.
  • The plain value is the text, empty when there is no value. BOOLEAN variables answer 1 or 0.
  • 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, /off and /toggle only work on BOOLEAN variables. Other types answer 400 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.