Making requests

Requests should be made to the API server over HTTPS and using a valid TLS client certificate.

Requests must set the Accept-Encoding header to include gzip, otherwise they may be rejected.

Note that some request may be redirected, so redirects must be followed.

Responses will have appropriate cache headers.

When {host}/{item} appears as part of a path, these refer to the host id and item key of the sensor or configurable item.

Requesting all sensors / current data

Make a GET request for the path /v0.

The response will be a JSON array of hosts, including all their sensors and configurable items.

Notice about lastvalue / lastclock

This request might not include lastvalue and lastclock values, since those might not exist or might be far in the past. Older data points might be filled in at later requests, or could simply not be available.

It has in practice been found that you seldom need 1500+ values at once for display purposes.

Requesting prototypes

To get all prototypes, make a GET request for the path /v0/prototypes.

The response will be a JSON array of prototypes.

To get a single prototype, make a GET request for the path /v0/prototypes/{id}.

Requesting all hosts without items

Make a GET request for the path /v0/hosts.

The response will be in the same format as the /v0 request, except that the hosts will not have an items property.

Requesting latest changes

Make a GET request for the path /v0/changed/{since}

{since} is a number in Unix-time. Only data that has changed after this time is included.

The response will be a JSON array of hosts, with those items that have changed recently enough.

Requesting items on a host

Make a GET request for the path /v0/{host}

The response will be a JSON array of items on the host.

Requesting data for an item on a host

Make a GET request for the path /v0/{host}/{item}

The response will be a simple JSON object of the latest data on the item.

{
  "key": "modbus.00124b0002741ede.L_LME021CG.3.24",
  "name": "00124b0002741ede 3.24 Total active electricity",
  "lastvalue": 50.24,
  "unit": "kWh",
  "configurable": false,
  "lastclock": 1453314469
}

Historical data

These requests respond with an array of history data.

Requesting latest history

Make a GET request for the path /v0/{host}/{item}/history

The response will include up to the latest 15 minutes of data.

Requesting history for a specific period

Make a GET request for the path /v0/{host}/{item}/history/{start}/{end}

{start}/{end} are numbers in Unix-time for the desired time interval.

If data is requested that is not yet available, the request will be redirected to a request for the latest history.

In general the request will be redirected for cacheability. The redirect will be to the same type of URI but with the start- and end times rounded backwards. This means:

  • The response might not return the newest data that was requested, so more requests may be needed to get all desired data
  • The response may contain more, older data than requested
  • The redirect will always be to a period for which complete history is available. The response can be cached, and there is no need to request the history for the time covered by the response again.

Requesting trend data for a specific period

Make a GET request for the path /v0/{host}/{item}/trend/{start}/{end}

{start}/{end} are numbers in Unix-time for the desired time interval.

If a period was requested for which there is no fulfilling data, an error may be raised.

The data will return as a time-series of data:

[
  [1458763440, {"num": 60, "min": 0.1, "avg": 1.2, "max": 2.0}],
  [1458767040, {"num": 60, "min": 0.2, "avg": 1.2, "max": 2.0}],
  [1458770640, {"num": 55, "min": 0.2, "avg": 1.2, "max": 2.0}]
]

Requesting a specific kind of trend data for a period

Make a GET request for any of the following paths:

  • /v0/{host}/{item}/trend/min/{start}/{end}
  • /v0/{host}/{item}/trend/avg/{start}/{end}
  • /v0/{host}/{item}/trend/max/{start}/{end}

The data returned will be a time-series like history data:

[
  [1458763440, 1.2],
  [1458767040, 1.3],
  [1458770640, 1.2],
  ...
]

Changing configurable values

Make a POST request for the path /v0/{host}/{item}/config

The format of the POST data is a JSON object like this:

{
  "target": 58,
  "expected": 60,
  "audit": ["test-user"]
}
  • target is the desired new value
  • expected is the current value
  • audit is an array of strings. The API will add information about the API user to the end of the array, and present it as information for identifying who or what made the change.

The API will perform som validation of the change, and will reject it if it does not follow these rules:

  • The item must be configurable
  • The API user must have permission to update the configuration
  • The expected value must match current value
  • The target value must exactly match the data type of the item
  • The target value must be within the limits of the item as decided by the backend. (There is currently no way to discover the limits through the API.)

The response is a config object, the same as the config property of the configurable item:

{
  "target": 58,
  "expected": 60,
  "audit": ["test-user", "Test_Environment", "api.moodio.se"],
  "lastclock": 1523288729,
  "status": "PENDING",
  "id": "1523288729"
}

The id field is server generated for future enhancements.

Verifying configuration changes

After release v3.4, the configuration state for an item is logged as a JSON-formatted data for the key:

{
  "config": {
    "target": 58,
    "expected": 60,
    "audit": ["test-user", "Test_Environment", "api.moodio.se"],
    "lastclock": 1523288729,
    "status": "PENDING",
    "id": 0
  }
}

