Overview of JSON protocol

Introduction to the Ateliere Live Rendering Engine JSON protocol

This is a description of the network protocol used to control, monitor and explore the components in a running Ateliere Live production.

The JSON protocol is used when connected to the Websocket Control Panel (acl-websocketcontrolpanel) and has multi-client support, making it possible for clients that are connected to the same production to mirror each other’s controls.

Control protocol layers

The JSON protocol sits on top of an application-independent platform protocol which transports the JSON payload between the clients and the production.

Control Panel implementation

Note: This section is mainly needed if you plan on implementing a new control panel for the Atelier Live Rendering Engine using the C++ SDK.

Most of the JSON messages described in this document are sent and received by the Websocket Control Panel using the ControlDataSender interface. The interface encapsulates the packing and unpacking of messages to and from the application-agnostic platform protocol. The platform protocol includes the addresses for the sender and receiver(s) of the messages but is unaware of the contents of the packages.

The ControlDataSender interface defines the callbacks that should be used for handling messages coming from the production. Response and status messages are received from the production by setting the mResponseCallback and mStatusMessageCallback, respectively. The data received in these callbacks are complete JSON messages conforming to the specification in this document and can be forwarded without changes to the connected clients. There are however some exceptions to this.

Events

Messages of the type event currently signals that a connection was opened or closed in the production. Event messages originate in the control panel meaning that implementing support for this message type is part of making a control panel using the C++ SDK.

The control panel gets the events from the underlying platform through the ControlDataSender::Settings::mConnectionEventCallback. By inspecting the ConnectionEvent provided in the callback, clients connected to the control panel can be informed about the event. This can be used by other control panels, implemented using the C++ SDK.

Please see the section about the event message type under “Message types” for information about the message syntax.

Hop count

Messages of different types need to propagate to different depth of the production. A hop count in each message determines if it will be relayed from one Rendering Engine to a possibly chained one behind it.

When receiving a JSON message from a client, the Websocket Control Panel will select a hop count based on the content of the message, before sending the message to the production.

The hop count is marked in the platform layer of the protocol when sending a message using ControlDataSender::sendRequestToReceivers. It is not visible in the JSON message.

For each type of message, the hop count used by the Websocket Control Panel is specified in a “Hop count” section within “Message types” below. This hop count should be used when implementing a new C++ control panel.

The state tree

The control API is based around a state tree that makes up the hierarchy of parameters and entities in the Rendering Engine that can be controlled or monitored. The tree is expressed as a JSON structure.

An entity in the tree is addressed by a path consisting of the names of each enclosing object surrounding the entity.

For instance, in the structure below, the path to the g-field of the rgb_filter would be /video/nodes/rgb_filter/g:

{
    "video": {
        "nodes": {
            "rgb_filter": {
                "r": 0.5,
                "g": 0.4,
                "b": -0.2
            }
        }
    }
}

Message format

JSON syntax is used for all messages. The type and resource fields are present in all messages and define the type of message and what resource that is affected by this message.

{
    "type": "...",
    "resource": "..."
}

Message types

All changes that can be made to a production are available in the JSON API through messages of type set or command.

A parameter that can be changed immediately, without side effects, and that will keep its state until the next change can be accessed directly with a set message. In other cases a command is necessary to initiate the change. A set message might for instance be used for controlling the layer opacity in an alpha-over node or the gain for an input to the audio mixer whereas a command is needed to initiate the loading of a media file or a transition effect spanning over a period of time.

To get the current state of a resource, a get message can be used. A resource can also be monitored for changes using a subscribe message. When a sub-resource is added or removed from the monitored resource, a state-add or state-remove message is sent to the subscriber. Other changes result in a state-change message.

Parameters that change continuously without any user input, such as the play position of a media player or the loudness in an audio output, are referred to as streaming parameters. Streaming parameters are monitored by sending a sampling-start message to the resource path of the streaming parameter and providing a time interval stating how often sampling-update messages should be sent.

Table of message types

Message typeDescription
getGet the value of a resource
get-responseThe response to a get message
setChange the value of a resource
set-responseThe response to a set message
subscribeSubscribe to state changes within a resource
subscribe-responseThe response to a subscribe message
unsubscribeStop monitoring state changes within a resource
unsubscribe-responseThe response to an unsubscribe message
commandExecute a command in a resource
command-responseThe response to a command message
state-changeDescribes the new state of a resource
state-addA sub-resource was added to a resource
state-removeA sub-resource was removed from a resource
subscription-listList own subscriptions
subscription-list-responseThe response to a subscription-list-response message
describeGet a description of a resource
describe-responseThe response to a describe message
sampling-startStart sampling a streaming parameter
sampling-start-responseThe response to a sampling-start message
sampling-stopStop sampling a streaming parameter
sampling-stop-responseThe response to a sampling-stop message
sampling-listList own streaming parameter subscriptions
sampling-list-responseThe response to a sampling-list message
sampling-list-allList all streaming parameter subscriptions
sampling-list-all-responseThe response to a sampling-list-all message
sampling-updateDescribes the latest sampled state of a streaming parameter
eventVarious information. Only sent to clients of the Websocket Control Panel

