Key Performance Indicators API Developer Guide
Introduction to Clockworks Analytics
Clockworks is a cloud-based fault detection and diagnostics (FDD) platform, with a global analysis engine built on 30 person-years of research and development. The comprehensive library of root-cause diagnostics is curated and updated continuously to cover all HVAC equipment and systems.
Clockworks has the ability to run in-depth diagnostics to quantify the avoidable energy costs of each identified performance issue and prioritize by impacts to energy, comfort, and maintenance on a 0-10 scale. Diagnostics can be sorted by portfolio or individual building, as well as equipment class and type of analyses. This allows a user to drill into a specific building, piece of equipment, or type of analysis.
Introduction to the Key Performance Indicators API
The KPI endpoint provides full access to all data collected by and produced by Clockworks. For example, on a single piece of equipment like a chiller the endpoint will expose everything from static information about the equipment details (equipment name, rated capacity, etc.) down to the 5-minute interval data collected throughout each day.
Traditional API calls versus the KPI endpoint
Let’s look at an example where you want to know how much energy waste occurred within your building in the last 7 days. For this you must sum all Avoidable Costs identified by the Diagnostics across all equipment within the building across the 7-day date range.
The Traditional Approach
Without the ability to aggregate data, all Diagnostic records for all equipment across the 7-day range must be collected. A POST call is used to specify the building, date range, and analysis interval and the response could include thousands of records based on the number of equipment within the building. As a result, you must parse through each record to find the cost savings field and further manipulate the data to find the sum across all records.
POST | https://rest.buildingsapi.net/core-diag/diagnostics |
Post | { |
Example Response | The call above would return thousands of individual diagnostic records for all equipment within the building across the 7-day period. Each response would have to be parsed to sum the “CostSavings” field for each “StartDate” {
"ID": "584436452",
"AEID": 22498,
"AID": 81,
"EID": 24478,
"EquipmentClassId": 0,
"EquipmentTypeId": 0,
"StartDate": "2025-04-11T00:00:00",
"AnalysisName": "Zone Unit",
"EquipmentName": "Bldg1_VAV2",
"BID": 1235,
"EnergyPriority": 2.0,
"ComfortPriority": 10.0,
"MaintenancePriority": 4.0,
"TotalPriority": 16.0,
"CostSavings": 0.0,
"Notes": "<div><p><strong>PROBLEM: ROOM AIR TEMPERATURE HIGHER THAN SETPOINT</strong><ul><li>The room air temperature was higher than its setpoint.</li></ul></p><p><strong>Possible Causes:</strong><ul><li>AHU supply air temperature higher than setpoint or max.</li><li>Zone unit supply air damper malfunction.</li><li>High load in zone(s) due to excess occupancy or solar gain.</li><li>Malfunctioning heating coil.</li><li>Uncalibrated or malfunctioning temperature sensor.</li><li>Controls or programming error.</li></ul></p></div><div><p><strong>PROBLEM: SLOW ROOM AIR TEMPERATURE RESPONSE TO CONDITIONING</strong><ul><li>The room air temperature was above its setpoint for 1.5 hours or more after the damper was opened.<li>The maximum time that elapsed before the room air temperature went within deadband, the damper was closed, or the diagnostic period ended was 17.3 hours.</li></ul></p><p><strong>Possible Causes:</strong><ul><li>Damper malfunction.</li><li>Not enough conditioning provided to zone.</li><li>High load in zone(s) due to excess occupancy or solar gain.</li><li>Uncalibrated or malfunctioning sensor.</li><li>Controls or programming error.</li></ul></p></div><div><p><strong>PROBLEM: SETPOINT IS ZERO</strong><ul><li>The zone supply air flow setpoint was zero for 6.6 hours over the analysis period while the zone was operational.</li><li>The times when any setpoint is zero were not used to determine zone compliance with that setpoint.</li></ul></p><p><strong>Possible Causes:</strong><ul><li>Incorrect or non-operational setpoint.</li><li>Controls or programming error.</li></ul></p></div><div><p><strong>Faults and opportunities investigated by this diagnostic:</strong></p><p>Damper cycling check. Max room air temp check. Min room air temp check. Room air temp setback check. Room air temp setpoint tracking. Sensor checks. Setpoint error check. Short cycling check. Slow room air temp response check. Stuck damper check. Supply air flow setpoint tracking. Zone on while unoccupied check. </p></div>",
"NotesSummary": "Room air temp higher than setpoint. Setpoint zero. Slow room air temp response to conditioning.",
"DiagnosticHyperlink": "https://portal.clockworksanalytics.com/Diagnostics?unitid=79&aid=81&eid=24478&etid=15&ecid=9&bid=1235&rng=DAILY&sd=04/11/2025",
"DateCreated": "0001-01-01T00:00:00",
"DateModified": "0001-01-01T00:00:00",
"UpdateFields": null
},
|
The KPI Approach
Unlike traditional API endpoints, the KPI endpoint allows users to customize a query against each dataset and aggregate the data by various parameters like buildings, equipment classes, etc.
Instead of collecting and parsing through thousands of records, the KPI endpoint can support a custom query to find the sum of cost savings for each day:
POST | https://rest.buildingsapi.net/core-kpis/AggregatedData |
Post | { |
Example Response | The call above aggregates the AvoidableCost field by the DiagnosticDate for the specified range. This reduces thousands of diagnostic records down to a simple sum of AvoidableCost across the 7-day period. [
{
"DiagnosticDate": "2025-04-13T00:00:00Z",
"CostSum": 118.0
},
{
"DiagnosticDate": "2025-04-15T00:00:00Z",
"CostSum": 110.0
},
{
"DiagnosticDate": "2025-04-12T00:00:00Z",
"CostSum": 3.0
},
{
"DiagnosticDate": "2025-04-14T00:00:00Z",
"CostSum": 127.0
},
{
"DiagnosticDate": "2025-04-11T00:00:00Z",
"CostSum": 0.0
},
{
"DiagnosticDate": "2025-04-16T00:00:00Z",
"CostSum": 0.0
},
{
"DiagnosticDate": "2025-04-10T00:00:00Z",
"CostSum": 0.0
}
] |
Setting up your API Calls
The KPI endpoint exposes ALL datasets within Clockworks with a single URL to call upon. Calls against the KPI endpoint utilize the same POST format shown below for all calls:
Post Call Format
POST | https://rest.buildingsapi.net/core-kpis/AggregatedData |
Body | { |
Post Call Body Parameters | |
KQL | The KQL parameter is a user-defined Kusto Query Language (KQL) query. KQL is Microsoft’s query language and provides a lot of flexibility for querying and aggregating data to suite the exact use case. All KQL queries must begin by calling the dataset name you are querying against along with the word “Dataset.” In the example above, the dataset name is “Diagnostics” so the query begins with “DiagnosticsDataset” |
Datasets | Datasets for the query must be listed, e.g. [“Dataset1”,”Dataset2”]. See the Available Datasets section below for a full list of Clockworks datasets. |
Required Parameters | Some, but not all, datasets have required parameters to run successfully. In the example shown, the Diagnostics call must have a date range and analysis interval. Simpler calls, like getting static information from Buildings have no required parameters. |
Optional Parameters | Additional paramters are available for optional use to quickly filter API calls across common elements such as Organizations, Buildings, and Equipment. |
Available Datasets
To see available fields within each dataset you can retrieve a single record from each following this POST call format below. Simply replace DatasetName with one of the datasets listed below.
{
"KQL": "DatasetNameDataset | take 1",
"Datasets": ["DatasetName"],
"[RequiredParameters]": "Parameter"
}
Dataset | Description |
|---|---|
AggregatedRawData | Pre-aggregated statistics on raw data binned into fixed time intervals of hourly, daily, weekly, and monthly. |
BuildingGroups | User-defined groups of buildings which can represent buildings within a common geography (e.g. Southeast Region), common management (e.g. Bob’s Buildings) or any other grouping. |
Buildings | The Buildings dataset contains static information about the building itself including total area, name, and location. |
BuildingVariables | Static variables which provide metadata about the Buildings, such as utility rates and operating schedules. |
DataSources | Details on the Clockworks Connect software gateway that is polling raw data from the Building Management System (BMS). |
DataSourceHealth | Connected/disconnected status of an entire data source. |
Deployments | New deployments of Clockworks. Deployments are related to the Buildings and Equipment being configured. |
DiagnosticResults | Diagnostic Results are produced by the daily analysis performed across all connected equipment. A Diagnostic Result can be a fault such as “Stuck pre-heating coil valve” with additional information around the energy cost waste and maintenance priorities. |
DiagnosticResultsVData | Calculated points produced by Clockworks with either an hourly or daily timestamp. Calculated points range from fan runtime hours, energy consumed by equipment, fault duration, and more. |
Diagnostics | Unlike an individual Diagnostic Result (see above), the Diagnostics are a combined output of all diagnostic results produced by a single analysis on a piece of equipment. The Diagnostic record may contain multiple faults along with their combined impacts to energy waste and maintenance priorities. |
Equipment | The Equipment dataset contains static information about the equipment itself including name, class, type, and any user-defined labels. |
EquipmentRelationships | Relationships between connected equipment, such as an Air Handling Unit (AHU) that serves many Variable Air Volume (VAV) boxes. |
EquipmentVariables | Static variables which provide metadata about the Equipment, such as rated fan power, rated flow, and sequence details to inform analytic checks. |
Organizations | The Organizations dataset contains static information about the organization itself including name and ID. |
Points | The Points dataset contains static information about the raw data points including name, class, type, and references to the BMS for cross-referencing points. |
RawData | 5-minute (typically) interval data collected from the Building Management System (BMS). |
ResultGroups | A collection of Diagnostic Results that when viewed together improve the investigation of related issues across equipment. |
Tasks | User-generated tasks which typically relate to issues identified by the Diagnostics which need to be addressed. |
Users | The Users dataset contains static information about the users within an organization including name and email. |
Vdata | Calculated points produced by Clockworks with either an hourly or daily timestamp. Calculated points range from fan runtime hours, energy consumed by equipment, fault duration, and more. |
Payload Keys
Payload Key | Data Type | Required for Datasets | Notes |
|---|---|---|---|
KQL | String | YES - all calls |
|
Datasets | Array of string | YES - all calls |
|
AggregatationInterval | string | AggregatedRawDataDataset
| FiveMinute, Hourly, Weekly, Daily, and Monthly. |
BGID | Array Of Integers |
| Building group ID |
BID | Array Of Integers |
| Building ID |
BuildingClassID | Array Of Integers |
|
|
BuildingTypeID | Array Of Integers |
|
|
ConfigurationStatusID | Array Of Integers |
| Status of equipment within a new deployment. Defaults to 5 (Complete) |
DiagnosticAnalysisInterval | String | DiagnosticResults, DiagnosticResultsVData, Diagnostics, and VData |
|
DiagnosticEndDate | Datetime | DiagnosticResults, DiagnosticResultsVData, Diagnostics, and VData |
|
DiagnosticStartDate | Datetime | DiagnosticResults, DiagnosticResultsVData, Diagnostics, and VData |
|
EID | Array Of Integers |
| Equipment ID |
EquipmentClassID | Array Of Integers |
|
|
EquipmentTypeID | Array Of Integers |
|
|
IsBuildingVisible | Boolean |
| Defaults to true if not supplied. |
IsEquipmentVisible | Boolean |
| Defaults to true if not supplied. |
IsVisible | Boolean |
| Defaults to true if not supplied. |
PID | Array Of Integers |
| Point ID |
PointClassID | Array Of Integers |
|
|
PointTypeID | Array Of Integers |
|
|
RawDataEndDate | Nullable Datetime |
|
|
RawDataStartDate | Datetime | AggregatedRawDataDataset and RawData |
|
ResultClassID | Array Of Integers |
|
|
ResultSubTypeID | Array Of Integers |
|
|
ResultTypeID | Array Of Integers |
|
|
TaskAssignedUID | Array Of Integers |
|
|
TaskCompletionEndDate | Datetime |
|
|
TaskCompletionStartDate | Datetime |
|
|
TaskModifiedEndDate | Datetime |
|
|
TaskModifiedStartDate | Datetime |
|
|
TaskOpenedEndDate | Datetime |
|
|
TaskOpenedStartDate | Datetime |
|
|
TaskReporterUID | Array Of Integers |
|
|
TaskStatus | Array Of Strings |
|
|
TaskStatusID | Array Of Integers |
|
|
UnitID | Array Of Integers |
|
|
VPID | Array Of Integers |
| Vdata Point ID |
Sample Calls
Use Case Example: External Reporting with PowerBI
1. Get Data → More → Blank Query
2. Setup API Key Parameter
Edit Query → Manage → New Parameter
3. Power Query Configuration
let
//EDIT ME - POST BODY WITH SINGLE QUOTES
PostBody = "{
'kql': 'EquipmentLiveDataset | take 10',
'Datasets': ['EquipmentLive'],
'UnitID': [79]
}",
// Wrapping PotBody in double quotes
body = Text.Replace(PostBody, "'", """"),
// Perform the POST request and Extract to Table
url = "https://rest.buildingsapi.net/core-kpis/AggregatedData",
headers = [
#"Content-Type" = "application/json",
#"Ocp-Apim-Subscription-Key" = APIKey
],
data = Json.Document(Web.Contents(url, [Headers = headers, Content = Text.ToBinary(body)])),
resultTable = Table.FromRecords(data)
in
resultTable