MistServer  2.5.3-Pro-19-gf5e75b1 ( Generic_64)
API calls

Listing of all controller API calls.

The controller listens for commands through a JSON-based API. This page describes the API in full.

A default interface implementing this API as a single HTML page is included in the controller itself. This default interface will be send for invalid API requests, and is thus triggered by default when a browser attempts to access the API port directly. The default API port is 4242 - but this can be changed through both the API and commandline parameters.

To send an API request, simply send a HTTP request to this port for any file, and include either a GET or POST parameter called "command", containing a JSON object as payload. Nearly all members of the request object are optional, and described below. A simple example request logging in to the system would look like this:

GET /api?command={"authorize":{"username":"test","password":"941d7b88b2312d4373aff526cf7b6114"}} HTTP/1.0

Or, when properly URL encoded:

GET /api?command=%7B%22authorize%22%3A%7B%22username%22%3A%22test%22%2C%22password%22%3A%22941d7b88b2312d4373aff526cf7b6114%22%7D%7D HTTP/1.0

The server is quite lenient about not URL encoding your strings, but it's a good idea to always do it, anyway. See the "authorize" section below for more information about security and logging in.

As mentioned above, sending an invalid request will trigger a response containing the default interface. As you may not want to receive a big HTML page as response to an invalid request, requesting the file "/api" (as done in the example above) will force a JSON response, even when the request is invalid.

You may also include a "callback" or "jsonp" HTTP variable, to trigger JSONP compatibility mode. JSONP is useful for getting around the cross-domain scripting protection in most modern browsers. Developers creating non-JavaScript applications will most likely not want to use JSONP mode, though nothing is stopping you if you really want to.

