How to use the WebAPI of aixtream?

aixtreamsoftware-webAPI

Typically, aixtream users interact with the system via the built-in web interface that is accessible via HTTP and HTTPS. For the majority of use cases, this web interface is the recommended way to access the system. It allows users to easily configure PIPEs or system settings and swiftly start or stop streams or monitor system properties.

However, sometimes the direct interaction via the web interface is not expedient, especially when certain tasks or operations are intended to be automated. One solution could be the Smart Control Applet feature that is available as an option for aixtream. When even applets are not sufficient to achieve the desired goal, directly accessing the WebAPI might be necessary.

Like most modern web services, the WebAPI of aixtream is based on the REST paradigm (https://en.wikipedia.org/wiki/Representational_state_transfer) where HTTP requests can create (POST), read (GET), update (PUT/PATCH) or delete (DELETE) objects. These being the various items that the system handles and can interact with, like individual user accounts or audio streams.

In this blog, I will first describe the general layout of the internal objects that may be interacted with via the API. Then, for each possible operation on such an object, I will provide a practical example.

1. Object Layout

In aixtream’s WebAPI, objects are represented in the common JSON format:

{

    “objectClass”: “stream”,

    “uuid”: “6bbfbb3a-49a8-454f-8542-a563d824e67a”,

    “attributes”: [ ],

    “rev”: 42,

    “state”: “playing”,

    “pendingState”: “invalid”,

    “nChannels”: 2,

    “elements”: [ … ],

    “name”: “test pipe”,

    “streamGroup”: “”,

    …

}

Each object in aixtream contains the fields objectClass (designating the type of the object), uuid (for uniquely identifying the object), rev (for internal revision management), and attributes (for general purpose data and for custom role-based access control). The remaining fields are specific to the particular object classes.

The example stream object represents a PIPE that is currently playing and no request to change this state is enqueued (the pendingState field is “invalid”). The PIPE has two channels and a list of elements (not shown in detail here). The name is “test pipe” and it does not belong to a PIPE group (streamGroup is empty).

2. Object Addressing

In the WebAPI, objects are addressed by this base URL: https://aixtream-12abcdef/webapi/http/objects/.

The base must be extended by an objectClass and possibly the uuid of a specific object. Hence, the URL https://aixtream-12abcdef/webapi/http/objects/stream addresses all objects of class stream while  https://aixtream-12abcdef/webapi/http/objects/stream/6bbfbb3a-49a8-454f-8542-a563d824e67a addresses the specific object from the example above.

3. Login / Creating an Object

To be able to interact with aixtream on the API level, a login is required. This is is managed through a “special” session object that needs to be created. For a login as root with default credentials the object looks like this:

{

    “objectClass” : “session”,

    “username” : “root”,

    “password” : “ferncast”

}

It must be sent to the address https://aixtream-12abcdef/webapi/http/objects/session via a POST request, for example with the common curl tool:

curl –header “Content-Type: application/json”

     –request POST \

     –cookie-jar session.jar \

     –data {“objectClass”:”session”,”username”:”root”,”password”:”ferncast” } \

     https://aixtream-12abcdef/webapi/http/objects/session

The output is a session cookie – saved to a file with the “–cookie-jar session.jar” parameter. It has to be passed along with all further requests, which is achieved with the “–cookie session.jar” parameter when using curl.

The above call actually creates the session object within the aixtream system. Internally, it automatically assigns a uuid field. As this uuid is needed, the object should be immediately retrieved again:

curl –header “Content-Type: application/json” \

     –request GET \

     –cookie session.jar \

     https://aixtream-12abcdef/webapi/http/objects/session

 The result looks like this and the assigned uuid can be extracted:

[

  {

    “duration”: 600.0,

    “objectClass”: “session”,

    “user_uuid”: “a79b9852-506f-48ad-8ccb-d268197e0266”,

    “username”: “root”,

    “uuid”: “5ff1c07e-5cd7-4d94-94ef-79a28bb189e4”

  }

]

4. Logout / Deleting an Object

Objects are simply deleted via a standard DELETE request. Specifically, the session logout is achieved via a DELETE request on the current session object, i.e.:

curl –header “Content-Type: application/json” \

     –request DELETE \

     –cookie session.jar \

     https://aixtream-12abcdef/webapi/http/objects/session/5ff1c07e-5cd7-4d94-94ef-79a28bb189e4

The session cookie (here in the file session.jar) should also be deleted by the client.

5. Reading an Object

Once logged in, objects may be accessed according to the current user and user role permissions. For example, the “test pipe” from our example may be retrieved at any time by a GET request:

curl –header “Content-Type: application/json” \

     –request GET \

     –cookie session.jar \

     https://aixtream-12abcdef/webapi/http/objects/stream/6bbfbb3a-49a8-454f-8542-a563d824e67a

The resulting JSON output may be inspected for the current state of the PIPE, eventual error messages (field errorMessage) or other properties.

6. Reading all Objects of a Specific Class

A GET request on the class URL instead of a specfic object URL returns all objects of that class, i.e., all PIPE groups may be fetched at once with:

curl –header “Content-Type: application/json” \

     –request GET \

     –cookie session.jar \

     https://aixtream-12abcdef/webapi/http/objects/streamGroup

 

This method can be readily used to implement a simple external monitoring of the aixtream system. The object class “alarm” is useful to quickly find out about PIPEs or connections which are currently suffering an error. A simple GET request on https://aixtream-12abcdef/webapi/http/objects/alarm is sufficient, for example, to find the following comprehensive alarm information:

[

  {

    “uuid”: “78e9cd3c-0526-46aa-be43-4d27e53d450f”,

    “attributes”: [],

    “rev”: 0,

    “objectClass”: “alarm”,

    “object”: {

      “uuid”: “f29dd4ca-df58-4702-8a14-71cbf198b24c”,

      “objectClass”: “stream”

    },

    “message”: “Failed to transfer data: Couldn’t connect to server”,

    “timestamp”: “2022-05-05T13:52:14.064584Z”,

    “event”: “E1007”

  },

  {

    “uuid”: “7e7f5ec0-875a-45cd-b1a7-0b48c4ebdece”,

    “attributes”: [],

    “rev”: 0,

    “objectClass”: “alarm”,

    “object”: {

      “uuid”: “1434beb7-02a4-4615-8cb1-e3fb894497f1”,

      “objectClass”: “stream”

    },

    “message”: “Selected soundcard not found”,

    “timestamp”: “2022-05-05T13:49:10.114613Z”,

    “event”: “E1007”

  }

]

Each alarm object contains an event code, a timestamp, and a reference to identify the object that caused the alarm.

 

7. Updating an Object

Updates of existing obejcts may be achieved in two ways. The first is to use a PUT request to send a new version of the object to the WebAPI. For example, if the PIPE (represented by the stream object from above) shall be stopped, the field pendingState must be set to inactive and the modified object must be sent with a PUT request:

curl –header “Content-Type: application/json” \

     –request PUT \

     –cookie session.jar \

     –data ‘{“objectClass”:”stream”, “uuid”:”6bbfbb3a-49a8-454f-8542-a563d824e67a”, “attributes”:[ ], “rev”:42, “state”:”playing”, “pendingState”:”inactive”, “nChannels”:2, “elements”:[    …    ], “name”:”test pipe”, streamGroup”:””, … }’ \

     http://aixtream-12abcdef/webapi/http/objects/stream/6bbfbb3a-49a8-454f-8542-a563d824e67a

This method is, in most cases not very efficient since the better part of the object remains untouched and just causes unncessecary traffic.

The second, usually more efficient way, is to use a PATCH request and the JSON patch syntax (http://jsonpatch.com/) to update only certain fields within the object. The same example from above (stopping the PIPE) would result in this call:

curl –header “Content-Type: application/json” \

     –request PATCH \

     –cookie session.jar \

     –data ‘[{“op”:”replace”,”path”:”/pendingState”,”value”:”inactive”}]’ \

     http://aixtream-12abcdef/webapi/http/objects/stream/6bbfbb3a-49a8-454f-8542-a563d824e67a

  

8. Method Objects (RPC)

There are a few actions available in aixtream that are not well representable in REST-compatible object form. Such actions may be triggered via classic RPC. The communicated JSON objects are only valid in the scope of the present call. An interesting example is the automatic triggering of a config export:

curl –header “Content-Type:application/json” \

     –request POST \

     –cookie session.jar \

     –data ‘{“methodClass”:”configExport”,”password”:”test”}’ \

     https://aixtream-12abcdef/webapi/http/methods/configExport

The output is a method object that contains the exported configuration file in base64-encoded form under the data field.

 

9. Obtaining System Status

Apart from explicitly retrieving the PIPE status and alarm objects, a quick overview of the system status may also be obtained under https://aixtream-12abcdef/webapi/http/status which just returns a JSON object listing many details about the current operating condition of the system.

 

Final Words

With this brief writeup I want to summarize the essential principles behind our WebAPI, while also offering you a few common practical examples. It is of course in no way a comprehensive programming reference. Yet, for further insights, you can easily inspect and learn from the network communication of our official frontend with the help of your browser (F12 key, network tab).

You should also know that we do our best to keep the API stable and backwads compatible across updates (although we cannot always guarantee this for every tiny detail). Usually, your self-written automation scripts should continue to work after every update. Should that ever not be the case, or if you have questions or specific requests, you can always contact our very committed support team.

 

 

 

Written by Bernd Geiser

Bernd studied Electrical Engineering & Information Technology at the RWTH Aachen, receiving the Dr.-Ing. degree in 2012 with contributions to backwards compatible speech and audio coding and standardization. At Ferncast, he is responsible for implementation of audio signal processing algorithms as well as audio transmission systems.

May 18, 2022

You may also like…