All response messages contain the field timestamp. This is the time when the request message was handled, i.e. the timestamp of the frame processed on that time.

Each type of message is described in detail below.

get and get-response

A message of type get is used to retrieve the current state of a given resource within the production.

Required fields for get messages:

ParameterDescription
typeMust be “get”
resourceThe path to get the current state from

For instance:

{
    "type": "get",
    "resource": "/video/nodes"
}

The response is a get-response. A successful response contains a body object with the current state of the resource:

{
    "type": "get-response",
    "resource": "/video/nodes",
    "timestamp": 1731073800720000,
    "body": {
        ...
    }
}

The body has its root where the resource URI points.

An unsuccessful get has no body and contains an error message, for instance:

{
    "type": "get-response",
    "resource": "/video/nodes",
    "error": "No such resource: /video/nodes",
    "timestamp": 1731073800720000
}

NOTE: Repeatedly calling get is a very inefficient way of monitoring the state of a production. Please see the subscribe and state-change message sections for a better way.

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, get messages will stop at the first one and the state for that pipeline will be returned. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to 1 (one) for get messages.

set and set-response

A message of type set is used to change the state of one or more components located at a specified resource path in the production. This can for instance be to change the currently selected video source of a transition node or to change the gain of an audio strip.

set messages are generally only available for changes which are immediate. Please see the command message section for details about changes that occur over a period of time.

Required parameters for set messages:

ParameterDescription
typeMust be “set”
resourceThe path to apply the changes to
bodyThe set of changes to apply

The body of a set request contains the new values of the fields to change within the resource path. The structure of the body does not need to be complete - only the fields that should be updated need to be included.

Example of a set request that changes program and preview within a node named my_transition_node:

{
    "type": "set",
    "resource": "/video/nodes/my_transition_node",
    "body": {
        "preview": 3,
        "program": 8
    }
}

The body does not need to be an object when setting a single item, just the value. Here is an example:

{
    "type": "set",
    "resource": "/audio/strips/1/filters/gain/value",
    "body": 8.6
}

The set-response does not contain a body with the set values - instead changes in the production need to be monitored by subscribing to the affected resources. Please see the subscribe message section for details about subscriptions.

If there is an error, a set-response is returned containing an error message. In this case none of the parameters in the body of the set message will be applied. If the set was successful the response will contain a result ok key/value.

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, set messages will propagate all the way to the last pipeline while following the configured alignment delay of each step. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to -1 (negative one) for set messages.

command and command-response

Commands are used to initiate events in the production which are not immediate or that do not have a direct relationship to one specific field of the production state tree. For instance, when starting playback of a media file there might be a play command. This will start the actual playback but also change the player state (e.g. from paused to playing) and also start to periodically update the current playback position field.

Required parameters for command messages:

ParameterDescription
typeMust be “command”
resourceThe resource receiving the command
body/commandThe name of the command to execute
body/parametersThe set of parameters to the command. If the command takes no parameters, this can be skipped, or passed empty

Example of a command that starts a fade command on a transition node:

{
    "type": "command",
    "resource": "/video/nodes/my_transition_node",
    "body": {
        "command": "fade",
        "parameters": {
          "duration_ms": 120
        }
    }
}

Example of a command that takes no parameters:

{
    "type": "command",
    "resource": "/video/nodes/my_transition_node",
    "body": {
        "command": "cut"
    }
}

As for set-response messages, the command-response has no body - instead changes in the production need to be monitored by subscribing to one or more resources. Please see the subscribe message section for details about subscriptions.

If there is an error, a command-response is returned containing an error message. If the command was successful the response will contain a result ok key/value.

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, command messages will propagate all the way to the last pipeline while following the configured alignment delay of each step. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to -1 (negative one) for command messages.

subscribe and subscribe-response

Subscriptions are used to monitor changes in the production. This can e.g. be useful in order to mirror the controls of different control surfaces that are connected to the same production, detect when new resources appear, or to otherwise visualize different parts of the system.

Required parameters for subscribe messages:

ParameterDescription
typeMust be “subscribe”
resourceThe path to monitor for changes

Example of a subscribe message for tracking changes of the resource /audio/strips/3/compressor:

{
    "type": "subscribe",
    "resource": "/audio/strips/3/compressor"
}

The response is a subscribe-response. A successful response contains a body object with the current state of the resource, for instance:

{
    "type": "subscribe-response",
    "resource": "/audio/strips/3/compressor",
    "body": {
        "attack": 30,
        "gain": 1,
        "knee": 3.5,
        "ratio": 3.3,
        "release": 2000,
        "threshold": -24,
        "type": "compressor"
    },
    "timestamp": 1731073800720000
}

If there is an error, a subscribe-response is returned containing an error message instead of a body.

Whenever a monitored resource changes, a state-change, state-add or state-remove message is sent to all subscribers of that resource. Please see the state-change, state-add and state-remove message sections for details about this.

Websocket Control Panel

In a proxy-editing setup, i.e. when there is one pipeline behind another one, subscribe messages will stop at the first one and it is from this pipeline that state changes will be reported. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to 1 for subscribe messages.

unsubscribe and unsubscribe-response

To stop receiving updates when a monitored resource changes, an unsubscribe message can be used.

Required parameters for unsubscribe messages:

ParameterDescription
typeMust be “unsubscribe”
resourceThe resource path to stop monitor for changes

If the unsubscribe message is successful, an unsubscribe-response is returned:

{
    "type": "unsubscribe-response",
    "resource": "/audio/strips/3/compressor",
    "timestamp": 1731073800720000
}

If there is an error, an unsubscribe-response is returned containing an error message instead of a body.

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, unsubscribe messages will stop at the first receiver of the message. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to 1 for unsubscribe messages.

state-change

A state-change message describes the new state for a number of fields within a specified resource. state-change messages are sent from the production side, i.e. they are only received, never sent, by clients.

state-change messages are sent whenever the internal state of the production changes, for instance when:

  • a client has issued a set message
  • a command that changes the state is being executed
  • an automation changes the state over a period of time
  • a component, such as a metering device, has new data to report

To avoid loops or unnecessary updates on the client side, the message includes an actor field stating whether the receiver of the message or some other entity caused the change to happen.

actor valueMeaning
“self”The receiver of the message caused the change
“other”Another client caused the change
“system”A change from within the system

Format of the state-change message:

ParameterDescription
typeMust be “state-change”
resourceThe resource path that has changed
bodyThe fields that have changed within the resource
actorThe entity responsible for the change

Below is an example state-change message where the client receiving the message also caused the change to happen:

{
    "type": "state-change",
    "resource": "/audio/strips/3/compressor",
    "actor": "self",
    "body": {
        "gain": 2.5,
        "ratio": 4.0
    }
}

state-add and state-remove

The state-add and state-remove messages are similar to the state-change message. The top level resource field is the resource the client subscribes to. In the body of the message there is another resource field telling what sub-resource has been added or removed.

Examples:

{
  "type": "state-add",
  "resource": "/audio",
  "actor": "system",
  "body": {
    "resource": "/strips/2"
  }
}
{
  "type": "state-remove",
  "resource": "/audio",
  "actor": "system",
  "body": {
    "resource": "/strips/2"
  }
}

subscription-list and subscription-list-response

The subscription-list message is used to list own subscriptions. The response message shows the client’s subscriptions, located under a given resource point in the tree.

Required fields for subscription-list messages:

ParameterDescription
typeMust be “subscription-list”
resourceThe resource path to start looking for subscriptions from

For instance:

{
    "type": "subscription-list",
    "resource": "/video"
}

The response is a subscription-list-response. A successful response contains a body object with the current state of the resource:

{
  "type": "subscription-list-response",
  "resource": "/video",
  "timestamp": 1731414140040000,
  "body": {
    "subscriptions": [
      "/nodes/alpha_combine",
      "/nodes/alpha_over"
    ]
  }
}

The body has its root where the resource URI points.

An unsuccessful request has no body and contains an error message, for instance:

{
  "type": "subscription-list-response",
  "resource": "/video/nodes/over",
  "timestamp": 1731414382900000,
  "error": "Failed to find resource with name 'over'"
}

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, subscription-list messages will stop at the first one, and the subscriptions for that pipeline will be returned. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to 1 for subscription-list messages.

describe and describe-response

The purpose of these messages is to get a description of some resource in the state tree, like a node in the video mixer component for example. The descriptions will list all commands and parameters which are valid for the resource.

Required fields for describe messages:

ParameterDescription
typeMust be “describe”
resourceThe path to resource to describe

This is the description for /video/nodes/fade_to_black:

{
  "type": "describe-response",
  "resource": "/video/nodes/fade_to_black",
  "timestamp": 1731480819600000,
  "body": {
    "children": [],
    "commands": [
      {
        "command": "fade_from",
        "optional_parameters": [],
        "required_parameters": [...],
        ...
      },
      ...
    ],
    "parameters": [
    ...
    ]
  }
}

Hop count

In a proxy-editing setup, i.e. when there is one pipeline behind another one, describe messages will stop at the first receiver of the message. This is applicable when using a Websocket Control Panel. When implementing a new control panel using the C++ SDK, set the hop count to 1 for describe messages.

