API Documentation

The my-devices.net REST API

The reflector server provides a REST API for programmatically querying and modifying device meta information. Using the API you can get a list of devices, search for a device, get and modify device properties, create and delete devices.

Endpoint

The HTTP or HTTPS endpoint for all API requests is api.my-devices.net. We highly recommend using HTTPS, especially if sensitive data like usernames and passwords are transmitted. This is especially true if HTTP Basic Authentication is used.

Authentication

The API supports two authentication mechanisms. The first is HTTP Basic Authentication (over HTTPS), the other one is session-based authentication. For Basic Authentication, the username and password must be supplied in the Authorization header with every HTTP request.

Note: all following examples use username "user" and password "s3cr3t".

Following is an example for a request using Basic Authentication:

GET /my-devices/api/devices HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

The second authentication mechanism is session-based authentication. This uses a session cookie, which must be passed with every request. To obtain a valid session cookie, a Login request must be sent to the server. This is a POST request to the server root ("/"), with the username and password supplied as form-encoded parameters in the request body.

POST / HTTP/1.1 Host: api.my-devices.net Connection: Close Content-Length: 42 Content-Type: application/x-www-form-urlencoded action=login&username=user&password=s3cr3t

The following parameters must be given:

  • action: This must always have the value login.
  • username: The name of the user.
  • password: The user's password.

Additionally, the following optional parameters can be passed:

  • onsuccess: The URI of a page to redirect to if the login was successful. If this is given and authentication was successful, the response will have a 303 See Other status with a Location header containing the URI given here.
  • onfailure: Similar to onsuccess, the URI given here will be used if authentication failed.

If onsuccess and onfailure are not given, the response status will be 200 OK if authentication succeeded, or 401 Unauthorized if authentication failed.

If authentication was successful, the response will include a Set-Cookie header containing the session cookie. This session cookie must be passed in with all API requests.

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 10:35:30 GMT Set-Cookie: osp.web.session.my-devices=000000075EA788B0; domain=.my-devices.net; path=/; expires=Thu, 01 Mar 2012 12:35:30 GMT

Here is an example for using the session cookie in a REST request:

GET /my-devices/api/devices HTTP/1.1 Host: api.my-devices.net Cookie: osp.web.session.my-devices=000000075EA788B0 Connection: Close

Some API requests, specifically getting and setting device properties, can also be made using device credentials. Device UUID and device password must be supplied using HTTP Basic authentication. A device password must have been set using the "password" device property. The special device UUID "self" must be used in the resource path instead of the actual device UUID (which is passed in the Authorization header).

Accessing Device Web Servers

The device web server of any device that is connected to the reflector server can be reached under the address <id>.my-devices.net, where <id> is the UUID identifying the device.

To access the device, a valid session cookie is required. Alternatively, HTTP Basic Authentication can be used to provide authentication info. However, as to not conflict with possible authentication required by the device itself, the authentication information is not passed via the Authorization header, but via the X-PTTH-Authorization header instead.

Example:

GET / HTTP/1.1 Host: a2359c27-cb1f-4692-8490-22d412ac87ba.my-devices.net X-PTTH-Authorization: Basic dXNlcjpzM2NyM3Q=

This is a very useful feature for programmatically "pushing" data to devices, using a POST or PUT request to the device's web server.

Browsing Devices

For browsing all available devices, send a GET request to /my-devices/api/devices. Optionally, parameters can be supplied to filter or limit the result.

To get a list of all devices, that are online, send the following request:

GET /my-devices/api/devices HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

The response will contain a JSON array of objects holding device properties (id, domain, name, online, etc.) in the body:

HTTP/1.1 200 OK Cache-Control: no-cache Connection: Close Content-Type: application/json Date: Thu, 01 Mar 2012 11:25:31 GMT Transfer-Encoding: chunked [ { "name": "Axis Network Camera", "geolocation": "46.528760, 14.099177", "port": "0", "lastConnect": "2012-03-01T11:25:02Z", "id": "0a72da53-9de5-44c8-9adf-0090e80e20a7", "host": "80.122.195.86", "online": true, "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Network camera via Reverse HTTP Proxy" }, { "name": "Web HMI Demo", "geolocation": " 46.528760, 14.099177", "port": "0", "lastConnect": "2012-03-01T11:25:26Z", "id": "33a9c5a3-81d8-4d3a-8068-1c910b3c61f6", "host": "188.22.62.220", "online": true, "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Industrial HMI built with web technologies", "hardware": "Digi ConnectCore 9C" }, { "name": "iWeatherStation", "geolocation": "46.528760, 14.099177", "port": "0", "lastConnect": "2012-03-01T11:25:15Z", "id": "a2359c27-cb1f-4692-8490-22d412ac87ba", "host": "80.122.195.86", "online": true, "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Internet-based weather station device", "hardware": "SSV DNP/9200" } ]

Note: in order to improve readability, the chunk sizes have been stripped from the responses shown in this document.

The following parameters can be added:

  • query: Specify a whitespace-separated list of keywords to only return devices matching these keywords. If any of the keywords are found in the name, description or tags properties of the device, then the device will be included in the result.
  • sort: Specify a sort criteria to order the result by. Valid values are domain, id, host, lastConnect, name, online and protocol.
  • dir: Specify sort direction. Valid values are asc (default) and desc.
  • fromIndex: A zero-based index of the first desired result. This is used for paging output, along with maxResults.
  • maxResults: Maximum number of results for paged output. Usually used together with fromIndex.
  • status: Only include devices with the given online status. Valid values are online, offline and all.

Example: Browse for all devices containing the keyword "axis" in their name, description or tags and order by last connect time:

GET /my-devices/api/devices?query=axis&sort=lastConnect HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

Server Response:

HTTP/1.1 200 OK Cache-Control: no-cache Connection: Close Content-Type: application/json Date: Thu, 01 Mar 2012 11:19:21 GMT Transfer-Encoding: chunked [ { "name": "Axis Network Camera", "geolocation": "46.528760, 14.099177", "port": "0", "lastConnect": "2012-03-01T11:19:07Z", "id": "0a72da53-9de5-44c8-9adf-0090e80e20a7", "host": "80.122.195.86", "online": true, "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Network camera via Reverse HTTP Proxy" } ]

Example: paged results:

GET /my-devices/api/devices?firstIndex=1&maxResults=10 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

Getting Properties of a Specific Device

To return all device properties for a device identified by its UUID, issue a GET request to /my-devices/api/device/<id>, where <id> is replaced with the device UUID.

Example:

GET /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

Server Response:

HTTP/1.1 200 OK Cache-Control: no-cache Connection: Close Content-Type: application/json Date: Thu, 01 Mar 2012 11:36:32 GMT Transfer-Encoding: chunked { "name": "Axis Network Camera", "geolocation": "46.528760, 14.099177", "port": "0", "lastConnect": "2012-03-01T11:35:59Z", "id": "0a72da53-9de5-44c8-9adf-0090e80e20a7", "host": "80.122.195.86", "online": true, "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Network camera via Reverse HTTP Proxy" }

It is also possible to only return a specific property. To do this, the name of the property must be added to the request URI:

GET /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7/name HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close

Server Response:

HTTP/1.1 200 OK Cache-Control: no-cache Connection: Close Content-Type: application/json Date: Thu, 01 Mar 2012 11:36:32 GMT Transfer-Encoding: chunked { "name": "Axis Network Camera" }

A device can query its own properties if a device password has been set using the "password" device property. The device UUID and password are used to authenticate the request. Instead of the device UUID, the special keyword "self" is used in the resource path.

GET /my-devices/api/device/self/name HTTP/1.1 Host: api.my-devices.net Authorization: Basic MGE3MmRhNTMtOWRlNS00NGM4LTlhZGYtMDA5MGU4MGUyMGE3OnMzY3IzdA== Connection: Close

Server Response:

HTTP/1.1 200 OK Cache-Control: no-cache Connection: Close Content-Type: application/json Date: Thu, 01 Mar 2012 11:36:32 GMT Transfer-Encoding: chunked { "name": "Axis Network Camera" }

Setting Properties of a Specific Device