Global Controller::authorize (JSON::Value &Request, JSON::Value &Response, Socket::Connection &conn)
To login, an "authorize" request must be sent. Since HTTP does not use persistent connections, you are required to re-sent authentication with every API request made. To prevent plaintext sending of the password, a random challenge string is sent first, and then the password is hashed together with this challenge string to create a one-time-use string to login with. If the user is not authorized, this request is the only request the server will respond to until properly authorized. "authorize" requests take the form of:
{
//username to login as
"username": "test",
//hash of password to login with. Send empty value when no challenge for the hash is known yet.
//When the challenge is known, the value to be used here can be calculated as follows:
// MD5( MD5("secret") + challenge)
//Where "secret" is the plaintext password.
"password": ""
}
and are responded to as:
{
//current login status. Either "OK", "CHALL", "NOACC" or "ACC_MADE".
"status": "CHALL",
//Random value to be used in hashing the password.
"challenge": "abcdef1234567890"
}
The challenge string is sent for all statuses, except "NOACC", where it is left out. A status of "OK" means you are currently logged in and have access to all other API requests. A status of "CHALL" means you are not logged in, and a challenge has been provided to login with. A status of "NOACC" means there are no valid accounts to login with. In this case - and ONLY in this case - it is possible to create a initial login through the API itself. To do so, send a request as follows:
{
//username to create, as plain text
"new_username": "test",
//password to set, as plain text
"new_password": "secret"
}
Please note that this is NOT secure. At all. Never use this mechanism over a public network! A status of "ACC_MADE" indicates the account was created successfully and can now be used to login as normal.
Global Controller::checkCapable (JSON::Value &capa)
"capabilities" requests are always empty:
{}
and are responded to as:
{
"connectors": { // a list of installed connectors
"FLV": { //name of the connector. This is based on the executable filename, with the "MistIn" / "MistConn" prefix stripped.
"codecs": [ //supported combinations of codecs.
[["H264","H263","VP6"],["AAC","MP3"]] //one such combination, listing simultaneously available channels and the codec options for those channels
],
"deps": "HTTP", //dependencies on other connectors, if any.
"desc": "Enables HTTP protocol progressive streaming.", //human-friendly description of this connector
"methods": [ //list of supported request methods
{
"handler": "http", //what handler to use for this request method. The "http://" part of a URL, without the "://".
"priority": 5, // priority of this request method, higher is better.
"type": "flash/7" //type of request method - usually name of plugin followed by the minimal plugin version, or 'HTML5' for pluginless.
}
],
"name": "HTTP_Progressive_FLV", //Full name of this connector.
"optional": { //optional parameters
"username": { //name of the parameter
"help": "Username to drop privileges to - default if unprovided means do not drop privileges", //human-readable help text
"name": "Username", //human-readable name of parameter
"option": "--username", //command-line option to use
"type": "str" //type of option - "str" or "num"
}
//above structure repeated for all (optional) parameters
},
//above structure repeated, as "required" for required parameters, if any.
"socket": "http_progressive_flv", //unix socket this connector listens on, if any
"url_match": "/$.flv", //URL pattern to match, if any. The $ substitutes the stream name and may not be the first or last character.
"url_prefix": "/progressive/$/", //URL prefix to match, if any. The $ substitutes the stream name and may not be the first or last character.
"url_rel": "/$.flv" //relative URL where to access a stream through this connector.
}
//... above structure repeated for all installed connectors.
},
"cpu": [ //a list of installed CPUs
{
"cores": 4, //amount of cores for this CPU
"mhz": 1645, //speed in MHz for this CPU
"model": "Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz", //model identifier, for humans
"threads": 8 //amount of simultaneously executing threads that are supported on this CPU
}
//above structure repeated for all installed CPUs
],
"load": {
"fifteen": 72,
"five": 81,
"memory": 42,
"one": 124
},
"mem": {
"cached": 1989, //current memory usage of system caches, in MiB
"free": 2539, //free memory, in MiB
"swapfree": 0, //free swap space, in MiB
"swaptotal": 0, //total swap space, in MiB
"total": 7898, //total memory, in MiB
"used": 3370 //used memory, in MiB (excluding system caches, listed separately)
},
"speed": 6580, //total speed in MHz of all CPUs cores summed together
"threads": 8 //total count of all threads of all CPUs summed together
}
Global Controller::checkConfig (JSON::Value &in, JSON::Value &out)
"config" requests take the form of:
{
"controller": { //controller settings
"interface": null, //interface to listen on. Defaults to all interfaces.
"port": 4242, //port to listen on. Defaults to 4242.
"username": null //username to drop privileges to. Defaults to root.
},
"protocols": [ //enabled connectors / protocols
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
},
//above structure repeated for all enabled connectors / protocols
],
"serverid": "", //human-readable server identifier, optional.
}
and are responded to as:
{
"controller": { //controller settings
"interface": null, //interface to listen on. Defaults to all interfaces.
"port": 4242, //port to listen on. Defaults to 4242.
"username": null //username to drop privileges to. Defaults to root.
},
"protocols": [ //enabled connectors / protocols
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
"online": 1 //boolean value indicating if the executable is running or not
},
//above structure repeated for all enabled connectors / protocols
],
"serverid": "", //human-readable server identifier, as configured.
"time": 1398982430, //current unix time
"version": "2.0.2/8.0.1-23-gfeb9322/Generic_64" //currently running server version string
}
Global Controller::CheckStreams (JSON::Value &in, JSON::Value &out)
"streams" requests take the form of:
{
"streamname_here": { //name of the stream
"source": "/mnt/media/a.dtsc" //full path to a VoD file, or "push://" followed by the IP or hostname of the machine allowed to push live data. Empty means everyone is allowed to push live data.
"DVR": 30000 //optional. For live streams, indicates the requested minimum size of the available DVR buffer in milliseconds.
},
//the above structure repeated for all configured streams
}
and are responded to as:
{
"streamname_here": { //name of the configured stream
"error": "Available", //error state, if any. "Available" is a special value for VoD streams, indicating it has no current viewers (is not active), but is available for activation.
"h_meta": 1398113185, //unix time the stream header (if any) was last processed for metadata
"l_meta": 1398115447, //unix time the stream itself was last processed for metadata
"meta": { //available metadata for this stream, if any
"format": "dtsc", //detected media source format
"tracks": { //list of tracks in this stream
"audio_AAC_2ch_48000hz_2": {//human-readable track name
"bps": 16043,
"channels": 2,
"codec": "AAC",
"firstms": 0,
"init": "\u0011Vå\u0000",
"lastms": 596480,
"rate": 48000,
"size": 16,
"trackid": 2,
"type": "audio"
},
//the above structure repeated for all tracks
},
"vod": 1 //indicates VoD stream, or "live" to indicated live stream.
},
"name": "a", //the stream name, guaranteed to be equal to the object name.
"online": 2, //online state. 0 = error, 1 = active, 2 = inactive.
"source": "/home/thulinma/a.dtsc" //source for this stream, as configured.
},
//the above structure repeated for all configured streams
}
Through this request, ALL streams must always be configured. To remove a stream, simply leave it out of the request. To add a stream, simply add it to the request. To edit a stream, simply edit it in the request. The LTS edition has additional requests that allow per-stream changing of the configuration.
Global Controller::CheckUpdateInfo ()
"update" and "checkupdate" requests (LTS-only) are responded to as: ~~~~~~~~~~~~~~~{.js} { "error": "Something went wrong", // 'Optional' "release": "LTS64_99", "version": "1.2 / 6.0.0", "date": "January 5th, 2014", "uptodate": 0, "needs_update": ["MistBuffer", "MistController"], //Controller is guaranteed to be last "MistController": "abcdef1234567890", //md5 sum of latest version //...
Global Controller::fillActive (JSON::Value &req, JSON::Value &rep, bool onlyNow=false)
"active_streams" and "stats_streams" requests may either be empty, in which case the response looks like this:
[
//Array of stream names
"streamA",
"streamB",
"streamC"
]
"stats_streams" will list all streams that any statistics data is available for, and only those. "active_streams" only lists streams that are currently active, and only those. If the request is an array, which may contain any of the following elements:
[
//Array of requested data types
"clients", //Current viewer count
"lastms" //Current position in the live buffer, if live
]
In which case the response is changed into this format:
{
//Object of stream names, containing arrays in the same order as the request, with the same data
"streamA":[
0,
60000
]
"streamB":[
//....
]
//...
}
All streams that any statistics data is available for are listed, and only those streams.
Global Controller::fillClients (JSON::Value &req, JSON::Value &rep)
"clients" requests take the form of:
{
//array of streamnames to accumulate. Empty means all.
"streams": ["streama", "streamb", "streamc"],
//array of protocols to accumulate. Empty means all.
"protocols": ["HLS", "HSS"],
//list of requested data fields. Empty means all.
"fields": ["host", "stream", "protocol", "conntime", "position", "down", "up", "downbps", "upbps"],
//unix timestamp of measuring moment. Negative means X seconds ago. Empty means now.
"time": 1234567
}
OR
[
{},//request object as above
{}//repeat the structure as many times as wanted
]
and are responded to as:
{
//unix timestamp of data. Always present, always absolute.
"time": 1234567,
//array of actually represented data fields.
"fields": [...]
//for all clients, the data in the order they appear in the "fields" field.
"data": [[x, y, z], [x, y, z], [x, y, z]]
}
In case of the second method, the response is an array in the same order as the requests.
Global Controller::fillTotals (JSON::Value &req, JSON::Value &rep)
"totals" requests take the form of:
{
//array of streamnames to accumulate. Empty means all.
"streams": ["streama", "streamb", "streamc"],
//array of protocols to accumulate. Empty means all.
"protocols": ["HLS", "HSS"],
//list of requested data fields. Empty means all.
"fields": ["clients", "downbps", "upbps"],
//unix timestamp of data start. Negative means X seconds ago. Empty means earliest available.
"start": 1234567
//unix timestamp of data end. Negative means X seconds ago. Empty means latest available (usually 'now').
"end": 1234567
}
OR
[
{},//request object as above
{}//repeat the structure as many times as wanted
]
and are responded to as:
{
//unix timestamp of start of data. Always present, always absolute.
"start": 1234567,
//unix timestamp of end of data. Always present, always absolute.
"end": 1234567,
//array of actually represented data fields.
"fields": [...]
// Time between datapoints. Here: 10 points with each 5 seconds afterwards, followed by 10 points with each 1 second afterwards.
"interval": [[10, 5], [10, 1]],
//the data for the times as mentioned in the "interval" field, in the order they appear in the "fields" field.
"data": [[x, y, z], [x, y, z], [x, y, z]]
}
In case of the second method, the response is an array in the same order as the requests.
Global Controller::handleAPIConnection (Socket::Connection &conn)

"addstream" requests (LTS-only) take the form of:

{
"streamname": {
//Stream configuration - see the "streams" call for details on this format.
}
}

These requests will add new streams or update existing streams with the same names, without touching other streams. In other words, this call can be used for incremental updates to the stream list instead of complete updates, like the "streams" call. Sending "addstream" or "deletestream" as part of your request will alter the "streams" response. As opposed to a full list of streams, this will now include a property "incomplete list" set to 1 and only include successfully added streams. As deletions cannot fail, these are never mentioned.

"deletestream" requests (LTS-only) take the form of:

{
"streamname": {} //any contents in this object are ignored
}

OR

[
"streamname",
]

OR

"streamname"

These requests will remove the named stream(s), without touching other streams. In other words, this call can be used for incremental updates to the stream list instead of complete updates, like the "streams" call. Sending "addstream" or "deletestream" as part of your request will alter the "streams" response. As opposed to a full list of streams, this will now include a property "incomplete list" set to 1 and only include successfully added streams. As deletions cannot fail, these are never mentioned.

"addprotocol" requests (LTS-only) take the form of:

{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}

OR

[
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}
]

