# OnTheAir Video REST API

OnTheAir Video's REST API allows you to retrieve OTAV's status, change playlists, do controls of the playback and playing with the DGO. Also note that this REST API is not final, it's a first draft and there could be changes in the future when it is finalised.

This API is meant to be RESTful, then, using different verbs on requests leads to different behaviour on request processing.
In general manner, consider theses verbs to have the described behaviour:

GET -> Retrieve data of a processable entity.

POST -> Create a new entity.

PUT -> Update a specified entity.

DELETE -> Delete an entity.

When you modify or retrieving data, be sure to handle properly the return code that is returned by the API as it indicates if the operation was successfull or not.
For POST & PUT requests you MUST supply the 'Content-Type' header with value 'application/json'.
Here is a short list common codes returned by the API:

Code | Meaning | Description
--- | --- | ---
200 | OK | The request was succesfully processed.
201 | Created | A new resource has been created on server side.
202 | Accepted | The resquest was accepted but was not processed.
400 | Bad Request | The resquest was not well formed.
401 | Unauthorized | The request needs an access token to proceed. See Authorization
403 | Forbidden | The token provided doesn't have sufficient privileges/permissions. See Authorization
404 | Not found | The resquest couldn't be processed. The path is not recognized.
422 | Unprocessable entity | The resquest is well formed but is sementically incorrect

To know if your request succeded; command, update, create and delete requests are followed with this kind of response:

#### Command Response Object:

    {
      "success" : boolean,
      "error" : string OPTIONAL
    }

"success": Indicates if the request was accepted and processed or not by OnTheAir Video.
"error": In case of success false, indicates what was wrong when processing the request.

NOTE:
OPTIONAL marked parameters indicates that these parameters can be or not be present in the response object, this is due to internal logics.
However for requests that require a body, like PUT or POST, it means that it can be passed but they are not mandatory.

# Authorization

Since playlists can play sensitive content at a time, an authorization mechanism will be required if you decide to enable it in OnTheAir Video's preferences. (General -> HTTP Server -> Require Authentication).

If this feature is enabled, it implies that you have to login with one of the registred user defined in OnTheAir Video and use the token received. In case not, you can ignore this section.

Each user has an access level, it defines how much control you have.
Theses are described as follows:

# | Title | Description
--- | --- | ---
1 | Read Only | You'll only be able to retrieve informations but not modifying it.
2 | Modify Playlists | You'll only be able to modify playlists.
3 | Modify And Control Playlists | You'll be able to modify playlist, control the playback and DGO.
4 | Full Access | You'll be granted to execute all commands (admin privileges).

In order to make request you must first login with the following request:

    PUT http://localhost:8081/authorize

    {
      "username": string, REQUIRED
      "password": string REQUIRED
    }

Response:

    {
      "token": string, OPTIONAL
      "error": string, OPTIONAL
      "level": number
    }

The token received MUST be added in the query parameter of each request you make to OTAV.
The level property is indicating the level granted to the logged user as defined in the table above.

NOTE:

- The token will be invalid if you relaunch OnTheAir Video and thus you will have to remake the process again to obtain a new valid token.
- In case of token invalidity, requests will send back a 401 error code
- In case of not token provided, requests will send back a 403 error code

# Unique id - index or display name ?

Each playlist can be addressed using either its unique_id or its index.

- The unique_id of a playlist represents its display name but may be altered to ensure it is unique among other playlists opened. It will not change unless you reanme the playlist.
- The index is the position of the playlist in opening order. The index '0' would represent the first playlist opened, then '1' would represent the second and so on.

Each clip can be addressed using either its unique_id, its index or eventually its display name.

- The unique_id is the safest way as it will not change and remain unique, but you have to request first its value before being able to send arguments.
- The index of a clip is the (zero based) position of a clip, or the order in which the playlists are displayed on screen (0 is the first playlist open, 1 is the second playlist open, etc...)
- The display name is the name given to a clip inside OnTheAir Video. But pay attention that if you have mutiple clips with the same name, it will always address to the first one (in index order). Should be used as a convenience way or when you are sure the name is unique witthin the playlist.

Each action can only be addressed by its unique_id.

# Getting information about the OnTheAir Video Instance

    GET http://localhost:8081/info

Response:

#### Info Response Object:

    {
      "time_zone": string,  eg: "Europe\/Brussels"
      "is_player_capable": boolean
      "computer_name": string,  eg: "Admin's computer"
      "application_name": string,  eg: "OnTheAir Video"
      "application_build_number": string,  eg: "402090"
      "mac_os_version": string,  eg: "14.1"
      "application_in_demo": boolean
      "application_version": string,  eg: "4.2"
      "requires_authentication": false,
      "name": string,  eg: "OTAV admin"
      "DGO_option": boolean
    }

# Getting the Playback status

## Get the "generic" playback status of OnTheAir Video

    GET http://localhost:8081/playback/playing

Response:

#### Playback Status Response object:

    {
      "current_date_time" : string, eg: "2023-03-08 12:53:03"
      "is_playing" : boolean,
      "is_paused" : boolean,
      "is_locked" : boolean,
      "item_index" : number, OPTIONAL * eg. 3
      "item_display_name" : string, OPTIONAL * eg. "My Movie Name"
      "item_duration" : number, OPTIONAL * eg. 233.3199
      "item_elapsed" : number, OPTIONAL * eg. 152.5200
      "item_filename" : string, OPTIONAL * eg. "MyMovie1"
      "item_media_url" : string, OPTIONAL * eg."file:\/\/\/Volumes\/Videos\/MyMovie1.mov"
      "item_remaining" : number, OPTIONAL * eg. 65.03
      "item_path" : string, OPTIONAL * eg. "/Volumes/Videos/MyMovie1.mov"
      "item_playback_status" : string, OPTIONAL * playback mode
      "item_unique_id" : string, OPTIONAL * eg. "666AD1EF-54C6-4A63-A67B-501C57E6080F" or "" if not playing
      "live_subtitling" : boolean, OPTIONAL *
      "next_live_display_name" : string, OPTIONAL * eg. "My Live Name"
      "next_live_unique_id" : string, OPTIONAL * eg. "666AD1EF-54C6-4A63-A67B-501C57E6080F" or "" if no live in currently playing playlist
      "playback_status" : string, OPTIONAL * eg. "Playing", "Stopped", "Pause"
      "playlist_display_name": string, OPTIONAL * Playing playlist's name
      "playlist_duration" : number, OPTIONAL * eg. 233.3199
      "playlist_elapsed" : number, OPTIONAL * eg. 233.3199
      "playlist_index": number, OPTIONAL *  Playing playlist's index (in opening order)
      "playlist_remaining" : number, OPTIONAL * eg. 80.7999
      "playlist_unique_id": string, OPTIONAL * Playing playlist's unique ID
      "remaining_time_until_next_live" : number, OPTIONAL * eg. 233.3199
    }

* Thoses fields will only appear if a playlist is playing

## Get the playback status of a playlist

With the following request, you will get a few info about the status of the playlist, and more. See playlist section for more controls.

    GET http://localhost:8081/playlists/{n}/playing

Response: Command Response Object

## Get the playback status of a clip

With the following request, you will get a few info about the status of the clip, and more. See clips section for more controls.

    GET http://localhost:8081/playlists/{n}/items/{m}/playing

Response: Command Response Object

# Live Sources

Retrieve the list of Live sources available for that OnTheAir Video.

    GET http://localhost:8081/live_sources

Response (array):

#### Live Response Object:

    [
      {
      "display_name" : string,  The name of the Live source. eg: "Live Source"
      "enabled" : boolean,  Wether the live source is enabled or not.
      "input_description" : string,  The name of the input used for the live source. eg: "UltraStudio 4K Mini"
      "input_unique_id" : string,  The unique id of the input used for the live source. eg: "A15G3FJ5YUI78"
      }
    ]

Change the settings of live sources.

    PUT http://localhost:8081/live_sources

Body (array):

