Organic Response Cloud API API Reference

Introduction

The Organic Response Portal is a simple yet powerful cloud-based data insights and lighting control platform, capturing the rich data stream available from the smart sensor network to provide valuable insights, including:

  • Centralised view of portfolio wide assets
  • Real-time visibility of current utilisation and performance
  • Detailed historial performance for trend analysis of Space Utilisation
  • Enterprise-level data security via encryption both in transport (128bit AES, TLS) and storage (Amazon AWS IoT).
  • On-going system status monitoring with fault monitoring and emailed fault notifications
  • Highly scalable
  • Automatic over-the-air updates
  • Time-based scheduling for fine control over your buildings lighting
  • BACnet Integration (BACnet is a Building Management System protocol)
  • Automated Emergency Light Monitoring and Test with emailed fault or failure notifications

The Organic Response Cloud API provides the ability to extend the Organic Response connected solution further.

API Endpoint
https://portal.organicresponse.com/public/api/v1/
Terms of Service: http://organicresponse.com
Contact: product@organicresponse.com
Version: 1.0

Authentication

An authentication token is required to make API calls. Please contact us if you require a token.

Authentication is on a per-building basis and authorisation can be applied at a granular level. The following permissions can be granted for a token:

  • VIEW - is required to discover the building entities such as floors, tags and sensor nodes
  • ANALYTICS - is required to query historical data
  • HIGH_RESOLUTION_ANALYTICS - is required to query real-time data
  • CONTROL_LIGHTS - is required to perform lighting control instructions

The token should be passed in the request body (formatted as JSON) of a POST request to /public/api/v1/authenticate. For example:

                  
  {
    "token": "4087-5762507a-5ede-453b-a189-4dba8e93173c"
  }
                  
                

The response will contain a JSON Web Token (JWT), valid for 1 day. For example:

                  
  {
    "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0X21vYmlsZV90b2tlbl8yMDEiLCJleHAiOjE1OTEwNzY5MjIsImlhdCI6MTU5MDk5MDUyMn0.IF3Xt4FWPSi0ruYh5MbBVFpFvJizuEtLlYNBsjtuQ9E",
    "expiryDate": "2020-06-02"
  }
                  
                

The client takes the JWT token and adds it to the Authorization header with value ‘Bearer {{token}}’ on all subsequent requests. Note: The JWT token is valid for 1 day, and a new token will need to be fetched once it expires.

Requests & Responses

Verbs

The API currently supports “GET" and "POST” methods.

  • GET: Retrieves a resource or a collection of resources
  • POST: Executes lighting control instructions and queries

POST Content Types

The API accepts JSON data with Content-Type: application/json and XML data with Content-Type: application/xml

JSON Response Format

All response bodies are in the JSON+HAL Hypermedia format.

The simplest possible response is an empty JSON document.

                  
  {}
                  
                

A JSON document can have keys and values. Typical resources contain a unique “id”.

                  
  {  
    "id":1,
    "name":"699 Bourke",
    ...
  }
                  
                

Links are always contained directly within a resource under the “_links” key. Links have a relation (aka. ‘rel’). This indicates the semantic, or the meaning, of a particular link. The example below is a link to a lighting control endpoint.

                  
  {
    "_links" : {
      "lightingcontrol" : {
        "href" : "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
      }
    }
  }
                  
                

All top-level resources have a link to “self”.

                  
  {
    "_links" : {
      "self" : {
        "href" : "https://portal.organicresponse.com/public/api/v1/floor/1"
      }
    }
  }
                  
                

Errors

HTTP status codes are used to indicate success or failure of a request.

  • 200 OK
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 429 Too Many Requests (see Rate Limiting for more info)

Error codes in the 500 range are not expected and should be reported.

Rate Limiting

The OR API is currently rate-limited to 1 request per second per token. API calls will return an HTTP 429 Too Many Requests error when your client is over that limit.

You will not be blacklisted by default, only throttled.

We currently do not offer a way to raise this limit, please contact us if you need help.

building

Building Resource Controller

getBuilding

GET /public/api/v1/

Returns the authorised Building for the supplied Token

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
[
  {
    "id": 1,
    "name": "OR Technologies",
    "address": {
      "addressLine1": "Level 1/2 Greenwood St, Abbotsford",
      "addressLine2": "",
      "addressLine3": "",
      "postcode": "3067",
      "country": "Australia"
    },
    "timeZone": "Australia/Melbourne",
    "thumbnailImage": "ortech_thumbnail.png",
    "links": {
      "self": {
        "href": "https://portal.organicresponse.com/public/api/v1/building/1"
      },
      "thumbnail": {
        "href": "https://portal.organicresponse.com/public/api/v1/building/1/thumbnail?id=ortech_thumbnail.png"
      }
    }
  }
]

