REST API
One API for every HVAC, BMS, and smart-home device you operate.
Normalized read + control endpoints across 60+ brands. Auth, sites, devices, telemetry, faults, schedules, webhooks. Unlock the full spec with one email.
Browse endpoints →Endpoints
REST API reference
Bearer-token auth, normalized JSON, brand-agnostic. Same shape whether the device is a Daikin VRV, a Trane RTU, or a Mitsubishi mini-split. Search by method, path, or capability — drop your email to unlock parameters and curl examples.
Base URL: https://api.hvacapi.com · 20 endpoints across 9 groups
Exchange a static API key for a short-lived access token
List all sites your token has access to
Get one site by id, including building metadata
List devices across sites you can access
Get a device with its capabilities
Current state — temperature, setpoint, mode, fan, runtime flags
Set the target temperature
Switch operating mode (heat | cool | auto | off | fan)
Apply or override a weekly schedule
Stream historical telemetry for a device
Site-level energy roll-up (kWh, kW, demand)
List active faults across your scope
Acknowledge a fault and stop re-alarming
Explain a brand-specific fault code
List supported brands and their protocols
Get capabilities for one brand
List schedules (templates) configured on your account
Create a new schedule template
Register a webhook for fault, control, or telemetry events
List configured webhooks
No endpoints match — try a different search term.
Full specifications
Drop your email to unlock request bodies, response shapes, scopes, error codes, and copy-paste curl examples for every endpoint above. One email unlocks every brand and the MCP tools too.
One email unlocks the whole site.
/v1/auth/tokenTrades a long-lived API key (issued at signup) for a 1-hour bearer token. Required for every other endpoint. Rate-limited to 60 requests / hour / key.
Scopes: public
Parameters
apiKey· body · string · requiredYour account API key.scopes· body · string[]Subset of granted scopes to request; defaults to all.
Response shape
{ token: string; expiresAt: ISO8601; scopes: string[] }curl
curl -X POST https://api.hvacapi.com/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"apiKey":"$HVACAPI_KEY"}'/v1/sitesPaginated. Each site rolls up a building or location. Used as the parent scope for device, telemetry, and fault queries.
Scopes: sites:read
Parameters
limit· query · intPage size, default 50, max 250.cursor· query · stringOpaque pagination cursor from the previous response.
Response shape
{ sites: Site[]; nextCursor?: string }curl
curl https://api.hvacapi.com/v1/sites \
-H "Authorization: Bearer $TOKEN"/v1/sites/{id}Returns the site's metadata (address, square footage, HVAC totals) plus a count of devices and active faults.
Scopes: sites:read
Parameters
id· path · string · requiredSite identifier.
Response shape
{ id; name; address; deviceCount; activeFaultCount; … }/v1/devicesFilter by site, brand, category, status. Useful to enumerate equipment for an integration job.
Scopes: devices:read
Parameters
siteId· query · stringRestrict to one site.brand· query · stringRestrict to one brand slug (carrier, daikin, …).category· query · enumHVAC | HomeAutomation | BMS.
Response shape
{ devices: Device[]; nextCursor?: string }/v1/devices/{id}Returns the canonical device record: brand, model, supported points, current online status. Capability set tells you which Control endpoints will succeed.
Scopes: devices:read
Parameters
id· path · string · requiredDevice identifier.
Response shape
{ id; brand; model; capabilities[]; online; … }/v1/devices/{id}/stateNormalized across brands. A Daikin VRV, a Trane RTU, and a Mitsubishi mini-split all return the same JSON shape. Latency typically <250ms.
Scopes: devices:read
Parameters
id· path · string · requiredDevice identifier.
Response shape
{ temperature; humidity; setpoint; mode; fanSpeed; status; readAt }curl
curl https://api.hvacapi.com/v1/devices/{id}/state \
-H "Authorization: Bearer $TOKEN"/v1/devices/{id}/setpointWrite-back is opt-in per device per scope. Every call is audit-logged with caller, before/after, and outcome. Subject to your site's safety interlocks.
Scopes: devices:write
Parameters
id· path · string · requiredDevice identifier.value· body · number · requiredTarget temperature in the device's native unit (°C or °F per site config).reason· body · stringAudit reason; freeform.
Response shape
{ ok: true; before; after; appliedAt; auditId }/v1/devices/{id}/modeMode set is bounded by the device's capabilities — sending "cool" to a heat-only unit returns 422 with allowed values.
Scopes: devices:write
Parameters
id· path · string · requiredDevice identifier.mode· body · enum · requiredheat | cool | auto | off | fan | dry.
Response shape
{ ok; before; after; appliedAt; auditId }/v1/devices/{id}/schedulePushes a 7-day schedule with up to 8 segments per day. Setpoints during unoccupied segments respect the global setback policy unless overridden per-segment.
Scopes: devices:write
Parameters
id· path · string · requiredDevice identifier.schedule· body · Schedule · requiredA WeeklySchedule object — see /v1/schedules.
Response shape
{ ok; scheduleId; effectiveFrom }/v1/devices/{id}/telemetryReturns sampled values for the requested points over a time window. Default sampling is 1-minute; downsamples for windows >24h.
Scopes: telemetry:read
Parameters
id· path · string · requiredDevice identifier.points· query · string[]Comma-separated point names (temperature, setpoint, …).from· query · ISO8601Start of window. Default: 24h ago.to· query · ISO8601End of window. Default: now.resolution· query · enum1m | 5m | 1h | 1d.
Response shape
{ points: { name; samples: [t, v][] }[] }/v1/sites/{id}/energyAggregates per-device runtime and amperage into a single site energy series. Used by the M&V / IPMVP report templates.
Scopes: telemetry:read
Parameters
id· path · string · requiredSite identifier.from· query · ISO8601Start of window.to· query · ISO8601End of window.
Response shape
{ kWh; peakKW; demandKW; samples: [t, kW][] }/v1/faultsFilter by site, brand, severity. The same data that drives /technician-copilot escalations.
Scopes: faults:read
Parameters
severity· query · enuminfo | warning | critical.siteId· query · stringRestrict to one site.
Response shape
{ faults: Fault[]; nextCursor? }/v1/faults/{id}/acknowledgeSets the fault state to acknowledged and silences further notifications for the configured cooldown.
Scopes: faults:write
Parameters
id· path · string · requiredFault identifier.note· body · stringAcknowledgement note; goes into the audit log.
Response shape
{ ok; acknowledgedAt; by }/v1/faults/explainReturns the human-readable meaning, severity, and suggested first-checks for a given brand + code. Same data that powers the /brands/<slug> fault-code tables.
Scopes: public
Parameters
brand· query · string · requiredBrand slug.code· query · string · requiredFault code (e.g. U4, E6).
Response shape
{ brand; code; category; meaning; severity; suggestedAction }/v1/brandsPublic — same data as the /coverage page. Returns the live catalog so integrations can adapt as new brands ship.
Scopes: public
Response shape
{ brands: { slug; name; category; protocols; status }[] }/v1/brands/{slug}Returns the brand's device families, supported points, protocol matrix, and code snippets. Used to gate UI before showing an integration step.
Scopes: public
Parameters
slug· path · string · requiredBrand slug.
Response shape
{ brand; deviceFamilies; capabilities; protocols }/v1/schedulesSchedules are reusable WeeklySchedule objects you can attach to many devices. Lifts schedule management out of the per-device control flow.
Scopes: schedules:read
Response shape
{ schedules: Schedule[]; nextCursor? }/v1/schedules7 days, up to 8 segments per day, per-segment setpoint or setback offset.
Scopes: schedules:write
Response shape
{ id; name; createdAt }/v1/webhooksPOST a URL + an event-type filter. We sign every delivery with HMAC-SHA256 and retry with exponential backoff for 24 hours.
Scopes: webhooks:write
Parameters
url· body · string · requiredHTTPS endpoint.events· body · string[] · requiredfault.opened | fault.acknowledged | device.write | telemetry.threshold | …
Response shape
{ id; secret; createdAt }/v1/webhooksIncludes lastDeliveryAt and lastDeliveryStatus so you can spot broken consumers quickly.
Scopes: webhooks:read
Response shape
{ webhooks: Webhook[] }Stuck on something?
Ask about the API — auth, scopes, rate limits.
Or tell us which endpoint you wish existed.
Send us the question
How it stays out of your way
Secure
Sealed data plane. Per-site auth. Audit log on every setpoint touch.
Runs on the edge
Deploys at the building edge — your data doesn't leave the site to be useful.
BYO LLM
Works with Claude, ChatGPT, and any MCP-compatible client. You pick the brain.