#### Live Body Object:

    [
      {
      "display_name" : string, OPTIONAL *  The name of the Live source. eg: "Live Source"
      "enabled" : boolean, OPTIONAL *  Wether the live source is enabled or not.
      }
    ]

# Virtual Sources

Retrieve the list of Virtual sources available for that OnTheAir Video. Virtual Sources are only available with the traffic option.

    GET http://localhost:8081/virtual_sources

Response (array):

#### Virtual Sources Response Object (Example):

    [
      {
         "before_action" : {
           "is_outpoint_clamped" : false,
           "is_valid" : true,
           "position_timecode" : "00:00:00:00",
           "version" : 2,
           "position" : 0,
           "template_id" : ":Do Nothing",
           "parameters" : {

           },
           "is_inpoint_clamped" : false,
           "unique_id" : "586A8408-27B4-40EA-8B26-B12C13B80F85",
           "is_offline" : false,
           "name" : "Do Nothing",
           "position_type" : "fromStart"
         },
         "default_clip_end_behaviour" : 2,
         "version" : "2",
         "is_live_source" : true,
         "switching_action" : {
      	 "is_outpoint_clamped" : false,
      	 "is_valid" : true,
      	 "position_timecode" : "00:00:00:00",
      	 "version" : 2,
      	 "position" : 0,
      	 "template_id" : "AppleScript:Execute AppleScript",
      	 "parameters" : {
      	   "AppleScript Name" : "U_GRID",
      	   "Parameter" : ""
      	 },
      	 "is_inpoint_clamped" : false,
      	 "unique_id" : "105F6389-5301-4854-8D21-AED719F71E1C",
      	 "is_offline" : false,
      	 "name" : "Execute AppleScript",
      	 "position_type" : "fromStart"
         },
         "source_name" : "GRID",
         "default_duration" : 600,
         "display_name" : "GRID",
         "gpi_trigger_input" : 0,
         "live_input_name" : "Live Source",
         "is_default" : false,
         "end_action" : {
      	 "is_outpoint_clamped" : false,
      	 "is_valid" : true,
      	 "position_timecode" : "00:00:00:00",
      	 "version" : 2,
      	 "position" : 0,
      	 "template_id" : ":Do Nothing",
      	 "parameters" : {

      	 },
      	 "is_inpoint_clamped" : false,
      	 "unique_id" : "2F13B026-1042-4DC7-824B-5E5B7F4F9243",
      	 "is_offline" : false,
      	 "name" : "Do Nothing",
      	 "position_type" : "fromStart"
         },
         "start_action" : {
      	 "is_outpoint_clamped" : false,
      	 "is_valid" : true,
      	 "position_timecode" : "00:00:00:00",
      	 "version" : 2,
      	 "position" : 0,
      	 "template_id" : ":Do Nothing",
      	 "parameters" : {

      	 },
      	 "is_inpoint_clamped" : false,
      	 "unique_id" : "75CD140C-1CB9-4DA9-9083-DA3D3C78C1FD",
      	 "is_offline" : false,
      	 "name" : "Do Nothing",
      	 "position_type" : "fromStart"
         }
       }
    ]

# Getting thumbnails of video output

Retrieve the thumbnails of the video output. Allows to have a small preview remotely.

    GET http://localhost:8081/playback/thumbnail

Response: JPEG data

# Playback Controls

## Types of controls

You have three ways to control the playback. Depending on what you want to achieve, you can:

- address "playback" and NOT specify a playlist, nor a clip. In this case, the playing playlist (or the front one if no playlist is playing) will be the one answering your requests.
- specify the playlist you want to control (by using its index or unique ID), but without specifying a clip. In this case you can start the playback on a specific playlist, and the first clip (or the playing one) in the playlist will be controlled
- specify both the playlist you want to control, as well as the clip (by using their index or unique ID). That's the way to start playing a specific clip in a specific playlist.

NOTE:
When using playback commands (play or pause) by specifying a clip, the following parameters can be passed in the URL to set the playback's play head at a precise timecode:

    "position_relative_timecode": string, "HH:MM:SS:FF" -" timecode position from the clip's start
    "position_media_timecode": string, "HH:MM:SS:FF" - absolute timecode in the media
    "position_relative_seconds": number, Position after x seconds from the media's beginning

Below, you will find the 3 types of controls (generic, per playlist or per clip). Depending on the type of command, you may have just one control possible. Or in some cases, all three are possible but will produce the same result. For example, if you aska a "generic" stop, it will do a stop the same way as if you specify a clip and/or a playlist.

## The basic - play/stop/pause

### Play

Start playing at the beginning of the front playlist:

    GET http://localhost:8081/playback/play

Start playing at the beginning of the specified playlist:

    GET http://localhost:8081/playlists/{n}/play

Start playing at the the specified clip of the specified playlist (see above to also specify an offset to start the clip):

    GET http://localhost:8081/playlists/{n}/items/{m}/play

Response: Command Response Object

### Stop

All three requests will stop the playback, whatever playlist is playing.

    GET http://localhost:8081/playback/stop

    GET http://localhost:8081/playlists/{n}/stop

    GET http://localhost:8081/playlists/{n}/items/{m}/stop

Response: Command Response Object

### Pause

If a playlist is playing or paused, the first 2 requests will control the "playing or paused" playlist: pause the playback if playing or resume it if paused. If nothing is playing, the first request will do a pause on the front playlist, on the selected clip if any. The second request will specify on which playlist the pause should be done.

    GET http://localhost:8081/playback/pause

    GET http://localhost:8081/playlists/{n}/pause

Even if something is playing or paused, the following request will ask to pause the clip. Never to resume it.

    GET http://localhost:8081/playlists/{n}/items/{m}/pause

Response: Command Response Object

### Resume

As the pause control can either do a pause or resume, if you want to be sure to do a resume, you should use this one, instead of the pause... Whatever three requests, it will do a resume of the paused clip if any, in whatever playlist.

    GET http://localhost:8081/playback/resume

    GET http://localhost:8081/playlists/{n}/resume

    GET http://localhost:8081/playlists/{n}/items/{m}/resume

Response: Command Response Object

## Skip to previous/next

### Skip to next

All three commands will do a skip to next on the playing playlist... Nothing will happen if nothing is played or paused. Note that they will return the "last position", which is the elapsed time (in seconds) of the previously playing clip

    GET http://localhost:8081/playback/skip_next

    GET http://localhost:8081/playlists/{n}/skip_next

    GET http://localhost:8081/playlists/{n}/items/{m}/skip_next

You can also indicate if the skip to next should only be done if the currently playing item is a live (useful to exit a live, but ignore if you are already out of the live).

    GET http://localhost:8081/playback/skip_next?live_only=1

#### Skip To Next Response Object:

    {
      "success": boolean,
      "last_position": number Indicates the elapsed time (in seconds) of the previously playing clip .
    }

### Skip to previous

All three commands will do a skip to previous on the playing playlist... Nothing will happen if nothing is played or paused.

    GET http://localhost:8081/playback/skip_previous

    GET http://localhost:8081/playlists/{n}/skip_previous

    GET http://localhost:8081/playlists/{n}/items/{m}/skip_previous

Response: Command Response Object

## Play next

### Play next (clip)

Set which clip will play once the current one is done playing (or when doing a skip to next). This request only works when specifying a playlist and a clip.

    GET http://localhost:8081/playlists/{n}/items/{i}/play_next

Response: Command Response Object

### Clear play next (clip)

All three requests will clear the clip that was previously set as the next to play.

    GET http://localhost:8081/playback/clear_next

    GET http://localhost:8081/playlists/{n}/clear_next

    GET http://localhost:8081/playlists/{n}/items/{m}/clear_next

Response: Command Response Object

## Other controls

### Cue trigger

Emulates the "space bar". If you want to do as if you were using the space bar on your computer...

    GET http://localhost:8081/playback/cue_trigger

Response: Command Response Object

### GPI trigger

Emulates a "GPI input" received trigger. You must specify the input number. This will do a skip to next if a "GPI trigger" for the specified input is set on the currently playing clip (cf clip attributes inspector)

    GET http://localhost:8081/playback/gpi_trigger?input=1

