> ## 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.

# List HVAC devices

> Get a paginated list of HVAC devices with their last pull state



## OpenAPI

````yaml /openapi.json get /hvac
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:
    get:
      tags:
        - HVAC
      summary: List HVAC devices
      description: Get a paginated list of HVAC devices with their last pull state
      operationId: listHvacs
      parameters:
        - name: userId
          required: false
          in: query
          description: Filter devices by userId
          schema:
            example: user_abc123
            type: string
        - name: offset
          required: false
          in: query
          description: 'Number of devices to skip (default: 0)'
          schema:
            example: 0
            type: number
        - name: limit
          required: false
          in: query
          description: 'Maximum number of devices to return (1-50, default: 10)'
          schema:
            example: 10
            type: number
      responses:
        '200':
          description: HVAC devices 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/PaginatedHvacResponseDto'
                  meta:
                    $ref: '#/components/schemas/ResponseMeta'
              examples:
                pageWithDevices:
                  summary: A page with two HVAC devices in different modes
                  value:
                    success: true
                    data:
                      items:
                        - 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: true
                            heatSetpoint: 20
                            coolSetpoint: 24
                            holdType: schedule
                            mode: auto
                          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
                        - id: device_hvac_002
                          vendor: example_vendor_b
                          sync:
                            available: true
                            lastPulledAt: '2026-05-07T09:24:10.000Z'
                          metadata:
                            model: Smart Thermostat 3
                            source: cache
                          state:
                            temperature: 23.8
                            active: false
                            heatSetpoint: 18
                            coolSetpoint: 22
                            holdType: permanent
                            mode: cool
                          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_mno345
                            command: cool
                            state: completed
                            createdAt: '2026-05-07T07:55:00.000Z'
                            updatedAt: '2026-05-07T07:58:00.000Z'
                            links:
                              self: /actions/action_hvac_mno345
                          currentSchedule: null
                      pagination:
                        limit: 10
                        offset: 0
                        total: 2
                        hasMore: false
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                emptyPage:
                  summary: No HVAC devices match the filters
                  value:
                    success: true
                    data:
                      items: []
                      pagination:
                        limit: 10
                        offset: 0
                        total: 0
                        hasMore: false
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
        '400':
          description: >-
            Invalid query parameters (e.g. `limit` outside 1-50, `offset`
            negative).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidLimit:
                  summary: '`limit` outside the supported range'
                  value:
                    success: false
                    error:
                      code: VALIDATION_ERROR
                      message: Request validation failed.
                      details:
                        fields:
                          limit:
                            - Number must be less than or equal to 50
                        description: Invalid query parameters
                    meta:
                      requestId: req_2fJ7kPqV
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /hvac?limit=200
                      latencyMs: 4
        '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
                      latencyMs: 2
      security:
        - api-key: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl --request GET \
              --url 'https://api.amps.ai/hvac' \
              --header 'x-api-key: amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx'
        - lang: javascript
          label: Node
          source: |-
            const response = await fetch('https://api.amps.ai/hvac', {
              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'
            headers = {
                'x-api-key': 'amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
            }

            response = requests.get(url, headers=headers)
            data = response.json()
components:
  schemas:
    PaginatedHvacResponseDto:
      type: object
      properties:
        items:
          type: array
          items:
            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
        pagination:
          type: object
          properties:
            limit:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Maximum number of items returned.
            offset:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Number of items skipped.
            total:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Total number of items matching the query.
            hasMore:
              type: boolean
              description: '`true` if more items exist beyond the current page.'
          required:
            - limit
            - offset
            - total
            - hasMore
      required:
        - items
        - pagination
      title: Paginated Hvac
    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

````