These requests will add the given protocol configurations, without touching existing configurations. In other words, this call can be used for incremental updates to the protocols list instead of complete updates, like the "config" call. There is no response to this call.

"deleteprotocol" requests (LTS-only) take the form of:

{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}

OR

[
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}
]

These requests will remove the given protocol configurations (exact matches only), without touching other configurations. In other words, this call can be used for incremental updates to the protocols list instead of complete updates, like the "config" call. There is no response to this call.

"browse" requests take the form of:

//A string, containing the path for which to discover contents. Empty means current working directory.
"/tmp/example"

and are responded to as:

[
//The folder path
"path":"/tmp/example"
//An array of strings showing all files
"files":
["file1.dtsc",
"file2.mp3",
"file3.exe"
]
//An array of strings showing all subdirectories
"subdirectories":[
"folder1"
]
]

"save" requests are always empty:

{}

Sending this request will cause the controller to write out its currently active configuration to the configuration file it was loaded from (the default being ./config.json).

"ui_settings" requests can take two forms. The first is the "set" form:

{
//Any data here
}

The second is the "request" form, and takes any non-object as argument. When using the set form, this will write the given object verbatim into the controller storage. No matter which form is used, the current contents of the ui_settings object are always returned in the response. This API call is intended to store User Interface settings across sessions, and its contents are completely ignored by the controller itself. Besides the requirement of being an object, the contents are entirely free-form and may technically be used for any purpose.