Response: Command Response Object

### Join in progress

This feature is only available if you have the traffic option, will use the theoretical start date/time of the playlist and clip in order to start playing what was scheduled to play. The first request will do a join in progress, in the following order, on: the playing playlist; if no playlist is playing, the playlist of the day; if no playlist is playing, nor a playlist of the day is open, the front playlist

    GET http://localhost:8081/playback/join_in_progress

The following two requests will do a join in progress on the specified playlist.

    GET http://localhost:8081/playlists/{n}/join_in_progress

    GET http://localhost:8081/playlists/{n}/items/{m}/join_in_progress

Response: Command Response Object

# Working with Playlists

## Get info about a playlist:

Here is an example of request that you can use in a simple browser, to get the information about the playlist {n}:

    GET http://localhost:8081/playlists/{n}

Response:

#### Playlist Response Object:

    {
      "unique_id" : string, name of the document made unique
      "path" : string, OPTIONAL eg. "/Volumes/Videos/MyPlaylist.xpls"
      "name" : string, eg. "MyPlaylist"
      "loop": boolean,
      "chain": boolean,
      "cue": boolean,
      "shuffle": boolean,
      "is_folder_based": boolean,
      "folder_based_path": string OPTIONNAL eg. "/Volumes/Videos/"
      "total_items" : number, eg. 57 OPTIONAL only if 'items' is not present
      "player_description" : string, eg. "Virtual Output (1080i 59.94)"
      "duration" : number, eg. 1800.7999
      "duration_string" : string, eg. "00:30:02" HH:MM:SS
      "preset_duration": number, eg. 1800
      "preset_duration_string": string, eg. "00:30:00" HH:MM:SS
      "start_time_offset": string, eg. "00:30:00" HH:MM:SS
      "enable_clocked_items": boolean,
      "is_front" : boolean,
      "has_on_air_item": boolean,
      "items": array Playlist Item Response Object OPTIONAL Pass "include_items=true" in query parameters
    }

NOTE:
The "preset_duration" parameter is a theoretical value that indicates the desired duration of the playlist althougth the duration may or may not be equal to this one.

## Get various info from a playlist

The following request will get the list of items in playlist.

    GET http://localhost:8081/playlists/{n}/items

Response: array Playlist Item Response Object (Array)

The following request will get the thumbnails of all the items in a playlist.

    GET http://localhost:8081/playlists/{n}/thumbnails

Response (Array):

#### Thumbnail Response Object:

    [
      {
        "unique_id" : string, name of the document made unique
        "thumbnail" : JPEG data
      }
     ]

Get the start times and overruns of items in a playlist. It is usefull when you don't want to ask the whole playlist if a duration has changed

    GET http://localhost:8081/playlists/{n}/start_times