getBuilding

GET /public/api/v1/building/{buildingId}

Returns the Building for the given id, including a list of Floors and Tags

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "id": 1,
  "name": "OR Technologies",
  "address": {
    "addressLine1": "Level 1/2 Greenwood St, Abbotsford",
    "addressLine2": "",
    "addressLine3": "",
    "postcode": "3067",
    "country": "Australia"
  },
  "timeZone": "Australia/Melbourne",
  "thumbnailImage": "ortech_thumbnail.png",
  "_embedded": {
    "floors": [
      {
        "id": 1,
        "floorNumber": 1,
        "name": "Level 1",
        "floorplan": "ortech_floor1_floorplan.png",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/floor/1"
          }
        }
      }
    ],
    "tags": [
      {
        "id": 1,
        "name": "Open Office",
        "color": "9CDCAE",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/building/1"
    },
    "thumbnail": {
      "href": "https://portal.organicresponse.com/api/v1/building/1/thumbnail?id=ortech_thumbnail.png"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

liveanalytics

Live Analytics Controller

aggregatedQuery

POST /public/api/v1/query/live/aggregated

Returns aggregated live data. Currently the only aggregated query type is 'STATUS' which returns (for the selected nodes) one of:

  • AUTO - all nodes are in Organic Response Auto mode - i.e. Scene 8
  • FORCE_ON - all nodes are forced on - i.e. in Scenes 1 to 6
  • FORCE_OFF - all nodes are forced off - i.e. in Scene 7
  • OTHER - nodes are not in a consistent Scene
Request Content-Types: application/json
Request Example
{
  "buildingId": 19,
  "liveQueryType": "STATUS"
}
200 OK

OK

201 Created

Created

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
"OTHER"

perNodeQuery

POST /public/api/v1/query/live/perNode

Returns node-by-node live data. Currently the supported per-node query types are:

  • PRESENCE
  • DIM_LEVEL
  • SCENE
  • FAULT
Request Content-Types: application/json
Request Example
{
  "buildingId": 19,
  "liveQueryType": "SCENE",
}
200 OK

OK

201 Created

Created

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": [
    {
      "key": "123",
      "value": "7",
      "address": "678"
    },
    {
      "key": "456",
      "value": "4",
      "address": "999"
    }
  ]
}

lightingcontrol

Lighting Control Instruction Controller

performInstruction

POST /public/api/v1/lightingcontrol

Send a lighting control instruction (LightingControlInstruction) to the specified entity (Building/Floors/Tags/Nodes)

instructionResource

Request Content-Types: application/json
Request Example
{
  "buildingId": 1,
  "command": "DIM_TO",
  "params": [
    60.0
  ]
}
200 OK

OK

201 Created

Created

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json

sensornodes

Sensor Node Resource Controller

getSensorNode

GET /public/api/v1/sensornode/{sensorNodeId}

Returns the SensorNode for the given id

sensorNodeId: integer (int64)
in path

sensorNodeId

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "id": 1,
  "address": 234,
  "x": 100,
  "y": 120,
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  },
  "_embedded": {
    "tags": [
      {
        "id": 1,
        "name": "Open Office",
        "color": "9CDCAE",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
          }
        }
      }
    ]
  }
}

floors

Floor Resource Controller

getFloor

GET /public/api/v1/floor/{floorId}

Returns the Floor for the given id, including a list of SensorNodes

floorId: integer (int64)
in path

floorId

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "id": 1,
  "floorNumber": 1,
  "name": "Level 1",
  "floorplan": "ortech_floor1_floorplan.png",
  "_embedded": {
    "sensornodes": [
      {
        "id": 1,
        "address": 234,
        "x": 100,
        "y": 120,
        "_links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
          }
        },
        "_embedded": {
          "tags": [
            {
              "id": 1,
              "name": "Open Office",
              "color": "9CDCAE",
              "links": {
                "self": {
                  "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
                }
              }
            }
          ]
        }
      }
    ],
  }
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/floor/1"
    },
    "floorplan": {
      "href": "https://portal.organicresponse.com/api/v1/floor/1/floorplan?id=ortech_floor1_floorplan.png"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

tags

Tag Resource Controller

getTag

GET /public/api/v1/tag/{tagId}

Returns the Tag for the given id, including a list of SensorNodes

tagId: integer (int64)
in path

tagId

200 OK
Tag

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "id": 1,
  "name": "Open Office",
  "color": "9CDCAE",
  "_embedded": {
    "sensornodes": [
      {
        "id": 1,
        "address": 234,
        "x": 100,
        "y": 120,
        "_links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
          }
        }
      }
    ]
  }
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

analytics

Analytics Controller

dayQuery