The properties of a device can be modified, and new properties can be added. This is done with a PUT or PATCH request to /my-devices/api/device/<id>, where <id> is replaced with the device UUID.

The new property values are given through a JSON document in the request body.

PUT and PATCH are equivalent, although PATCH is semantically more appropriate.

Example:

PUT /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close Content-Type: application/json Content-Length: 38 { "name": "Axis Network Camera" }

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:38:24 GMT

Note: System properties (id, domain, online, lastConnect, host and port) cannot be modified.

A device can modify its own properties if a device password has been set using the "password" device property. The device UUID and password are used to authenticate the request. Instead of the device UUID, the special keyword "self" is used in the resource path.

Example:

PUT /my-devices/api/device/self HTTP/1.1 Host: api.my-devices.net Authorization: Basic MGE3MmRhNTMtOWRlNS00NGM4LTlhZGYtMDA5MGU4MGUyMGE3OnMzY3IzdA== Connection: Close Content-Type: application/json Content-Length: 38 { "name": "Axis Network Camera" }

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:38:24 GMT

Deleting a Device Property

A device property can be deleted with a DELETE request to /my-devices/api/device/<id>/<prop>, where <id> is replaced with the device UUID and <prop> is replaced with the property name.

Example:

DELETE /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7/tags HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close Content-Length: 0

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:44:32 GMT

Deleting a Device

A device can be deleted with a DELETE request to /my-devices/api/device/<id>, where <id> is replaced with the device UUID.

Deleting a device is normally only allowed if the device is offline. However, by adding the X-PTTH-Force: disconnect header to the request, the device will be disconnected before being deleted.

Example:

DELETE /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close Content-Length: 0

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:44:32 GMT

Creating a Device

A device can be created with a POST request to /my-devices/api/device/<id>, where <id> is replaced with the device UUID of the new device.

The new device properties must be passed as JSON object in the request body. The properties must at least include domain and name. The id property must not be included. The id and online properties will be set automatically.

Example:

POST /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close Content-Length: 195 { "name": "Axis Network Camera", "geolocation": "46.528760, 14.099177", "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Network camera via Reverse HTTP Proxy" }

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:44:32 GMT

Creating or Updating a Device

POST can also be used to update an existing device's properties. For this to work, a X-PTTH-If-Exists: update header must be included in the request.

If this header is included, and the device with the given ID already exists, it's properties will be updated. If the device does not exist, it will be created.

Example:

POST /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= Connection: Close Content-Length: 195 X-PTTH-If-Exists: update { "name": "Axis Network Camera", "geolocation": "46.528760, 14.099177", "domain": "e3efbb09-f384-4c00-8e7a-e18b8e93c362", "description": "Network camera via Reverse HTTP Proxy" }

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:44:32 GMT

HTTP Method Override (Firewall)

If your firewall does not allow HTTP PUT or HTTP DELETE requests, you can send a POST request and add the X-HTTP-Method-Override header to specify the actual method to use. Please note that method names are case sensitive. Example:

POST /my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7 HTTP/1.1 Host: api.my-devices.net Authorization: Basic dXNlcjpzM2NyM3Q= X-HTTP-Method-Override: DELETE Connection: Close Content-Length: 0

Server Response:

HTTP/1.1 200 OK Connection: Close Content-Length: 0 Date: Thu, 01 Mar 2012 11:44:32 GMT

Cross-Origin Resource Sharing (CORS)

The API supports CORS and thus allows you to invoke the API from browser-based applications served from another domain. In the standard setup, CORS is allowed for all domains, but this can be changed by the server administrator to a specific domain, if required.

Error Handling

The following conventions are used by the API for reporting errors:

  • A successful action will always result in a 200 OK response.
  • If a device or property does not exist, a 404 Not Found response is returned.
  • An attempt to create a device that already exists results in a 409 Conflict response.
  • If no authentication information or bad credentials are provided, a 401 Unauthorized response is returned.
  • An incorrect HTTP method results in a 405 Method Not Allowed response.
  • If the URI is malformed, a 400 Bad Request response is returned.
  • If the server encounters an error during processing the request, a 500 Internal Server Error response is returned.