Response:

    {
      {
        "303315D0-5D02-4610-B155-CCC7F5AC83E9" : {
        "start_time" : 60929,
        "overrun_underrun" : 0
      },
        "90B89FE6-1A84-4291-93AC-56A5A0F79C81" : {
        "start_time" : 60809,
        "overrun_underrun" : 0
      }
    }

Retrieve a list of items (their unique IDs) that don't match the "theoreticalStartDate" of the playlist

    GET http://localhost:8081playlists/{n}/out_of_time_range_items

Response:

    {
      "7EC74545-83C5-475A-B97E-8D64AF4D3A20",
      "B0C11EC0-0159-4C15-8D0A-C83ABE687A6F"
    }

Retrieve a list of items that have start date/time that are not chronologicaly ordered with the previous clip that has a start date/time

    GET http://localhost:8081playlists/{n}/not_chronological_items

Response:

    {
      "7EC74545-83C5-475A-B97E-8D64AF4D3A20",
      "B0C11EC0-0159-4C15-8D0A-C83ABE687A6F"
    }

## Create an empty playlist

This option is only available when you have the "traffic" option, as the playlist will be created in the folder selected for the schedule.

    POST http://localhost:8081/playlists/{NAME}

Response: Playlist Object

## Delete all clips of a playlist

    DELETE http://localhost:8081/playlists/{n}/items

Response: Command Response Object

NOTE:
Trying to delete all clips of playing playlist will return an error.

## Close a playlist

Close the playlist with specified ID.
Warning ! Use this command with care as some other remote user will no longer have access to the playlist after it is closed.

    GET http://localhost:8081/playlists/{id}/close

Response: Command Response Object

# Working with clips in playlists

## Get the info of a specific item in a playlist

The following request will get the info of the item {m} in playlist {n}. You can use the playlist index, or a unique ID (see above), same thing for the clip, you can use either the index or the unique ID.

    GET http://localhost:8081/playlists/{n}/items/{m}

#### Playlist Item Response Object:

    {
      "unique_id" : string, OPTIONAL * eg. "666AD1EF-54C6-4A63-A67B-501C57E6080F"
      "clip_type" : enum clip_type,
      "filename" : : string, eg. "MyMovie1.mov"
      "name" : string, eg. "MyMovie1"
      "url" : string, eg. "/Users/admin/Documents/MyMovie1.mov" REQUIRED for FILE or STREAM
      "external_item_url" : string, eg. "http:\/\/192.168.0.33:8081\/media\/items\/MyMovie1.mov"  OPTIONAL
      "media_browser_item_unique_id" string, eg. "MyMovie1"  OPTIONAL
      "video_codec" : string, eg. "H.264"
      "audio_codec" : string, eg. "AAC"
      "live_source_name": string eg. "Live Source 2"  OPTIONAL
      "is_streamed": boolean, Indicates if the stream is a remote file or not.
      "is_valid" : boolean,
      "validation_status" : string, validation status
      "validation_error" : string, validation error
      "is_offline": boolean, will always set to false for a LIVE or STREAM clip.
      "is_disabled" : boolean,
      "is_locked" : boolean,
      "last_modification_date" : string eg. ""2024-05-13T11:56:08.597Z"",
      "relative_start_time" : number, eg. 9.902 (in seconds)
      "relative_start_timecode" : string, eg. "00:11:34" HH:MM:SS
      "displayed_start_time" : number " eg. "679" (in seconds),
      "theoretical_absolute_start_time" : number,	eg. 13.532 (in seconds)
      "timed_start_date" : : string eg. ""2024-05-13T11:56:08.597Z"",
      "displayed_start_timecode" : string,	eg. "00:00:00" HH:MM:SS
      "overrun_underrun" : number, eg. "60" (in seconds)
      "first_frame_number" :  number, eg. "9000" (in frame number)
      "last_started_date": string eg. ""2024-05-13T11:56:08.597Z"",
      "start_transition_name": string eg. "Push - Down",
      "start_transition_duration" : number, eg. "1" (in seconds)
      "has_previous_item_mix_point" : boolean,
      "previous_item_mix_point" : number, eg. 1.000 (in seconds) OPTIONAL
      "has_in_point" : boolean,
      "in_point" : number, eg. 9.902 (in seconds) OPTIONAL
      "has_out_point" : boolean,
      "out_point" : number, eg. 59.000 (in seconds) OPTIONAL
      "has_next_item_mix_point" : boolean,
      "next_item_mix_point" : number, eg. 1.000 (in seconds) OPTIONAL
      "media_file_duration" : number, eg. "600.000" (in seconds)
      "duration" : number, eg. "600.000" (in seconds)
      "duration_timecode" : string, eg. "00:10:00" HH:MM:SS
      "theoretical_duration" : number, eg. "600.000" (in seconds)
      "chained_playback_duration" : number eg. "600.000" (in seconds)
      "chained_playback_duration_timecode" :  string, eg. "00:10:00" HH:MM:SS
      "non_chained_playback_duration" : eg. "600.000" (in seconds)
      "non_chained_playback_duration_timecode" :  string, eg. "00:10:00" HH:MM:SS
      "graphics_attributes" : array,
      "display_rect" : array,
      "media_display_size" : array
      "gpi_trigger_input" : number,
      "is_cued_as_next" : boolean, OPTIONAL
      "logo_filename" : string, eg. "MyLogo"
      "closed_captions" : array <string> array closed_captions_types, OPTIONAL
      "playback_mode" : string, playback mode
      "actions" : array action,
      "include_in_auto_check" : boolean,
      "playback_status": string, eg. "stopped" GET only
      "input_midi_message" : array,
      "resize_mode_option" : string, eg. "Default"
      "proxy_url" : string, eg. "http:\/\/127.0.0.1:8081\/MyMovie1.mp4"
      "thumbnail_url" : string, eg. "http:\/\/127.0.0.1:8081\/MyMovie1.jpg"
      "epg_tag_unique_id" : string, eg. "MYEPGTAG"
      "resize_mode": string, resize mode
      "finder_label_index" : number,  OPTIONAL
      "finder_label_description" : string, eg. "Red" OPTIONAL
      "segment_number" : number,
      "virtual_clip" : boolean,  OPTIONAL
      "virtual_source" : string, eg. "REC-VS"  OPTIONAL
      "content_type" : string, eg. "CM"  OPTIONAL
      "isci_code" : string, eg. "MMS15OURVOICE"  OPTIONAL
      "reconcile_id" : string, eg. "0003-T"  OPTIONAL
      "tv_rating" : string, eg. "-16"  OPTIONAL
      "remote_change_id" : string, eg. "125A2F9B-2774-4929-93BC-9311C672873A"  OPTIONAL
      "languages" : array <string>
      "premultiply_by_alpha" : boolean,
      "can_be_inspected" :  boolean, OPTIONAL
      "audio_volume" : number "0" is muted, "1" is 0dB, "2" is 6dB,
      "logo_enabled" : boolean,
      "reverse_field_order" : boolean,
      "frames_per_second" : number,
      "drop_frame" : boolean,
    }

* : if the unique_id property is not present it means that the item is still in the playlist but will be further deleted and thus cannot be accessed.
NB: If 'clip_type' is a comment item, he will only have 'unique_id', 'name', 'clip_type' & 'segment_number' properties.

## Get the thumbnail of a clip

The following request will get the thumbnail of the item {m} in playlist {n}. You can use the playlist index, or a unique ID (see above), same thing for the clip thumbnail, you can use either the index or the unique ID.

    GET http://localhost:8081/playlists/{n}/thumbnails/{m}

#### Playlist's item object response:

    {
      "unique_id":"64191780-B968-454E-A5ED-A61CC85F170D",
      "thumbnail":"JPEG data"
    }

## Get the thumbnails

Retrieve the thumbnails of all the clips in the playlist

    GET /playlists/{n}/thumbnails

Response: array Playlist Response Object
Retrieve the thumbnail of a clip (in JSON with Base64 data)

    GET /playlists/{n}/thumbnails/{i}

Response: array Playlist Item Response Object
Retrieve the thumbnail of a clip (in JPEG)

    GET /playlists/{n}/items/{i}/thumbnail

Response: JPEG data

## Check for missing clips / validate

The following request will validate the clips within a playlist. A validation will open the file, read the header to retrieve the codec and format. You can either ask it for the whole playlist, or for a specific clip in the playlist. You can use the playlist index, or a unique ID (see above), same thing for the clip, you can use either the index or the unique ID.
There are 2 types of check:

- A "simple" validation, "check for missing clips": we will compare the modification date of the file, and what we have stored in the playlist, and only validate the clip if the 2 are different. This is mainly useful when asking a whole playlist to check if clips have been modified or became online/offline
- A "forced" validation: we will not check the modification date and force to validate the clip. This is to be used with care as it uses some resources (we have to open the file to get its info).

### Check for missing clips

For the whole playlist:

    GET http://localhost:8081/playlists/{n}/validate

Response: Command Response Object

For a specific clip:

    GET http://localhost:8081/playlists/{n}/items/{m}/validate

Response: Command Response Object

### Force a validation

For a specific clip (it is not recommended to do it on a whole playlist as it will use resources):

    GET http://localhost:8081/playlists/{n}/items/{m}/validate?force=1

Response: Command Response Object

## Update playlist's clip

All properties of a clip can be changed but here are the most common to be changed.
WARNING: if you change some properties that doesn't appear on this list, it might lead to unwanted UI behaviour. For example, we do not recommend sending things as "Modification date", durations, etc... as these will be calculated by OnTheAir Video directly depending on the media that it has. Note that this command will also automatically save the playlist once it has loaded the new values.

    PUT http://localhost:8081/playlists/{n}/items/{m}

Body:

    {
      "name" : string, OPTIONAL eg. "MyMovie1"
      "url" : string, OPTIONAL eg. "/Volumes/Movies/MyMovie.mov" (ONLY FOR FILE or STREAM)
      "live_source_name" : string, OPTIONAL eg. "Live Source 2" (ONLY FOR LIVE)
      "duration" : number, OPTIONAL eg. 679.902 (in seconds) (ONLY FOR LIVE or STREAM)
      "playback_mode" : string, playback_mode OPTIONAL
      "has_in_point" : boolean, OPTIONAL
      "in_point" : number, OPTIONAL eg. 9.902 (in seconds)
      "has_out_point" : boolean, OPTIONAL
      "out_point" : number, OPTIONAL eg. 59.000 (in seconds)
      "start_transition_name": string OPTIONAL
    }

Response: Playlist Item Response Object

## Change playlist content & properties

WARNING: You MUST send the entire items list, the content will be reflected, the additional items wil not be added nor removed. To add or delete items, please use POST/DELETE requests

    PUT http://localhost:8081/playlists/{n}/items/

Body: Playlist Object
Response: Command Response Object

## Create a clip

    POST http://localhost:8081/playlists/{n}/items

If you want to create a clip at a specific index {m}, you can use the following:

    POST http://localhost:8081/playlists/{n}/items/{m}

Body:

    {
      "clip_type" : enum <clip_type>, REQUIRED
      "url" : string, REQUIRED ONLY FOR FILE or STREAM eg. "/Volumes/Movies/MyMovie.mov"
      "live_source_name" : string, REQUIRED ONLY FOR LIVE eg. "Live Source 	2"
      "duration" : number, REQUIRED ONLY FOR STREAM OR LIVE eg. 679.902 (in seconds)
      "name" : string, OPTIONAL eg. "MyMovie1"
      "playback_mode" : string, playback_mode OPTIONAL
      "has_in_point" : boolean, OPTIONAL
      "in_point" : number, OPTIONAL eg. 9.902 (in seconds)
      "has_out_point" : boolean, OPTIONAL
      "out_point" : number, OPTIONAL eg. 59.000 (in seconds)
      "start_time" : number, OPTIONAL
    }

Response: Playlist Item Response Object
Examples:

### File based clip body:

    {
      "clip_type" : 0,
      "url" : "/Volumes/Movies/MyMovie.mov"
    }

### Comment:

    {
      "clip_type" : 3,
      "name" : "Start Section"
    }

### Live clip body:

    {
      "clip_type" : 4,
      "live_source_name" : "Live Source 2",
      "duration" : 1800,
      "name" : "Live"
    }

### Stream clip body:

    {
      "clip_type" : 5,
      "url" : "rtmp://192.168.0.10:1935/live/mystream",
      "duration" : 1800
    }

## Delete a specific clip of a playlist

    DELETE http://localhost:8081/playlists/{n}/items/{m}

Response: Command Response Object

NOTE:
Trying to delete a playing clip of a playlist will return an error.

# Working with the currently playing clip

To address the currently playing clip, instead of communicating "through" the playlist, you go through the "playback" command. With the currently playing item, you can do all the same requests you do to the playlist items.

## Get the info of the currently playing clip

The following request will get the info of the currently playing clip.

    GET http://localhost:8081/playback/current_item

Response: Playlist Item Response Object

# Working with Actions

WARNING: There is a major change with Actions in OnTheAir Video 4.2. In previous versions, Actions were only AppleScripts. Now they can be AppleScript, or other direct actions that allow you to control various equipments. Make sure to check the changes, and when sending or receiving requests to a OnTheAir Video, check the version of the server (using GET /info), to make sure you are compatible.

## Get available the list of available actions

The following request will retrieve the available actions on the server. You can use them to update your clip's available actions, and know the possible values for each.

    GET http://localhost:8081/actions

Response (example):

    [
      {
      "is_available" : false,
      "is_user_action" : false,
      "group_name" : "",
      "name" : "Do Nothing",
      "unique_id" : ":Do Nothing",
      "should_run_on_backup" : true
      },
      {
      "parameters" : [
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 128,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Source Index",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 7,
      "is_visible_in_description" : true,
      "default_value" : false,
      "name" : "Transition",
      "index" : 1
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "ATEMSwitchByIndex",
      "unique_id" : "ATEM:ATEM Program Switch (by index)",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "ATEM",
      "name" : "ATEM Program Switch (by index)"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "Source Name",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 7,
      "is_visible_in_description" : true,
      "default_value" : false,
      "name" : "Transition",
      "index" : 1
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "ATEMSwitchByName",
      "unique_id" : "ATEM:ATEM Program Switch (by name)",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "ATEM",
      "name" : "ATEM Program Switch (by name)"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 100,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : "1",
      "name" : "Macro Index",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "runATEMMacroAtIndex",
      "unique_id" : "ATEM:Run Macro At Index",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "ATEM",
      "name" : "Run Macro At Index"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "Macro Name",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "runATEMMacroWithName",
      "unique_id" : "ATEM:Run Macro With Name",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "ATEM",
      "name" : "Run Macro With Name"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "BUGEnd",
      "BUGStart",
      "LowerThird",
      "RollBreak"
      ],
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "AppleScript Name",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 2,
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "Parameter",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "executeAppleScript",
      "unique_id" : "AppleScript:Execute AppleScript",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "AppleScript",
      "name" : "Execute AppleScript"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8"
      ],
      "is_visible_in_description" : true,
      "default_value" : "1",
      "name" : "Output Number",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "gpiPulseOutput",
      "unique_id" : "GPI:GPI Pulse Output",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "GPI",
      "name" : "GPI Pulse Output"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8"
      ],
      "is_visible_in_description" : true,
      "default_value" : "1",
      "name" : "Output Number",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "gpiSetOutputOff",
      "unique_id" : "GPI:GPI Set Output OFF",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "GPI",
      "name" : "GPI Set Output OFF"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8"
      ],
      "is_visible_in_description" : true,
      "default_value" : "1",
      "name" : "Output Number",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "gpiSetOutputOn",
      "unique_id" : "GPI:GPI Set Output ON",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "GPI",
      "name" : "GPI Set Output ON"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "LowerThird",
      "BUG",
      "Coming_Next",
      "Box_Right"
      ],
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "Project Name",
      "index" : 0
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "startDGOProject",
      "unique_id" : "Graphics:Start DGO Project",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "Graphics",
      "name" : "Start DGO Project"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "LowerThird",
      "BUG",
      "Coming_Next",
      "Box_Right"
      ],
      "is_visible_in_description" : true,
      "default_value" : "",
      "name" : "Project Name",
      "index" : 0
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "stopDGOProject",
      "unique_id" : "Graphics:Stop DGO Project",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "Graphics",
      "name" : "Stop DGO Project"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "note_on",
      "note_off",
      "after_touch",
      "program_change",
      "control_change",
      "channel_pressure",
      "pitch_wheel",
      "non_musical"
      ],
      "is_visible_in_description" : true,
      "default_value" : "program_change",
      "name" : "Message Type",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 255,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Channel",
      "index" : 1
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 255,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "Param 1",
      "index" : 2
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 255,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "Param 2",
      "index" : 3
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "sendMIDIMessage",
      "unique_id" : "MIDI:Send MIDI Message",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "MIDI",
      "name" : "Send MIDI Message"
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiCueNextClip",
      "unique_id" : "Playback:Cue Next Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Cue Next Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiCueSelectedClip",
      "unique_id" : "Playback:Cue Selected Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Cue Selected Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiPause",
      "unique_id" : "Playback:Pause",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Pause",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiPlayNextClip",
      "unique_id" : "Playback:Play Next Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Play Next Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiPlaySelectedClip",
      "unique_id" : "Playback:Play Selected Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Play Selected Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiReCueCurrentClip",
      "unique_id" : "Playback:Re-Cue Current Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Re-Cue Current Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiRePlayCurrentClip",
      "unique_id" : "Playback:Re-Play Current Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Re-Play Current Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiReleasePause",
      "unique_id" : "Playback:Release Pause",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Release Pause",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiSelectNextClip",
      "unique_id" : "Playback:Select Next Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Select Next Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiSelectNextPlaylist",
      "unique_id" : "Playback:Select Next Playlist",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Select Next Playlist",
      "should_run_on_backup" : false
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiSelectPreviousClip",
      "unique_id" : "Playback:Select Prev. Clip",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Select Prev. Clip",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiSpaceBar",
      "unique_id" : "Playback:Space Bar",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Space Bar",
      "should_run_on_backup" : true
      },
      {
      "group_name" : "Playback",
      "selector" : "gpiStop",
      "unique_id" : "Playback:Stop",
      "is_user_action" : false,
      "is_available" : true,
      "name" : "Stop",
      "should_run_on_backup" : true
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 2,
      "is_visible_in_description" : true,
      "default_value" : "192.168.0.1",
      "name" : "IP Address",
      "index" : 0
      },
      {
      "minimum_value" : 1,
      "is_optional" : true,
      "maximum_value" : 16,
      "parameter_type" : 3,
      "is_visible_in_description" : false,
      "default_value" : 1,
      "name" : "Matrix",
      "index" : 1
      },
      {
      "minimum_value" : 1,
      "is_optional" : true,
      "maximum_value" : 16,
      "parameter_type" : 3,
      "is_visible_in_description" : false,
      "default_value" : 1,
      "name" : "Level",
      "index" : 2
      },
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 128,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Destination",
      "index" : 3
      },
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 128,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Source",
      "index" : 4
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "proBelSwitch",
      "unique_id" : "Routers:ProBel Switch",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "Routers",
      "name" : "ProBel Switch"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 2,
      "is_visible_in_description" : true,
      "default_value" : "192.168.0.1",
      "name" : "IP Address",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 2,
      "is_visible_in_description" : true,
      "default_value" : "GPI 1",
      "name" : "Command",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "rossTalkSwitch",
      "unique_id" : "Routers:RossTalk",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "Routers",
      "name" : "RossTalk"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 2,
      "is_visible_in_description" : true,
      "default_value" : "192.168.0.1",
      "name" : "IP Address",
      "index" : 0
      },
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 128,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Destination",
      "index" : 1
      },
      {
      "minimum_value" : 1,
      "is_optional" : false,
      "maximum_value" : 128,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Source",
      "index" : 2
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : false,
      "selector" : "videohubSwitch",
      "unique_id" : "Routers:Videohub Switch",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "Routers",
      "name" : "Videohub Switch"
      },
      {
      "parameters" : [
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 0,
      "parameter_type" : 5,
      "possible_values" : [
      "Cancel",
      "Start Normal",
      "End Normal",
      "Start Immediate",
      "End Immediate"
      ],
      "is_visible_in_description" : true,
      "default_value" : "Start Normal",
      "name" : "Splice Type",
      "index" : 0
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 4294967295,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Event ID",
      "index" : 1
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 65535,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 1,
      "name" : "Program ID",
      "index" : 2
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 65535,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 300,
      "name" : "Duration (ds)",
      "index" : 3
      },
      {
      "minimum_value" : 0,
      "is_optional" : false,
      "maximum_value" : 10000,
      "parameter_type" : 3,
      "is_visible_in_description" : true,
      "default_value" : 0,
      "name" : "After Delay (ms)",
      "index" : 99
      }
      ],
      "should_run_on_backup" : true,
      "selector" : "sendSCTETrigger",
      "unique_id" : "SCTE:Send SCTE Trigger",
      "is_user_action" : false,
      "is_available" : true,
      "group_name" : "SCTE",
      "name" : "Send SCTE Trigger"
      }
    ]