GET /public/api/v1/query/day?floorId={floorId}&date={YYYY-MM-DD}

Returns node-by-node presence recorded for the specified date. If no day is specified it returns node-by-node presence recorded for the previous day. Note that querying partial data for the current day is possible.

floorId: integer (int64)
in query

floorId

date: string
in query

date

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": [{
    "key": "1234567",
    "value": "7.11",
    "address": "89"
  }],
  "max": 100,
  "suffix": "%"
}

hourQuery

GET /public/api/v1/query/hour?floorId={floorId}&date={YYYY-MM-DD}&hour={HH}

Returns node-by-node presence recorded for the specified hour. If no hour is specified it returns node-by-node presence recorded for the previous hour. Note that querying partial data for the current hour is possible.

floorId: integer (int64)
in query

floorId

date: string
in query

date

hour: integer (int32)
in query

hour

200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": [{
    "key": "1234567",
    "value": "7.11",
    "address": "89"
  }],
  "max": 100,
  "suffix": "%"
}

minQuery

GET /public/api/v1/query/min?floorId={floorId}&date={YYYY-MM-DD}&hour={HH}&min={MM}

Returns node-by-node presence recorded for the specified five minutes. If no minute is specified it returns node-by-node presence recorded for the previous five minutes. Note that querying partial data for the current five minutes is possible.

floorId

floorId

type
integer (int64)
in
query
date

date

type
string
in
query
hour

hour

type
integer (int32)
in
query
min

min

type
integer (int32)
in
query
nodeId

nodeId

type
integer (int64)
in
query
tagId

tagId

type
integer (int64)
in
query
200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": [{
    "key": "1234567",
    "value": "7.11",
    "address": "89"
  }],
  "max": 100,
  "suffix": "%"
}

monthQuery

GET /public/api/v1/query/month?floorId={floorId}&year={YYYY}&month={MM}

Returns node-by-node presence recorded for the specified month. If no month is specified it returns node-by-node presence recorded for the previous month. Note that querying partial data for the current month is possible.

floorId

floorId

type
integer (int64)
in
query
year

year

type
integer (int32)
in
query
month

month

type
integer (int32)
in
query
nodeId

nodeId

type
integer (int64)
in
query
tagId

tagId

type
integer (int64)
in
query
200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": "1",
  "max": 100,
  "suffix": "%"
}

weekQuery

GET /public/api/v1/query/week?floorId={floorId}&year={YYYY}&week={WW}

Returns node-by-node presence recorded for the specified week. If no week is specified it returns node-by-node presence recorded for the previous week. Note that querying partial data for the current week is possible.

floorId

floorId

type
integer (int64)
in
query
year

year

type
integer (int32)
in
query
week

week

type
integer (int32)
in
query
nodeId

nodeId

type
integer (int64)
in
query
tagId

tagId

type
integer (int64)
in
query
200 OK

OK

401 Unauthorized

Unauthorized

403 Forbidden

Forbidden

404 Not Found

Not Found

429 Too Many Requests

Too Many Requests

Response Content-Types: application/hal+json
Response Example (200 OK)
{
  "values": "1",
  "max": 100,
  "suffix": "%"
}

Schema Definitions

Building: object

A building configured with Organic Response's revolutionary lighting controls technology

id: integer (int64)

System generated id for the building

name: string

Unique name of the Building

address: Address

Address of the building

timeZone: string

Time zone of the building

thumbnailImage: string

Thumbnail image of the building

floors: Floor

List of the building's floors

Floor
tags: Tag

List of the building's tags