sampling-start and sampling-start-response

The sampling-start message is used to start sampling a streaming parameter. If successful, sampling-update messages will be sent to the subscriber periodically at the specified time inteval.

Required parameters for sampling-start messages:

ParameterDescription
typeMust be “sampling-start”
resourceAn expression describing the streaming parameter(s) to start sampling
body/interval_msThe update interval

An asterisk (*) can be used at any level of the resource expression to indicate “all components at this level”. If an asterisk is used, no other characters are allowed at that level of the path. For instance, "resource": "/audio/mixes/*/input_meter/*" can be used to start sampling all streaming parameters under input_meter for all audio mixes.

The interval_ms parameter must be greater than or equal to 40.

Example:

{
  "type": "sampling-start",
  "resource": "/audio/mixes/*/input_meter/*",
  "body": {
    "interval_ms": 100
  }
}

If there is an error, a sampling-start-response is returned containing an error message. If the sampling-start was successful the response will contain a result ok key/value.

sampling-stop and sampling-stop-response

The sampling-stop message is used to stop sampling a streaming parameter.

Required parameters for sampling-stop messages:

ParameterDescription
typeMust be “sampling-stop”
resourceAn expression used to start sampling one or more streaming parameters

The resource parameter must match one used to start sampling exactly.

Example:

{
  "type": "sampling-stop",
  "resource": "/audio/mixes/*/input_meter/*"
}

If there is an error, a sampling-stop-response is returned containing an error message. If the sampling-stop was successful the response will contain a result ok key/value.

sampling-list and sampling-list-response

The sampling-list message is used to list the streaming parameter subscriptions that are registered to the client sending the message.

Required parameters for sampling-stop messages:

ParameterDescription
typeMust be “sampling-list”
resourceMust be “/”

Example:

{
  "type": "sampling-list",
  "resource": "/"
}

If there is an error, a sampling-list-response is returned containing an error message. If the sampling-stop was successful the response will contain a list of all the sender’s streaming parameter subscriptions.

Example:

{
    "type": "sampling-list-response",
    "resource": "/",
    "body": {
        "samplings": [
            "/audio/strips/1/pre_filter_meter/*",
            "/audio/mixes/0/input_meter/*"
        ]
    },
    "timestamp": 1736860857880000
}

sampling-update

A sampling-update message describes the latest sampled state of one or more streaming parameters matching a subscription. The message is sent periodically to clients that have started subscriptions using sampling-start.

The message contains the resource expression used in sampling-start. If necessary this can be used to identify the subscription in the client.

The body of the message contains the updated state for all of the streaming parameters matching the subscription. Note that the body starts at the root of the state tree, which is different from e.g. get responses or subscriptions for non-streaming parameters.

Example:

{
    "type": "sampling-update",
    "resource": "/audio/strips/*/pre_filter_meter/*",
    "body": {
        "audio": {
            "strips": {
                "1": {
                    "pre_filter_meter": {
                        "peak": -0.439775225995602234
                    }
                },
                "2": {
                    "pre_filter_meter": {
                        "peak": -0.982362873895602837
                    }
                }
            }
        }
    },
    "timestamp": 1736861180080000
}

event

When connected to a Websocket Control Panel it will act as a proxy in front of the Rendering Engine. This introduces a message of type event, which is only used between the Websocket Control Panel and its clients. Messages of type event contain an event field specifying the type of event.

All clients connected to the Websocket Control Panel will receive events of type connect whenever a new connection is established between the Websocket Control Panel and a Rendering Engine. Such a message might look like:

{
    "type": "event",
    "connected_node": "<uuid>",
    "address": "<uuid>:<uuid>:...",
    "event": "connect"
}

where connected_node is the UUID of the newly connected node (Rendering Engine) and address is a colon separated list of UUIDs, which is the address to the node that discovered the connection. For connect events this is currently only the Websocket Control Panel itself, meaning the address is always the Websocket Control Panel’s.

When a connection between a client and a Websocket Control Panel is established, the client will receive connect events for all Rendering Engines that where already connected to the Websocket Control Panel, to let the client know it is connected to a production.

If the connection between the Websocket Control Panel and the Rendering Engine breaks, whether it is disconnected on purpose or gets disconnected due to a network outage, the Websocket Control Panel will send an event message to all its clients.

{
    "type": "event",
    "disconnected_node": "<uuid>",
    "address": "<uuid>:<uuid>:...",
    "event": "disconnect"
}

A similar message is also sent to the clients in case the connection between two Rendering Engines/Pipelines is torn down or lost, such as between a Low Delay and a High Quality Pipeline. In that case the address parameter will be the UUID of the Websocket Control Panel followed by the UUID of the LD Pipeline and the disconnected_node is the UUID of the HQ Pipeline.