The parameter_type set if it's a string, a number, a boolean. And is defined here:
parameter type

## Get the list of actions of a playlist item

The following request will retrieve all the actions set on the item {m} of playlist {n}. You can use indexes, or unique IDs (see above).

    GET http://localhost:8081/playlists/{n}/items/{m}/actions

#### Action response object:

    {
      "name" : string, The name of the type of Action to execute. eg. "Execute AppleScript"
      "unique_id" : string, The unique identifier of the action.  eg. "0650A319-B0B7-4B06-957C-F81B38470548"
      "position" : number,position of the action in seconds. eg. 0
      "position_type" : string, position type
      "position_timecode" : string, position of the action in timecode. eg. "00:00:00:00" HH:MM:SS:FF
      "template_id" : string, type of action
      "parameters" : array, will depend on the selected "template_id". See below for examples
      "is_outpoint_clamped" : boolean, *
      "is_inpoint_clamped" : boolean, **
      "is_valid" : boolean, TRUE if the action is not valid (for example outside of clip boundaries)
      "is_offline": boolean, TRUE if the AppleScript action, or custom action file is not present on disk
    }

* TRUE if the Action is set to be triggered juste after the out point of the clip (less than 1 second after). Therefore, we have 'clamped' it so it will be triggered at the end of the clip.
** TRUE if the Action is set to be triggered juste before the in point of the clip (less than 1 second after). Therefore, we have 'clamped' it so it will be triggered at the end of the clip.