Tag
_links: Link
Link
Example
{
  "id": 1,
  "name": "OR Technologies",
  "address": {
    "addressLine1": "Level 1/2 Greenwood St, Abbotsford",
    "addressLine2": "",
    "addressLine3": "",
    "postcode": "3067",
    "country": "Australia"
  },
  "timeZone": "Australia/Melbourne",
  "thumbnailImage": "ortech_thumbnail.png",
  "_embedded": {
    "floors": [
      {
        "id": 1,
        "floorNumber": 1,
        "name": "Level 1",
        "floorplan": "ortech_floor1_floorplan.png",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/floor/1"
          }
        }
      }
    ],
    "tags": [
      {
        "id": 1,
        "name": "Open Office",
        "color": "9CDCAE",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
          }
        }
      }
    ]
  }
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/building/1"
    },
    "thumbnail": {
      "href": "https://portal.organicresponse.com/api/v1/building/1/thumbnail?id=ortech_thumbnail.png"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

Floor: object

A floor configured with Organic Response's revolutionary lighting controls technology

id: integer (int64)

System generated id for the floor

floorNumber: integer (int64)

Number of the floor

name: string

Name of the floor

floorplan: string

Floorplan image of the floor

sensornodes: SensorNode

List of the sensor nodes installed on the floor

SensorNode
_links: Link
Link
Example
{
  "id": 1,
  "floorNumber": 1,
  "name": "Level 1",
  "floorplan": "ortech_floor1_floorplan.png",
  "_embedded": {
    "sensornodes": [
      {
        "id": 1,
        "address": 234,
        "x": 100,
        "y": 120,
        "_links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
          }
        },
        "_embedded": {
          "tags": [
            {
              "id": 1,
              "name": "Open Office",
              "color": "9CDCAE",
              "links": {
                "self": {
                  "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
                }
              }
            }
          ]
        }
      }
    ],
  }
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/floor/1"
    },
    "floorplan": {
      "href": "https://portal.organicresponse.com/api/v1/floor/1/floorplan?id=ortech_floor1_floorplan.png"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

LightingControlInstruction: object

A lighting control instruction targeting a building, floor/s, tag/s, or sensor node/s

buildingId: integer (int64)
floorIds: integer[]
integer (int64)
sensorNodeIds: integer[]
integer (int64)
tagIds: integer[]
integer (int64)
command: string DIM_TO, REVERT_ORES_MODE, SCENE
params: number[]
Example 1
{
  "buildingId": 1,
  "command": "DIM_TO",
  "params": [
    60.0
  ]
}
Example 2
{
  "buildingId": 1
  "sensorNodeIds": [1234567, 2345678],
  "command": "SCENE",
  "params": [
    7.0
  ]
}
  
Example 3
{
  "buildingId": 1
  "floorIds": [1],
  "command": "REVERT_ORES_MODE",
  "params": []
}
    

KeyValueAddress: object

An object with three properties (key, value and address)

key: int(64)

The node id

value: double

The measured value

address: int(32)

The node address

Example
{
  "key": "1234567",
  "value": "7.11",
  "address": "89"
}

Address: object

A building's address

addressLine1: string

Address line 1

addressLine2: string

Address line 2

addressLine3: string

Address line 3

postcode: string

Postcode

country: string

Country

Example
{
  "addressLine1": "Level 1/2 Greenwood St, Abbotsford",
  "addressLine2": "",
  "addressLine3": "",
  "postcode": "3067",
  "country": "Australia"
}

QueryResult: object

A query result

values: KeyValueAddress

A list of key,value and address objects, where the key corresponds to the node id and the value to the measured value

KeyValueAddress
max: number (double)

The maximum value

suffix: string

The unit suffix

Example
{
  "values": [{
    "key": "1234567",
    "value": "7.11",
    "address": "89"
  }],
  "max": 100,
  "suffix": "%"
}

Tag: object

A tag used to group a collection of sensor nodes

id: integer (int64)

System generated id for the tag

name: string

Name of the tag

color: string

Colour of the tag (in hex format)

sensornodes: SensorNode

List of sensor nodes tagged with the given tag

SensorNode
_links: Link
Link
Example
{
  "id": 1,
  "name": "Open Office",
  "color": "9CDCAE",
  "_embedded": {
    "sensornodes": [
      {
        "id": 1,
        "address": 234,
        "x": 100,
        "y": 120,
        "_links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
          }
        }
      }
    ]
  }
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  }
}

LiveQueryOutline: object

A live query outline targeting a building, floor/s, tag/s, or sensor node/s

buildingId: integer (int64)
floorIds: integer[]
integer (int64)
sensorNodeIds: integer[]
integer (int64)
tagIds: integer[]
integer (int64)
liveQueryType: string PRESENCE , DIM_LEVEL , SCENE , STATUS , FAULT
Example
{
  "buildingId": 19,
  "liveQueryType": "STATUS"
}

SensorNode: object

An Organic Response sensor node - the heart of the revolutionary lighting controls technology

id: integer (int64)

System generated id for the sensor node

x: integer (int32)

X coordinate of the sensor node relative to the floorplan image (in pixels)

y: integer (int32)

Y coordinate of the sensor node relative to the floorplan image (in pixels)

_links: Link
Link

List of the node's tags

Tag
Example
{
  "id": 1,
  "address": 234,
  "x": 100,
  "y": 120,
  "_links": {
    "self": {
      "href": "https://portal.organicresponse.com/public/api/v1/sensornode/1"
    },
    "analytics": {
      "href": "https://portal.organicresponse.com/public/api/v1/query"
    },
    "lightingcontrol": {
      "href": "https://portal.organicresponse.com/public/api/v1/lightingcontrol"
    }
  },
  "_embedded": {
    "tags": [
      {
        "id": 1,
        "name": "Open Office",
        "color": "9CDCAE",
        "links": {
          "self": {
            "href": "https://portal.organicresponse.com/public/api/v1/tag/1"
          }
        }
      }
    ]
  }
}