cURL Examples

The well-known cURL utility can be used to test the API.

Example 1: Get a list of all devices:

curl -uuser:s3cr3t https://api.my-devices.net/my-devices/api/devices?status=all

Example 2: Get the properties of a specific device

curl -uuser:s3cr3t \ https://api.my-devices.net/my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7

Example 3: Set a device property:

curl -uuser:s3cr3t --request PUT \ --data '{ "name": "My Network Camera" }' \ --header 'Content-Type: application/json' \ https://api.my-devices.net/my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7

jQuery Examples

Example 1: Get and display a list of devices

<DOCTYPE html> <html> <head> <title>my-devices.net API Example</title> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> </head> <body> <h1>my-devices.net API Example</h1> <div id="result"></div> <script> $.ajax({ url : 'https://api.my-devices.net/my-devices/api/devices', type: 'GET', username: 'user', password: 's3cr3t', xhrFields: { withCredentials: true }, success: function(data, textStatus, jqXHR) { var result = "<table><tr><th>ID</th><th>Name</th></tr>"; for (var i = 0; i < data.length; i++) { var device = data[i]; result = result + "<tr>" + "<td>" + device.id + "</td>" + "<td>" + device.name + "</td>" + "</tr>" } result = result + "</table>"; $('#result').html(result); }, error: function (jqXHR, textStatus, errorThrown) { $('#result').text(textStatus + ": " + errorThrown); } }); </script> </body> </html>

Example 2: Get and display the properties of a device

<DOCTYPE html> <html> <head> <title>my-devices.net API Example</title> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> </head> <body> <h1>my-devices.net API Example</h1> <div id="result"></div> <script> $.ajax({ url : 'https://api.my-devices.net/my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7', type: 'GET', username: 'user', password: 's3cr3t', xhrFields: { withCredentials: true }, success: function(data, textStatus, jqXHR) { var result = "<table><tr><th>Name</th><th>Value</th></tr>"; for (prop in data) { result = result + "<tr>" + "<td>" + prop + "</td>" + "<td>" + data[prop] + "</td>" + "</tr>" } result = result + "</table>"; $('#result').html(result); }, error: function (jqXHR, textStatus, errorThrown) { $('#result').text(textStatus + ": " + errorThrown); } }); </script> </body> </html>

Example 3: Setting properties of a device

<DOCTYPE html> <html> <head> <title>my-devices.net API Example</title> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> </head> <body> <h1>my-devices.net API Example</h1> <div id="result"></div> <script> $.ajax({ url : 'https://api.my-devices.net/my-devices/api/device/0a72da53-9de5-44c8-9adf-0090e80e20a7', type: 'PUT', contentType: 'application/json', data: JSON.stringify( { name: 'My Network Camera', description: 'This is a network camera' }), username: 'user', password: 's3cr3t', xhrFields: { withCredentials: true }, success: function(data, textStatus, jqXHR) { $('#result').text("Success!"); }, error: function (jqXHR, textStatus, errorThrown) { $('#result').text(textStatus + ": " + errorThrown); } }); </script> </body> </html>

HTTP Proxy

The reflector server can act as a HTTP proxy supporting TCP connection tunneling via HTTP CONNECT requests. Any network client supporting connections through a HTTP proxy can open a connection to a device connected to the reflector server. Note that only the CONNECT method is supported. Proxying normal HTTP requests (GET, POST, etc.) is not supported.

To open a tunnel connection, send a HTTP CONNECT request to the reflector server and supply the username and password via the Proxy-Authorization header. The following example opens a connection for tunneling SSH:

CONNECT 0a72da53-9de5-44c8-9adf-0090e80e20a7.my-devices:22 HTTP/1.1 Host: 0a72da53-9de5-44c8-9adf-0090e80e20a7.my-devices:22 Proxy-Authorization: Basic dXNlcjpzM2NyM3Q=

One important drawback of this approach is that your credentials are transmitted in clear-text unless you use HTTPS for the CONNECT request. Unfortunately, most clients do not support HTTPS connections to the proxy server.

Table of Contents