## Get the info of a specific action on a playlist item

The following request will retrieve the action {k} set on the item {m} of playlist {n}. You can use indexes, or unique IDs (see above).

    GET http://localhost:8081/playlists/{n}/items/{m}/actions/{k}

Response: array <playback response object>

## Add actions to a clip

Previously, you just had to set a name of the AppleScript that had to be triggered for the action. Now you need to indicate the template_id, which is the type of action to execute. Then in its parameters, you set the attributes for that action. These parameters will be different depending on the type of action selected. This is why, we give some examples of actions below.

    POST http://localhost:8081/playlists/{n}/items/{m}/actions

Body:

    {
      "name" : string, OPTIONAL, eg. "Execute AppleScript" -> the name of the type of Action to execute
      "unique_id" : string, OPTIONAL, The unique identifier of the action. eg. "0650A319-B0B7-4B06-957C-F81B38470548"
      "position" : number, OPTIONAL, The position of the action in seconds. eg. 0 *
      "position_timecode" : string, OPTIONAL, The position of the action in timecode in HH:MM:SS:FF *
      "position_type" : string, OPTIONAL, position type
      "template_id" : string, type of action
      "parameters" : array, OPTIONAL, will depend on the selected "template_id". See below for examples
    }

* When adding actions, you can specify 2 types of timing. Either using seconds (position), or using timecode (position_timecode). If you set both, it's the "position" (in seconds) that will be used.

## Some examples of actions to add

As the parameter you will set will be different depending on the type of action, we are showing below some examples. But the easiest is for you to add actions in the OnTheAir Video playlist, and see the parameters that can be used.

### Add an AppleScript Action

This actions will trigger an AppleScript (as the old actions). In parameters, you set the AppleScript to execute, and the "parameter" for that AppleScript (the string that can be used as a variable in the AppleScript).

    POST http://localhost:8081/playlists/{n}/items/{m}/actions

Body:

    {
      "position_timecode": string, OPTIONAL eg. "00:00:45:00"
      "position_type": string, OPTIONAL, position_type
      "template_id": "AppleScript:Execute AppleScript"
      "parameters": {
        "AppleScript Name": string, The name of the project to start.
        "Parameter": string, OPTIONAL, The string that will be passed to be used in the AppleScript
        "After Delay (ms)": number, OPTIONAL, The delay to start the action in ms. eg. 0
      }
    }

Response: action response object

### Add a Dynamic Graphics Overlay (DGO) action

This actions will control CG projects. The difference with the DGO control below is that when using Actions, you can set a specific time for the action to be triggered. If you want to control the status of the projects for the whole length of a clip, you may want to look below, in the section to control the DGO on a "per clip" base

    POST http://localhost:8081/playlists/{n}/items/{m}/actions

Body:

    {
      "position_timecode": string, OPTIONAL eg. "00:00:45:00"
      "position_type": string, OPTIONAL, position_type
      "template_id": "Graphics:Start DGO Project"
      "parameters": {
        "Project Name": string, The name of the project to start.
    	"After Delay (ms)": number, OPTIONAL, The delay to start the action in ms. eg. 0
      }
    }

Response: action response object

### Add a SCTE trigger action

This actions will output SCTE35 triggers in the SDI output (CC option required).

    POST http://localhost:8081/playlists/{n}/items/{m}/actions

Body:

    {
      "position_timecode": string, OPTIONAL eg. "00:00:45:00"
      "position_type": string, OPTIONAL, position_type
      "template_id": "SCTE:Send SCTE Trigger"
      "parameters": {
        "Splice Type": string, The type of splice to do. splice_type
        "Event ID": number, OPTIONAL The number of the Event ID to. eg. 1
        "Program ID": number, OPTIONAL The number of Program ID. eg. 1
        "Duration (ds)": number, OPTIONAL The duration of the event in ds. eg. 0
        "After Delay (ms)": number, OPTIONAL The delay to start the action in ms. eg. 0
      }
    }

Response: action response object

### Add a Videohub Action

This actions will control a Blackmagic-Design VideoHub.

    POST http://localhost:8081/playlists/{n}/items/{m}/actions

Body:

    {
      "position_timecode": string, OPTIONAL eg. "00:00:45:00"
      "position_type": string, OPTIONAL, position_type
      "template_id": "Routers:Videohub Switch"
      "parameters": {
        "IP Address": string, The IP address of the VideoHub
        "Source": number, OPTIONAL The number of the source to switch to. eg. 1
        "Destination": number, OPTIONAL The number of the destination to control. eg. 1
        "After Delay (ms)": number, OPTIONAL The delay to start the action in ms. eg. 0
      }
    }

Response: action response object

## Modify an existing action on a clip

Once you have actions on a clip, you can use a PUT request to modify it. Just pass the keys that you want to modify. So if you need to modify the position, just pass the position key. You can usen either the index or the UID of the action. The UID is recommended so you are sure of which action you are modifying even if their order change.

    PUT http://localhost:8081/playlists/{n}/items/{m}/actions/{k}

Body:

    {
      "name" : string, OPTIONAL, eg. "Execute AppleScript" -> the name of the type of Action to execute
      "unique_id" : string, OPTIONAL, The unique identifier of the action. eg. "0650A319-B0B7-4B06-957C-F81B38470548"
      "position" : number, OPTIONAL, The position of the action in seconds. eg. 0 *
      "position_timecode" : string, OPTIONAL, The position of the action in timecode in HH:MM:SS:FF *
      "position_type" : string, OPTIONAL, position type
      "template_id" : string, type of action
      "parameters" : array, OPTIONAL, will depend on the selected "template_id". See below for examples
    }

Response: action response object

## Delete actions

### Delete a specific action of a clip

    DELETE http://localhost:8081/playlists/{n}/items/{m}/actions/{k}

Response: Command Response Object

### Delete all actions of a clip

    DELETE http://localhost:8081/playlists/{n}/items/{m}/actions

Response: Command Response Object

## Run an Apple script action on the go

The following request will run the mentionned apple script.

    GET http://localhost:8081/actions/{name}/run?parameter={parameter}

Where :
{name} is the name of the action (the one you see on your folder)
{parameter} is the paramter you want to pass to that action
Warning: Use url percent encoded string if your action's name or parameter is using special characters (especially spaces) !
Response: Command Response Object

# Control the Dynamic Graphics Overlays "per clip"

In this section, you will see how to control the status of the DGO projects on a "per clip" base. In the OnTheAir Video preferences, you have to set a default status of a DGO project (running or stopped), which will be used if nothing is set on the clips. So it's very easy for example to have a project running by default, but then on a specific clip, to set the project to stop. This will be done for the whole duration of the clip. If you would like the project to start, or stop (or having its values modified) at a specific time in the clip, use actions instead.

