> ## Documentation Index
> Fetch the complete documentation index at: https://docs.amps.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get HVAC state

> Retrieve the current state of an HVAC device including mode, temperature, and humidity



## OpenAPI

````yaml /openapi.json get /hvac/{deviceId}
openapi: 3.1.0
info:
  title: Amps.ai API
  description: >-
    Energy device management API for batteries, EV chargers, solar inverters,
    and HVAC systems
  version: '1.0'
  contact: {}
servers:
  - url: https://api.amps.ai
    description: Amps API
security: []
tags: []
paths:
  /hvac/{deviceId}:
    get:
      tags:
        - HVAC
      summary: Get HVAC state
      description: >-
        Retrieve the current state of an HVAC device including mode,
        temperature, and humidity
      operationId: getHvac
      parameters:
        - name: expedite
          required: false
          in: query
          description: Use expedite cache with 1 minute TTL instead of normal 15 minute TTL
          schema:
            example: false
            type: boolean
        - name: deviceId
          required: true
          in: path
          description: The unique identifier for the HVAC device
          schema:
            example: device_abc123
            type: string
      responses:
        '200':
          description: HVAC state retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                  - meta
                properties:
                  success:
                    type: boolean
                    const: true
                    description: Always `true` for success responses.
                  data:
                    $ref: '#/components/schemas/HvacResponse'
                  meta:
                    $ref: '#/components/schemas/ResponseMeta'
              examples:
                hvacHeating:
                  summary: HVAC actively heating the home
                  description: >-
                    `active: true` and `mode: heat`. Room temperature below
                    `heatSetpoint`, so the unit is calling for heat. `commands`
                    advertises the canonical control surface the device
                    supports.
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: live
                      state:
                        temperature: 18.5
                        active: true
                        heatSetpoint: 21
                        coolSetpoint: 25
                        holdType: schedule
                        mode: heat
                      commands:
                        heat:
                          parameters:
                            target:
                              unit: celsius
                              min: 10
                              max: 35
                          execution:
                            - immediate
                            - scheduled
                            - windowed
                        cool:
                          parameters:
                            target:
                              unit: celsius
                              min: 10
                              max: 35
                          execution:
                            - immediate
                            - scheduled
                            - windowed
                        idle:
                          parameters: {}
                          execution:
                            - immediate
                            - scheduled
                        auto.maintain:
                          parameters:
                            heatSetpoint:
                              unit: celsius
                              min: 10
                              max: 35
                            coolSetpoint:
                              unit: celsius
                              min: 10
                              max: 35
                          execution:
                            - immediate
                            - scheduled
                        auto.schedule:
                          parameters: {}
                          execution:
                            - immediate
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                hvacCooling:
                  summary: HVAC actively cooling the home
                  description: >-
                    `active: true` and `mode: cool`. Room temperature above
                    `coolSetpoint`, so the unit is calling for cool.
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: live
                      state:
                        temperature: 26.2
                        active: true
                        heatSetpoint: 18
                        coolSetpoint: 24
                        holdType: schedule
                        mode: cool
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                hvacIdle:
                  summary: HVAC running but currently inactive
                  description: >-
                    `active: false` — temperature sits inside the deadband
                    between `heatSetpoint` and `coolSetpoint`. Nothing to do.
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: cache
                      state:
                        temperature: 21.5
                        active: false
                        heatSetpoint: 20
                        coolSetpoint: 24
                        holdType: schedule
                        mode: auto
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                hvacFollowingSchedule:
                  summary: HVAC following its programmed schedule
                  description: >-
                    `holdType: schedule` means the device is honouring its
                    programmed schedule rather than a permanent hold.
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: cache
                      state:
                        temperature: 21
                        active: false
                        heatSetpoint: 20
                        coolSetpoint: 24
                        holdType: schedule
                        mode: auto
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                hvacHolding:
                  summary: HVAC holding at a permanent setpoint
                  description: >-
                    `holdType: permanent` means the device is overriding its
                    schedule. Use `POST /hvac/{deviceId}` with `action:
                    auto.schedule` to release.
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: live
                      state:
                        temperature: 21.5
                        active: false
                        heatSetpoint: 20
                        coolSetpoint: 24
                        holdType: permanent
                        mode: auto
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                hvacOff:
                  summary: HVAC powered off
                  description: '`mode: off` — heating and cooling both disabled.'
                  value:
                    success: true
                    data:
                      id: device_hvac_001
                      vendor: example_vendor_a
                      sync:
                        available: true
                        lastPulledAt: '2026-05-07T09:23:45.000Z'
                      metadata:
                        model: Smart Thermostat 4
                        source: cache
                      state:
                        temperature: 19.8
                        active: false
                        heatSetpoint: 18
                        coolSetpoint: 24
                        holdType: permanent
                        mode: 'off'
                      conflictStrategies:
                        - cancel_and_replace
                      lastAction:
                        id: action_hvac_def456
                        command: heat
                        state: completed
                        createdAt: '2026-05-07T08:15:00.000Z'
                        updatedAt: '2026-05-07T08:18:00.000Z'
                        links:
                          self: /actions/action_hvac_def456
                      currentSchedule: null
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
        '400':
          description: >-
            The device manufacturer rejected the pull request
            (`INVALID_PARAMETERS` or `COMMAND_FAILED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingApiKey:
                  summary: No `x-api-key` header present
                  value:
                    success: false
                    error:
                      code: UNAUTHORIZED
                      message: Authentication is required.
                      details:
                        description: API key is required
                    meta:
                      requestId: req_8sW2dRtX
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /hvac/device_hvac_001
                      latencyMs: 2
        '403':
          description: >-
            Live access is disabled, consent is revoked, the device allowance is
            exceeded, or the manufacturer denied access to the device
            (`DEVICE_UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Device not found or access denied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                deviceNotFound:
                  summary: No device matches the ID for this customer
                  value:
                    success: false
                    error:
                      code: DEVICE_NOT_FOUND
                      message: No matching device was found for the supplied details.
                      details:
                        description: Device not found or access denied
                    meta:
                      requestId: req_5pH1cQbY
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /hvac/device_unknown_999
                      latencyMs: 5
        '410':
          description: >-
            The device is offline at the manufacturer (`DEVICE_OFFLINE`). See
            the [device error codes](/reference/error-codes) reference.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                deviceOffline:
                  summary: >-
                    The manufacturer reports the device as offline. Use the
                    cached state from the previous pull, or retry once the
                    device is back online.
                  value:
                    success: false
                    error:
                      code: DEVICE_OFFLINE
                      message: The device is currently offline at the manufacturer.
                    meta:
                      requestId: req_FnP7tAhH
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /hvac/device_hvac_001
                      latencyMs: 142
        '503':
          description: >-
            The device manufacturer service is temporarily unavailable
            (`SERVICE_UNAVAILABLE`). Retryable with exponential backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                serviceUnavailable:
                  summary: >-
                    The manufacturer cloud is down or refusing requests. Retry
                    with backoff.
                  value:
                    success: false
                    error:
                      code: SERVICE_UNAVAILABLE
                      message: >-
                        The device manufacturer service is temporarily
                        unavailable.
                    meta:
                      requestId: req_GoQ8uBiI
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /hvac/device_hvac_001
                      latencyMs: 1873
      security:
        - api-key: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl --request GET \
              --url 'https://api.amps.ai/hvac/device_abc123' \
              --header 'x-api-key: amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx'
        - lang: javascript
          label: Node
          source: >-
            const response = await
            fetch('https://api.amps.ai/hvac/device_abc123', {
              method: 'GET',
              headers: {
                'x-api-key': 'amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
              },
            });


            const data = await response.json();
        - lang: python
          label: Python
          source: |-
            import requests

            url = 'https://api.amps.ai/hvac/device_abc123'
            headers = {
                'x-api-key': 'amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
            }

            response = requests.get(url, headers=headers)
            data = response.json()
components:
  schemas:
    HvacResponse:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the HVAC device.
        vendor:
          type: string
          description: OEM display name.
        sync:
          type: object
          properties:
            available:
              type: boolean
            lastPulledAt:
              anyOf:
                - type: string
                - type: 'null'
          required:
            - available
            - lastPulledAt
        metadata:
          type: object
          properties:
            model:
              type: string
            cacheType:
              type: string
              enum:
                - expedite
                - normal
            source:
              type: string
              enum:
                - cache
                - live
                - fallback
                - projection
              description: >-
                How this device-state reading was obtained. `live`: read from
                the device just now. `cache`: a recent reading served from
                cache. `fallback`: the most recent stored reading, returned when
                the device could not be reached. `projection`: simulated sandbox
                state — sandbox devices are not physical hardware, so their
                reported state reflects the commands you have sent.
            degraded:
              description: >-
                Present and `true` when this reading was served from stored
                state because the platform is temporarily not contacting this
                device’s manufacturer (a protective circuit is open). The data
                is the most recent known reading, not a live one. Absent on a
                normal reading.
              type: boolean
          required:
            - model
            - source
        state:
          type: object
          properties:
            temperature:
              type: number
              description: Current temperature reading in degrees Celsius.
            active:
              type: boolean
              description: Whether the unit is actively heating or cooling right now.
            heatSetpoint:
              type: number
              description: Heat setpoint in degrees Celsius. The unit heats below this.
            coolSetpoint:
              type: number
              description: Cool setpoint in degrees Celsius. The unit cools above this.
            holdType:
              type: string
              enum:
                - permanent
                - schedule
              description: >-
                `permanent` if the unit is overriding its schedule with a fixed
                setpoint, `schedule` if it is following its programmed schedule.
            mode:
              type: string
              enum:
                - heat
                - cool
                - auto
                - 'off'
              description: Current operating mode.
          required:
            - temperature
            - active
            - heatSetpoint
            - coolSetpoint
            - holdType
            - mode
        commands:
          description: >-
            Per-command capability surface for this device. An open record keyed
            by command name (`heat`, `cool`, `idle`, `auto.maintain`,
            `auto.schedule`). Each entry exposes its parameter bounds and the
            execution shapes the device accepts. Absent when the device declares
            no commands.
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: object
            properties:
              parameters:
                type: object
                propertyNames:
                  type: string
                additionalProperties:
                  type: object
                  properties:
                    unit:
                      description: Unit of measure (e.g. `percent`, `kw`, `celsius`).
                      type: string
                    min:
                      description: Lower bound for the parameter value.
                      type: number
                    max:
                      description: Upper bound for the parameter value.
                      type: number
                    step:
                      description: >-
                        Increment the value must land on, counted from `min` (or
                        from 0 when no `min` is declared). A value off the grid
                        is rejected. Absent when the device accepts any value
                        within the bounds.
                      type: number
              execution:
                type: array
                items:
                  type: string
                  enum:
                    - immediate
                    - scheduled
                    - windowed
            required:
              - parameters
              - execution
        conflictStrategies:
          type: array
          items:
            type: string
            enum:
              - cancel_and_replace
              - queue_after
          description: >-
            Conflict-resolution strategies this device accepts on `onConflict`.
            Empty when the device declares none.
        scheduling:
          type: object
          properties:
            maxSlots:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: >-
                The largest number of slots a single schedule on this device can
                hold.
            supportsRecurrence:
              type: boolean
              description: >-
                Whether this device accepts a `recurrence` rule on a schedule.
                When `false`, only one-shot schedules are accepted.
            slotVariants:
              type: array
              items:
                type: string
                enum:
                  - at
                  - time
              description: >-
                The slot variants this device accepts. `at` = an absolute ISO
                8601 timestamp; `time` = a wall-clock `HH:mm` resolved against a
                schedule-level IANA `timezone`. A schedule may not mix the two.
            supportedRecurrence:
              description: >-
                The recurrence rules this device accepts, when
                `supportsRecurrence` is `true`. Absent when the device declares
                no recurrence support.
              type: array
              items:
                type: string
                enum:
                  - daily
                  - weekly
            minSlotDuration:
              description: >-
                The shortest slot duration this device honours, as an ISO 8601
                duration (e.g. `PT15M`). Absent when the device declares no
                minimum.
              type: string
          required:
            - maxSlots
            - supportsRecurrence
            - slotVariants
          description: >-
            The device's scheduling limits (max slots, supported slot variants,
            recurrence support). Presence-based and published ahead of the
            scheduler: the whole block is absent until the device declares its
            scheduling capabilities. Schedules are set on the device via `PUT
            /{type}/{id}/schedule` (coming soon) and followed today via the
            `auto.schedule` command.
        lastAction:
          anyOf:
            - type: object
              properties:
                id:
                  type: string
                  description: >-
                    Unique action identifier. Fetch the full record at
                    `links.self`.
                command:
                  type: string
                  description: >-
                    The canonical verb of the action (e.g. `charge`, `heat`,
                    `auto.schedule`). Derived from the same source as `GET
                    /actions`, so it always matches the full record.
                state:
                  type: string
                  enum:
                    - acknowledged
                    - completed
                    - failed
                    - scheduled
                    - cancelled
                  description: >-
                    Lifecycle state of the action. `scheduled` indicates a
                    deferred action awaiting its fire time; the terminal states
                    are `completed`, `failed`, and `cancelled`.
                createdAt:
                  type: string
                  format: date-time
                  description: ISO 8601 timestamp when the action was created.
                updatedAt:
                  type: string
                  format: date-time
                  description: ISO 8601 timestamp of the most recent state change.
                errorCode:
                  anyOf:
                    - type: string
                      enum:
                        - INVALID_CREDENTIALS
                        - INVALID_API_KEY
                        - INVALID_MFA_CODE
                        - MFA_REQUIRED
                        - ACCOUNT_LOCKED
                        - UNSUPPORTED_CREDENTIAL_TYPE
                        - DEVICE_NOT_FOUND
                        - DEVICE_OFFLINE
                        - DEVICE_UNAUTHORIZED
                        - NO_DEVICES_FOUND
                        - COMMAND_FAILED
                        - COMMAND_NOT_SUPPORTED
                        - EXECUTION_NOT_SUPPORTED
                        - MODE_OVERRIDDEN
                        - VPP_LOCKED
                        - INVALID_PARAMETERS
                        - INVALID_OEM_PARAMETERS
                        - INVALID_TIME_WINDOW
                        - BIND_NOT_SUPPORTED
                        - SCHEDULER_ACTIVE
                        - SCHEDULER_FULL
                        - UNSUPPORTED_AUTH_PATH
                        - SETTING_OUT_OF_RANGE
                        - NETWORK_ERROR
                        - RATE_LIMITED
                        - SERVICE_UNAVAILABLE
                        - TIMEOUT
                        - NOT_YET_AVAILABLE
                        - SIMULATED_FAILURE
                        - UNKNOWN_ERROR
                        - VEHICLE_NOT_CONNECTED
                        - SESSIONS_NOT_SUPPORTED
                        - CREDENTIAL_NOT_FOUND
                        - OEM_CIRCUIT_OPEN
                        - INVALID_OEM_RESPONSE
                        - COMMAND_NOT_APPLIED
                        - STALE_ACTION
                        - DEFERRED_SCHEDULE_FAILED
                        - UNROUTABLE_ACTION_TYPE
                        - UNAUTHORIZED
                        - EXPIRED_TOKEN
                        - FORBIDDEN
                        - INSUFFICIENT_PERMISSIONS
                        - LIVE_ACCESS_DISABLED
                        - VALIDATION_ERROR
                        - INVALID_INPUT
                        - INVALID_REQUEST_BODY
                        - EMPTY_SETTINGS
                        - PAYLOAD_TOO_LARGE
                        - UNSUPPORTED_MEDIA_TYPE
                        - NOT_FOUND
                        - METHOD_NOT_ALLOWED
                        - CONFLICT
                        - CONFLICT_IN_EXECUTION
                        - GONE
                        - RATE_LIMIT_EXCEEDED
                        - INTERNAL_ERROR
                        - NOT_IMPLEMENTED
                        - BAD_GATEWAY
                        - GATEWAY_TIMEOUT
                        - DEVICE_TYPE_MISMATCH
                        - CONSENT_REVOKED
                        - DEVICE_OVERAGE
                        - SETTINGS_STORE_UNAVAILABLE
                        - ACTION_NOT_FOUND
                        - DIRECT_ACTION_UNSUPPORTED
                        - UNSUPPORTED_ACTION
                        - UNSUPPORTED_MODE
                        - UNSUPPORTED_PARAMETER
                        - UNSUPPORTED_PARAMETER_COMBINATION
                        - UNSUPPORTED_UNIT
                        - PARAMETER_OUT_OF_RANGE
                        - START_IN_PAST
                        - START_OUT_OF_RANGE
                        - START_OFFSET_NOT_ACCEPTED
                        - START_INVALID_FORMAT
                        - START_NONEXISTENT_WALL_CLOCK
                        - TIMEZONE_UNRESOLVED
                        - INVALID_TIMEZONE
                        - ACTION_NOT_CANCELLABLE
                        - STRATEGY_NOT_SUPPORTED
                        - UNSUPPORTED_SETTING
                        - UNSUPPORTED_SETTING_COMBINATION
                        - READ_ONLY_SETTING
                        - INVALID_SETTING_UNIT
                        - INVALID_SETTING_VALUE
                        - NO_OP
                        - NO_OVERRIDE
                        - AVAILABILITY_ENV_UNSUPPORTED
                        - UNSUPPORTED_COMBINATION
                    - type: 'null'
                  description: >-
                    Machine-readable error code when `state` is `failed`. Null
                    otherwise. Lets a device card show the failure reason
                    without fetching the full record.
                errorMessage:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: >-
                    Human-readable error message when `state` is `failed`. Null
                    otherwise.
                links:
                  type: object
                  properties:
                    self:
                      type: string
                      description: >-
                        Canonical path to the full action record: `GET
                        /actions/{actionId}`.
                  required:
                    - self
                  description: Hypermedia link to the full action record.
              required:
                - id
                - command
                - state
                - createdAt
                - updatedAt
                - errorCode
                - errorMessage
                - links
              description: >-
                Summary of the most recent action dispatched to this device. A
                pointer, not a copy: the full record (parameters, timestamps,
                result) is at `links.self`.
            - type: 'null'
          description: >-
            Summary of the most recent action dispatched to this device; full
            record at `links.self`. Null when the device has no actions yet. A
            pointer for the "render a device card in one call" case, not a
            denormalised copy.
        currentSchedule:
          anyOf:
            - type: object
              properties:
                id:
                  type: string
                  description: >-
                    Unique schedule identifier. Fetch the full schedule at
                    `links.self`.
                status:
                  type: string
                  description: >-
                    Lifecycle status of the schedule (e.g. `active`). The full
                    status vocabulary lands with the scheduler.
                links:
                  type: object
                  properties:
                    self:
                      type: string
                      description: >-
                        Canonical path to the device's full schedule: `GET
                        /{type}/{id}/schedule`.
                  required:
                    - self
                  description: Hypermedia link to the full schedule.
              required:
                - id
                - status
                - links
              description: >-
                Summary of the schedule currently governing this device. A
                pointer, not a copy: the full schedule is at `links.self`.
            - type: 'null'
          description: >-
            The device's active Amps schedule. Always null until the scheduler
            ships.
      required:
        - id
        - vendor
        - sync
        - metadata
        - state
        - conflictStrategies
        - lastAction
        - currentSchedule
      title: HVAC Response
    ResponseMeta:
      type: object
      title: Response Meta
      description: >-
        Metadata attached to every response: the request identifier, the serving
        environment, the build timestamp, and the server-side latency.
      required:
        - environment
        - timestamp
        - latencyMs
      properties:
        requestId:
          description: >-
            Unique request identifier. Echoes the `x-request-id` header when
            present; otherwise generated server-side.
          type: string
        environment:
          type: string
          description: The environment that served the request (`sandbox` or `live`).
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the response was built.
        latencyMs:
          type: integer
          description: Server-side processing time in milliseconds.
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Always `false` for error responses.
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INVALID_CREDENTIALS
                - INVALID_API_KEY
                - INVALID_MFA_CODE
                - MFA_REQUIRED
                - ACCOUNT_LOCKED
                - UNSUPPORTED_CREDENTIAL_TYPE
                - DEVICE_NOT_FOUND
                - DEVICE_OFFLINE
                - DEVICE_UNAUTHORIZED
                - NO_DEVICES_FOUND
                - COMMAND_FAILED
                - COMMAND_NOT_SUPPORTED
                - EXECUTION_NOT_SUPPORTED
                - MODE_OVERRIDDEN
                - VPP_LOCKED
                - INVALID_PARAMETERS
                - INVALID_OEM_PARAMETERS
                - INVALID_TIME_WINDOW
                - BIND_NOT_SUPPORTED
                - SCHEDULER_ACTIVE
                - SCHEDULER_FULL
                - UNSUPPORTED_AUTH_PATH
                - SETTING_OUT_OF_RANGE
                - NETWORK_ERROR
                - RATE_LIMITED
                - SERVICE_UNAVAILABLE
                - TIMEOUT
                - NOT_YET_AVAILABLE
                - SIMULATED_FAILURE
                - UNKNOWN_ERROR
                - VEHICLE_NOT_CONNECTED
                - SESSIONS_NOT_SUPPORTED
                - CREDENTIAL_NOT_FOUND
                - OEM_CIRCUIT_OPEN
                - INVALID_OEM_RESPONSE
                - COMMAND_NOT_APPLIED
                - STALE_ACTION
                - DEFERRED_SCHEDULE_FAILED
                - UNROUTABLE_ACTION_TYPE
                - UNAUTHORIZED
                - EXPIRED_TOKEN
                - FORBIDDEN
                - INSUFFICIENT_PERMISSIONS
                - LIVE_ACCESS_DISABLED
                - VALIDATION_ERROR
                - INVALID_INPUT
                - INVALID_REQUEST_BODY
                - EMPTY_SETTINGS
                - PAYLOAD_TOO_LARGE
                - UNSUPPORTED_MEDIA_TYPE
                - NOT_FOUND
                - METHOD_NOT_ALLOWED
                - CONFLICT
                - CONFLICT_IN_EXECUTION
                - GONE
                - RATE_LIMIT_EXCEEDED
                - INTERNAL_ERROR
                - NOT_IMPLEMENTED
                - BAD_GATEWAY
                - GATEWAY_TIMEOUT
                - DEVICE_TYPE_MISMATCH
                - CONSENT_REVOKED
                - DEVICE_OVERAGE
                - SETTINGS_STORE_UNAVAILABLE
                - ACTION_NOT_FOUND
                - DIRECT_ACTION_UNSUPPORTED
                - UNSUPPORTED_ACTION
                - UNSUPPORTED_MODE
                - UNSUPPORTED_PARAMETER
                - UNSUPPORTED_PARAMETER_COMBINATION
                - UNSUPPORTED_UNIT
                - PARAMETER_OUT_OF_RANGE
                - START_IN_PAST
                - START_OUT_OF_RANGE
                - START_OFFSET_NOT_ACCEPTED
                - START_INVALID_FORMAT
                - START_NONEXISTENT_WALL_CLOCK
                - TIMEZONE_UNRESOLVED
                - INVALID_TIMEZONE
                - ACTION_NOT_CANCELLABLE
                - STRATEGY_NOT_SUPPORTED
                - UNSUPPORTED_SETTING
                - UNSUPPORTED_SETTING_COMBINATION
                - READ_ONLY_SETTING
                - INVALID_SETTING_UNIT
                - INVALID_SETTING_VALUE
                - NO_OP
                - NO_OVERRIDE
                - AVAILABILITY_ENV_UNSUPPORTED
                - UNSUPPORTED_COMBINATION
              description: >-
                Machine-readable error code (e.g. `VALIDATION_ERROR`,
                `CONFLICT`, `UNSUPPORTED_MODE`). Stable across releases; safe to
                switch on.
            message:
              type: string
              description: Human-readable error message.
            details:
              description: >-
                Structured context for the error: which fields were invalid,
                which actions conflicted, which capabilities the device
                declares. Shape varies by error code.
              type: object
              properties: {}
              additionalProperties: {}
          required:
            - code
            - message
          description: Error envelope.
        meta:
          type: object
          properties:
            requestId:
              description: >-
                Unique request identifier. Echoes the `x-request-id` header when
                present; otherwise generated server-side.
              type: string
            timestamp:
              type: string
              description: ISO 8601 timestamp when the error response was built.
            path:
              type: string
              description: Request path that produced the error.
            latencyMs:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Server-side processing time in milliseconds.
          required:
            - timestamp
            - path
            - latencyMs
          description: Request metadata.
      required:
        - success
        - error
        - meta
      title: Error Response
      description: >-
        Uniform error response. The `error.code` identifies the failure,
        `error.message` carries a human-readable explanation, and
        `error.details` carries structured context (failed fields, conflicting
        action IDs, supported capabilities) where relevant.
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key

````