H.E.A.T. Cloud API (0.1.0)

Download OpenAPI specification:

H.E.A.T. Cloud Public API Overview

The HEAT Cloud Public API provides programmatic access to hybrid energy sites managed by the H.E.A.T. Energy Gateway. It is a REST API authenticated with an API key, which you can obtain on the H.E.A.T. Cloud API Settings page.

Once authenticated, callers can:

  • List sites — retrieve all sites accessible to the API key's access group, including connectivity status and any currently active schedules.
  • Inspect a site — get the aggregated asset groups (solar, BESS, EV chargers, heat pumps, gensets, grid connections) configured for a specific site, along with their rated power and energy capacities.
  • Schedule operations — submit batches of time-windowed commands to a site. Supported command types are upperLimitkW, lowerLimitkW(set grid import/export limits), activePowerkW (set grid or BESS active power setpoint), optimalSocPcnt (set BESS optimal state of charge), solarCurtailmentPcnt.

A /health endpoint is also available for liveness/readiness probing and does not require authentication.


API Versioning Policy

Current version

The API is currently at version 0.1.0. Until version 1.0 is released, we do not guarantee backward compatibility — breaking changes may occur between releases.


How versioning works

The API version is part of the URL path:

/api/v0/public/sites
/api/v1/public/sites

We do not create a new version for every change. A new version is only introduced when a change would break existing clients.


What changes within a version

The following changes may happen without a version bump. Your integration should be written to handle them gracefully:

  • New fields in responses — a GET endpoint may return additional fields. As long as your code ignores unknown properties rather than treating them as errors, nothing breaks.
  • New optional fields in request bodies — a POST endpoint may gain a new optional field. If you don't send it, the previous behavior is preserved.

What triggers a new version

The following changes will always result in a new version:

  • New required field in a request — you will eventually need to update your implementation to send the new field.
  • Changed meaning of a field — if a field's semantics change in either a request or a response, a new version is introduced. You will need to update your implementation to use the new meaning.
  • Removed field — if a field is dropped from a request or response, a new version is introduced. You will need to stop sending or reading that field.

Authentication

Overview

The API uses API key authentication. Every request must include an API key in the Authorization header.

API key (from Heat Cloud website)
        │
        ▼
All API requests (Authorization: Bearer agk_<id>.ags_<secret>)

Step 1 — Obtain an API key

API keys are managed in the Heat Cloud website under your account settings. Each key is associated with an access group that determines which sites the key can see.

When a key is created you receive two strings — an API key ID and an API key secret. Store the secret securely — it is not shown again after creation.


Step 2 — Authenticate requests

Pass the full API key as a Bearer token on every request:

Authorization: Bearer agk_<id>.ags_<secret>

The /health endpoint does not require authentication.


API key limitations

Constraint Details
Keys per access group Maximum 20 active keys (keys that are neither revoked nor expired).
Name uniqueness Key names must be unique within an access group.
Expiry Optional. A key can be set to expire at a specific date/time or have no expiry. Expired keys are rejected.
Revocation Keys can be revoked at any time from the Heat Cloud website. Revoked keys are rejected immediately, even if their expiry date has not passed.

Sites

List all sites available to the caller's access group

Returns every site the API key's access group can reach, including connectivity status and any currently active schedules.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "sites": [
    ]
}

Get asset groups for a site

Returns the aggregated asset groups (e.g. solar, BESS, EV chargers) configured for the specified site, including rated power and, for BESS, rated energy capacity.

Authorizations:
bearerAuth
path Parameters
siteId
required
string <uuid>

UUID of the site to retrieve

Responses

Response samples

Content type
application/json
{
  • "siteId": "123e4567-e89b-12d3-a456-426614174000",
  • "siteName": "Site 1",
  • "isOnline": true,
  • "reportedAt": "2025-06-01T08:00:00Z",
  • "schedules": [
    ],
  • "assets": {
    }
}

Submit schedule commands for a site

Accepts schedule commands for a site. Each command targets an asset with a schedule type and a list of time-range entries. Each asset/type combination must appear at most once — duplicate pairs cause the entire schedule to be rejected. Entries within a command must not overlap in time; any conflict also rejects the entire schedule. upperLimitkW and lowerLimitkW are signed: positive = import, negative = export.

To clear existing schedules of a specific type for a selected asset, send a command with an empty entries array.

Supported asset + type combinations:

grid + upperLimitkW/lowerLimitkW - grid export(negative values) and import (positive values)

grid + activePowerkW - grid active power setpoint

solar + solarCurtailmentPcnt - solar curtailment percentage

bess + activePowerkW - BESS active power setpoint

bess + optimalSocPcnt - BESS optimal state of charge

Note: BESS activePowerkW and optimalSocPcnt are mutually exclusive which practically means 2 things:

  • a request containing schedule commands of both types is invalid and will be declined
  • sending an activePowerkW schedule command overwrites any existing optimalSocPcnt, and vice versa
Authorizations:
bearerAuth
path Parameters
siteId
required
string <uuid>

UUID of the target site

Request Body schema: application/json
required
required
Array of objects (AssetScheduleCommand) [ 1 .. 10 ] items

List of asset schedule commands. Each asset/type combination must appear at most once.

Responses

Request samples

Content type
application/json
{
  • "schedules": [
    ]
}

Response samples

Content type
application/json
{
  • "batchId": "5579c111-9c50-47e2-af92-f16d52e63189",
  • "accepted": 0
}

Health

Check cloud API health status

Returns 204 when the service is operational, 503 when unavailable. Request timeouts should also be treated as service unavailability.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "error": "internal_server_error",
  • "message": "An unexpected error occurred"
}