## Get the DGO projects:

Here are examples of requests to get the available CG projects or a specific project designated by {n}:

    GET http://localhost:8081/playback/cg_projects

Response: array <CG Project object>

    GET http://localhost:8081/playback/cg_projects/{n}

Response: CG Project object

#### CG Project object:

    {
      "unique_id" : string,
      "formatted_elapsed_time" : string, eg. "00:00:00"
      "formatted_duration_time" : string,
      "formatted_remaining_time" : string,
      "published" : boolean,
      "display_name" : string, eg. "AnalogClock"
      "display_mode" : string, OPTIONAL eg. "1080i 59.94"
      "width" : number, OPTIONAL eg. 1920
      "height" : number, OPTIONAL eg. 1080
      "frames_per_second" : number, OPTIONAL
      "metadata" : object,
      "path" : string, eg. "\/Applications\/OnTheAir CG\/Projects\/AnalogClock.cg3"
      "remaining" : number,
      "elapsed" : number,
      "duration" : number,
      "status" : string  eg. "Loading"
    }

## Play/Pause/Stop a DGO project:

### Play

    PUT http://localhost:8081/playback/cg_projects/{n}/play

Response: Command Response Object

### Pause

    PUT http://localhost:8081/playback/cg_projects/{n}/pause

Response: Command Response Object

### Stop

    PUT http://localhost:8081/playback/cg_projects/{n}/stop

Response: Command Response Object

## Additional commands:

### Getting the thumbnail of a project

    PUT http://localhost:8081/playback/cg_projects/{n}/thumbnail

Query parameters:

      "width"  REQUIRED
      "height" REQUIRED

Response: image/jpeg DATA or Command Response Object

### Close the project

    PUT http://localhost:8081/playback/cg_projects/{n}/close

Response: Command Response Object

### Scrub in the project

    PUT http://localhost:8081/playback/cg_projects/{n}/scrub

Query parameters:

      "position" REQUIRED

Response: Command Response Object

## Get the CG items of a DGO project:

    GET http://localhost:8081/playback/cg_projects/{n}/items

Response: array <CG Item object>

    GET http://localhost:8081/playback/cg_projects/{n}/items/{i}

Response: CG Item object

#### CG Item object:

    {
      "unique_id" : string,
      "type" : string,
      "display_name" : string,
      "frame" : number,
      "begin_time" : number,
      "hold_duration" : number,
      "stay_forever" : boolean,
      "is_locked" : boolean,
      "is_hidden" : boolean,
      "is_published" : boolean,
      "default_value" : string
    }

## Modify the items of a DGO project:

Below are example of request that you can use to modify the items {i} of a DGO project {n}:

### Modifying the position and dimensions of an item

You can modify the width, height and position of an item. The unit of the numbers below are in pixels, and the origin for the position is at the bottom left of the signal

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "width": number, OPTIONAL eg. "40",
      "height": number, OPTIONAL eg. "60",
      "originX": number, OPTIONAL eg. "600",
      "originY": number, OPTIONAL eg. "800",
    }

### Hiding an item

To hide an item, set the "hidden" property of an item to true, set it to false to unhide it.

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "hidden": boolean,,
    }

### Modifying text items

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "text" : string, OPTIONAL eg. "This is my new text"
    }

### Modifying rich text items

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "htmlText": "<span style='font-family:Courier; color:red; font-size: 20;'> 20px red text. </span>
      <span style='font-family:Courier; color:blue; font-size: 50;'> 50px blue text.</span>"
    }

### Modifying shapes

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "shape_type": string, OPTIONAL eg. "rectangle" - Possible shape types,
      "fill_type": string, OPTIONAL eg. "linear_gradient" - Possible shape fill types,
      "stroke_width": number, OPTIONAL eg. "5",
      "stroke_color": string, OPTIONAL  eg. "0xFFFF00FF" - RGBA 32-bit Representation (0xRRGGBBAA),
      "fill_color": string, OPTIONAL eg. "0x51127FFF" - RGBA 32-bit Representation (0xRRGGBBAA),
      "gradient_colors": array of strings, OPTIONAL eg. ["0x143490FF","0x51127FFF","0xC4408FFF"] - RGBA 32-bit Representations (0xRRGGBBAA) of the different colors of the gradient,
      "gradient_locations": array of numbers, OPTIONAL eg. [0,0.25,1] - Number (from 0 to 1) representing the position of the gradient colors indicated in 'gradient_colors',
      "stroke_line_cap": string, OPTIONAL eg. "butt" - Possible line cap styles,
      "stroke_line_join": string, OPTIONAL eg. "miter" - Possible line join styles,
      "stroke_pattern": string, OPTIONAL eg. "10-20-50-20" - The dash pattern, represented by units of dash and gaps. The example before will be: a dash of 10 units, gap 20 units, dash 50 units, gap 20 units, repeating,
      "gradient_angle": number, OPTIONAL eg. "45"
    }

### Change Movies items

You can change the path of a movie item using either the full path or the relative path. When using the relative path, this means that the file used will be found relatively to the location of the project itself. This allows you then to move the project and media to another location, and this will continue to work. Of course this requires that the file be located in the same folder as the project.

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "moviePath" : url, REQUIRED eg. using full path "/Volumes/Movies/MyMovie.mov"
    }

### Change Images items

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "imagePath" : url, OPTIONAL eg. using relative path "../MyImage.jpeg"
    }

### Change Audio items

    PUT http://localhost:8081/playback/cg_projects/{n}/items/{i}

Body:

    {
      "filePath" : url, OPTIONAL eg. using relative path "../MySound.AIFF"
    }

# Scheduler & Control

## Start the schedule

    GET http://localhost:8081/scheduler/start

## Stop the schedule

    GET http://localhost:8081/scheduler/stop

## Resynchornize the schedule

This will force OTAV to go through the schedule again and start what is scheduled to be started. Note that this will interrupt playback very briefly to start a new clip.

    GET http://localhost:8081/scheduler/resynchronize

## Get the list of playlists in the current schedule

    GET http://localhost:8081/scheduler/playlists

Response: array <scheduler's Playlist Object>

#### Scheduler's Playlist Object response:

    {
      "path" : string, eg. "/Volumes/Movies/DailyPlaylist.xpls"
      "missing_items" : number,
      "modification_date" : string, eg. "Today at 09:35"
      "is_folderbased" : boolean,
      "total_items" : number,
      "duration" : number, eg. 1802.00
      "duration_string" : string eg. "00:30:02" HH:MM:SS
    }

## Open a playlist from the schedule

The following request will open the playlist with specified path {path}. Once a scheduled playlist is open you can control it the way you do with opened playlists.

    GET http://localhost:8081/scheduler/playlists?path={path}

Response: playlist response object in case of success, Command Response Object in case of open failure

## Close a playlist

The following request will close the playlist with specified ID.
Warning ! Use this command with care as some other remote user may no longer have access to the playlist after its close.

    GET http://localhost:8081/playlists/{id}/close

## Get schedule's infos

    GET http://localhost:8081/scheduler?include_items=1

You can retrieve several infos about the current scheduler. The query parameter "include_items" will allow you to get all the events of the scheduler. If you don't need them, don't pass it.

Response:

    {
      "version" : string, eg. "2.0"
      "is_enabled" : boolean,
      "schedule_path" : string, OPTIONAL eg. "/Users/admin/Documents/MySchedule.xml"
      "current_playlist": string, OPTIONAL
      "next_playlist": string, OPTIONAL
      "next_timed_playlist": string, OPTIONAL
      "events": array <scheduler event response object> OPTIONAL
    }

## Get schedule's events only

    GET http://localhost:8081/scheduler/events