Configuration changes may take significant time, and a response to the request indicates that the request has been accepted by the API, not that it has been put into effect.

A PENDING change may still fail or be superseded by a later request.

Completed configuration changes might not contain all the fields of the request.

Example of a completed configuration change:

{
  "config": {
    "target": None,
    "expected": None,
    "audit": [],
    "lastclock": 1523288820,
    "status": "SUCCESS"
  }
}

Success or failure of the change is updated by changing status to SUCCESS or FAILED. Also note that hosts may on their own also create transactions for items, for example when copying values between sensors, or when using direct control loops.

Daily/monthly change statistics

These requests calculate the difference of values over time periods. They are useful for values that only increase over time, such as the energy value of electricity meters.

Requesting monthly change statistics

Make a GET request for the path /v0/{host}/{item}/deltas/{year}/{timezone}. {timezone} is a name from the IANA Time Zone Database, such as UTC or Europe/Stockholm.

The response is a JSON object like this:

{
  "2014": {
    "1": {"delta": 2171},
    "2": {"delta": 1937},
    "3": {"delta": 1612},
    "4": {"delta": 1253},
    "5": {"delta": 725},
    "6": {"delta": 794},
    "7": {"delta": 510},
    "8": {"delta": 546},
    "9": {"delta": 1067},
    "10": {"delta": 1255},
    "11": {"delta": null},
    "12": {"delta": null}
  }
}

Note that there are null values if data is unavailable.

Requesting daily change statistics

Make a GET request for the path /v0/{host}/{item}/deltas/{year}/{month}/{timezone}. {timezone} is a name from the IANA Time Zone Database, such as UTC or Europe/Stockholm.

The response is a JSON object like this:

{
  "2014": {
    "10": {
      "1": {"delta": 125},
      "2": {"delta": 88},
      "3": {"delta": 104},
      "4": {"delta": 118},
      "5": {"delta": 105},
      "6": {"delta": 111},
      "7": {"delta": 106},
      ...
    }
  }
}

Note that there are null values if data is unavailable.

Requesting hourly change statistics

Make a GET request for the path /v0/{host}/{item}/deltas/{year}/{month}/{day}/{timezone}

{timezone} is a name from the IANA Time Zone Database, such as UTC or Europe/Stockholm.

The response is a JSON object like this:

{
  "2014": {
    "10": {
      "4": {
        "0": {"delta": 18},
        "1": {"delta": 25},
        "2": {"delta": 3},
        "3": {"delta": 13},
        ...
      }
    }
  }
}

Note that there are null values if data is unavailable.

Alarm events

Take special care if you depend on up-to-date acknowledgements data:

Caching of data may prevent the latest acknowledgements from showing up in responses, since acknowledgements may be added at any time to any event, possibly in bulk.

But, single event requests are exempt from caching and their responses are guaranteed to contain the most recent acknowledgements.

Requesting an event by id

Make a GET request for the path /v0/events/{id}.

The response will be a single event object. It is not cached and will always contain the most recent acknowledgements.

Deprecated function, events/status

This call turned out to be a bad idea in practice. It's maintained for backwards compatibility but has an increased cache time. Do not use.

Requesting the latest alarm events for all sensors

Make a GET request for one of the following paths:

  • /v0/events
  • /v0/{host}/events
  • /v0/{host}/{item}/events

The response will be a JSON array of event objects, ordered from earlier to later events. It will include up to the latest 15 minutes of data.

If a {host} is specified, only events for that host will be included.

If {host}/{item} is specified, only events for that sensor will be included.

Requesting all alarm events for a specific period

Make a GET request for one of the following paths:

  • /v0/events/{start}/{end}
  • /v0/{host}/events/{start}/{end}
  • /v0/{host}/{item}/events/{start}/{end}

{start}/{end} are numbers in Unix-time for the desired time interval.

The response will be a JSON array of event objects, ordered from earlier to later events.

Note that because of caching, the events might not contain the latest acknowledgements data. Requesting data for a single event is necessary to be guaranteed to see the most recent acknowledgements, if any.

If a {host} is specified, only events for that host will be included.

If {host}/{item} is specified, only events for that sensor will be included.

Triggers

Information about triggers

Make a GET request for one of the following paths:

  • https://api.modio.se/v0/trigger
  • https://api.modio.se/v0/{host}/trigger
  • https://api.modio.se/v0/{host}/{item}/trigger
  • https://api.modio.se/v0/trigger/{triggerid}

The events of a trigger

Make a GET request for one of the following paths:

  • https://api.modio.se/v0/trigger/{triggerid}/events
  • https://api.modio.se/v0/trigger/{triggerid}/events/{start}/{stop}

Testing server connectivity

Make a GET request for the path /v0/ping.

This request can be used to verify connectivity to the API server while consuming minimal bandwidth.