LTS builds will always include an "LTS" response, set to 1.

"autoupdate" requests (LTS-only) will cause MistServer to apply a rolling update to itself, and are not responded to.

"log" responses are always sent, and cannot be requested:

[
[
1398978357, //unix timestamp of this log message
"CONF", //shortcode indicating the type of log message
"Starting connector: {\"connector\":\"HTTP\"}" //string containing the log message itself
],
//the above structure repeated for all logs
]

It's possible to clear the stored logs by sending an empty "clearstatlogs" request.

"deletestream" requests (LTS-only) take the form of:

{
"streamname": {} //any contents in this object are ignored
}

OR

[
"streamname",
]

OR

"streamname"

These requests will remove the named stream(s), without touching other streams. In other words, this call can be used for incremental updates to the stream list instead of complete updates, like the "streams" call. Sending "addstream" or "deletestream" as part of your request will alter the "streams" response. As opposed to a full list of streams, this will now include a property "incomplete list" set to 1 and only include successfully added streams. As deletions cannot fail, these are never mentioned.

"addprotocol" requests (LTS-only) take the form of:

{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}

OR

[
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}
]

These requests will add the given protocol configurations, without touching existing configurations. In other words, this call can be used for incremental updates to the protocols list instead of complete updates, like the "config" call. There is no response to this call.

"deleteprotocol" requests (LTS-only) take the form of:

{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}

OR

[
{
"connector": "HTTP" //Name of the connector to enable
//any required and/or optional settings may be given here as "name": "value" pairs inside this object.
}
]

These requests will remove the given protocol configurations (exact matches only), without touching other configurations. In other words, this call can be used for incremental updates to the protocols list instead of complete updates, like the "config" call. There is no response to this call.

"browse" requests take the form of:

//A string, containing the path for which to discover contents. Empty means current working directory.
"/tmp/example"

and are responded to as:

[
//The folder path
"path":"/tmp/example"
//An array of strings showing all files
"files":
["file1.dtsc",
"file2.mp3",
"file3.exe"
]
//An array of strings showing all subdirectories
"subdirectories":[
"folder1"
]
]

"save" requests are always empty:

{}

Sending this request will cause the controller to write out its currently active configuration to the configuration file it was loaded from (the default being ./config.json).

"ui_settings" requests can take two forms. The first is the "set" form:

{
//Any data here
}

The second is the "request" form, and takes any non-object as argument. When using the set form, this will write the given object verbatim into the controller storage. No matter which form is used, the current contents of the ui_settings object are always returned in the response. This API call is intended to store User Interface settings across sessions, and its contents are completely ignored by the controller itself. Besides the requirement of being an object, the contents are entirely free-form and may technically be used for any purpose.

LTS builds will always include an "LTS" response, set to 1.

"autoupdate" requests (LTS-only) will cause MistServer to apply a rolling update to itself, and are not responded to.

"log" responses are always sent, and cannot be requested:

[
[
1398978357, //unix timestamp of this log message
"CONF", //shortcode indicating the type of log message
"Starting connector: {\"connector\":\"HTTP\"}" //string containing the log message itself
],
//the above structure repeated for all logs
]

It's possible to clear the stored logs by sending an empty "clearstatlogs" request.