#### Scheduler's event object response:

    [
      {
        "start_date_time" : date, OPTIONAL *, eg. "2023-10-28 04:00:00"
        "playlists": [
          {
          "playlist_path": string, eg. "/Volumes/Playlists/MyPlaylist.xpls"
          "should_shuffle": boolean,
          "should_loop": boolean,
          "should_randomize": boolean
          },
          {
          "playlist_path": string, eg. "/Volumes/Playlists/MyPlaylist.xpls"
          "should_shuffle": boolean,
          "should_loop": boolean,
          "should_randomize": boolean
          }
        ],
        "is_enabled": boolean,
        "repeating_event_start_time": number, OPTIONAL ** In seconds. eg. "3600"
        "should_loop": false,
        "repeating_days": OPTIONAL **{
          "monday": boolean, TRUE if event repeats on Mondays
          "tuesday": boolean, TRUE if event repeats on Tuesdays
          "wednesday": boolean, TRUE if event repeats on Wednesdays
          "thursday": boolean, TRUE if event repeats on Thursdays
          "friday": boolean, TRUE if event repeats on Fridays
          "saturday": boolean,  TRUE if event repeats on Saturdays
          "sunday": boolean, TRUE if event repeats on Sundays
          },
        "use_preset_theoretical_duration" : boolean, TRUE if event has a preset duration
        "theoretical_duration_in_seconds" : number, OPTIONAL ***, the preset duration in seconds of the event
        "finder_label_index" : number, the index number of the color label eg. "0"
        "display_name" : string, Name of the event eg. "My event"
        "is_repeating_event" : boolean
      }
    ]

* Only for events with a specific date (non repeating) ** Only for repeating events *** Only when "use_preset_theoretical_duration" = TRUE

## Resynchronize the schedule

The following request will ask the scheduler to resynchornize: stop playing what it is currently playing and start playing what was scheduled to play.

    GET http://localhost:8081/scheduler/resynchronize

Response: Command Response Object

# Media Browser

## Refresh media browser's content

    GET http://localhost:8081/media/refresh

Response: Command Response Object

## Refresh media browser's content

    GET http://localhost:8081/media/refresh

Response: Command Response Object

# Working with Transitions

## Get available transitions

    GET http://localhost:8081/playback/transitions

Response: Transitions object

#### Transitions response object:

    [
      {
        "user_transition" : boolean TRUE if it's a user custom transition
        "type" : string,  eg: "alphaMovie" (custom transition), "shader" (built-in transition)
        "unique_id" : string,  eg: "MyTransition"
        "name" : string,  eg: "MyTransition"
        "item_b_start_frame_offset" : number, eg. 19.452766666666665
        "item_a_end_frame_offset" : number, eg. 9.4761333333333333
        "duration" : number, eg. 30.163466666666668
        "path" : string, OPTIONAL *, "\/Volumes\/Transitions\MyTransition.mov"
        "should_premultiply_by_alpha" : boolean, OPTIONAL *, TRUE to premultiply alpha
        "shader_animation_type" : string, OPTIONAL **, shader animation type
        "shader_animation_option" : string, OPTIONAL **, shader animation option
      }
    ]

* Only for user transitions
** Only for built-in transitions

# Working with Subtitles

This allows you to control the subtitles that are going out of OTAV. This is very useful to provide live subtitling output for your program.

## Get playback's subtitles

    GET http://localhost:8081/playback/subtitles

Response: array <subtitle record object>

#### Subtitle record response object:

    {
      "start_time_seconds": number,
      "start_timecode": string,
      "end_time_seconds": number,
      "end_timecode": string,
      "text_lines": array <subtitle line>
    }

#### Subtitle line response object:

    {
      "alignment": string, eg. "center" see alignment type
      "text": string
    }

## Adding subtitles to current playback

    POST http://localhost:8081/playback/subtitles

#### Subtitle record object:

    {
      "start_time_seconds": number, REQUIRED
      "start_timecode": string, OPTIONAL Format HH:MM:SS,ttt
      "end_time_seconds": number, REQUIRED
      "end_timecode": string, OPTIONAL Format HH:MM:SS,ttt
      "text_lines": array <subtitle line> REQUIRED
    }

#### Subtitle line object:

    {
      "color": string, eg. "#ff00ff" OPTIONAL
      "alignment": string, alignment type OPTIONAL
      "vertical_position": number, eg. 11 OPTIONAL
      "text": string
    }

Response: Command Response Object

NOTE:
"end_time_seconds" property override the "end_timecode" property.
"start_time_seconds" property override the "start_timecode" property.

# For more information

If you need more info or support about OnTheAir Video, you can find it on our support desk. And if you need additional information on the API and/or the websockets, submit a ticket and we'll be happy to guide you.

- unknown
- normal
- stop
- holdLastFrame
- chain
- loop
- cueNext

- default
- fill
- letterbox
- panAndScan
- natural

- stopped
- playing
- paused
- holdLastFrame
- holdFirstFrame

0. Video file
1. Audio file
2. Image file
3. Comment
4. Live
5. Stream

0. No Captions
1. CEA-608 (Embedded)
2. CEA-708 (Embedded)
3. OP47/Teletext (Embedded)
4. ATSC (Not Supported)
5. SRT (Sidecar File)
6. STL (Sidecar File)

- "invalid"
- "valid"
- "offline"
- "notYetValidated"

- "none"
- "fileNotFound"
- "notAMovie"
- "notSelfContained"
- "notThreadSafe"
- "codecNotFound"
- "videoCodecNotSupported"
- "noVideoTrack"
- "noAudioTrack"
- "invalidAudioTracks"
- "fileFormatNotSupported"
- "incorrectFrameRate"
- "liveInputNotPresent"
- "liveDisabled"
- "liveCaptureNotStarted"
- "liveInvalidInputFormat"
- "liveNotSupportedInOTAVE"
- "streamNotFound"
- "streamNotSupportedInOTAVE"
- "fileDurationTooShort"
- "containsOfflineActions"
- "unknown"

- "beforeStart"
- "fromStart"
- "fromEnd"
- "fromInPoint"
- "fromOutPoint"

- "Do Nothing"
- "ATEM:ATEM Program Switch (by index)"
- "ATEM:ATEM Program Switch (by name)"
- "ATEM:Run Macro At Index"
- "ATEM:Run Macro With Name"
- "GPI:GPI Pulse Output"
- "GPI:GPI Set Output ON"
- "GPI:GPI Set Output OFF"
- "Graphics:Start DGO Project"
- "Graphics:Stop DGO Project"
- "MIDI:Send MIDI Message"
- "Playback:Cue Next Clip"
- "Playback:Cue Selected Clip"
- "Playback:Pause"
- "Playback:Play Next Clip"
- "Playback:Play Selected Clip"
- "Playback:Re-Cue Current Clip"
- "Playback:Re-Play Current Clip"
- "Playback:Release Pause"
- "Playback:Select Next Clip"
- "Playback:Select Next Playlist"
- "Playback:Select Prev. Clip"
- "Playback:Space Bar"
- "Playback:Stop"
- "Routers:ProBel Switch"
- "Routers:RossTalk"
- "Routers:Videohub Switch"
- "SCTE:Send SCTE Trigger"

- "Cancel"
- "Start Normal"
- "End Normal"
- "Start Immediate"
- "End Immediate"

- 0 (None)
- 1 (File Path)
- 2 (String)
- 3 (Integer Number)
- 4 (Double Number)
- 5 (Multiple Values)
- 6 (Blob)
- 7 (Boolean)

- "left"
- "right"
- "center"
- "unchanged"

- "rectangle"
- "rounded_rectangle"
- "ellipse"

- "clear_color"
- "color"
- "linear_gradient"
- "radial_gradient"

- "butt"
- "round"
- "square"

- "miter"
- "round"
- "bevel"

- CrossFade
- FadeInFadeOut
- Push
- WipeColumns
- WipeLines
- WipeColumns
- WipeSingleTriangle
- WipeDualTriangles
- WipeCircle
- WipeDiagonalFromCenter
- WipeCornersInDiagonal
- WipeSingleBox
- WipeCornersInFourBoxes
- WipeSingleBox

- none
- bottom
- left
- right
- top
- topRight
- topLeft
- bottomRight
- bottomLeft
- left+right
- top+bottom
- topCenter
- middleCenter
- middleRight
- middleLeft
- bottomCenter