openapi: 3.1.0
info:
  title: Cozify OneAPI
  version: '3.0'
  termsOfService: https://en.cozify.fi/pages/privacy-policy
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  description: |-
    The [OpenAPI specification](./one-3.0.yaml) for the Cozify ONE platform.

    ## Graph API

    Cozify Graph is the primary, unified API surface. Instead of per-resource REST
    endpoints, a single pair of endpoints dispatches a polymorphic set of typed messages,
    each selected by its `type` discriminator:

    - `PUT /graph/command` — change state.
    - `POST /graph/query` — read state.

    Commands that start long-running work return an **operation** you can track to
    completion, and server-side changes are delivered live as **push messages** over the
    SignalR hub stream. The classic per-provider REST endpoints (Hub, Hubs, DeviceRegister)
    are deprecated in favor of Graph.

    ## Terminology

    If you are new to Cozify Services, there are some terms you might not be familiar with.

    - **resource** — A manageable item available through the platform. Hubs, Devices and
      Sites are examples of resources; resource groups, subscriptions and tags are too.
    - **resource group** — A container that holds related resources for a platform
      solution. You decide which resources belong to a group based on what makes the most
      sense for your organization.
    - **resource provider** — A service that supplies platform resources. For example, the
      canonical site resource provider is `Cozify.Sites`, which supplies the structural
      management of site (a.k.a. building) resources. `Cozify.Site` is accepted as a
      compatibility alias for clients that model the provider namespace separately from the
      plural resource type. `Cozify.DeviceRegister` is another common resource provider.

    ## SignalR (/hub/v1)

    In addition to the REST endpoints described here, the API is available over a persistent
    SignalR connection at the `/hub/v1` endpoint. See Microsoft's guide to
    [SignalR streaming](https://learn.microsoft.com/en-us/aspnet/core/signalr/streaming) for
    how to consume it from a .NET / JavaScript / Java client.

    ### Graph over SignalR

    The Graph command/query API is exposed as hub methods that carry the same envelopes as
    the REST endpoints:

    - `Command(CommandRequest)` returns `CommandResponse` — the equivalent of `PUT /graph/command`.
    - `Query(QueryRequest)` returns `QueryResponse` — the equivalent of `POST /graph/query`.

    ### Device events

    1. To receive device events you **must open the event stream** — otherwise no events are
       delivered, regardless of subscriptions. Open the `DeviceEventsStream` stream; its
       messages are delivered over SignalR and are not part of this OpenAPI document.
    2. To manage event subscriptions, use the following hub methods:
       - `DeviceEventsSubscribeAll(deviceRegisterId)` — subscribe to events from **all**
         devices in the register.
       - `DeviceEventsUnsubscribeAll(deviceRegisterId)` — unsubscribe from **all** device
         events from the register.
       - `DeviceEventsSubscribe(request)` — subscribe to events from specific devices in the
         register. **Warning:** if you previously subscribed to **all** events from the same
         register, this changes nothing — you will still receive events from every device.
       - `DeviceEventsUnsubscribe(request)` — unsubscribe from specific devices in the
         register. **Warning:** if you previously subscribed to **all** events from the same
         register, this changes nothing — use `DeviceEventsUnsubscribeAll` instead.

    > **Note:** Cozify supports Transport Layer Security (TLS) 1.2 or later only.
  contact:
    email: support@cozify.fi
servers:
  - url: https://one.cozify.io
security:
  - Bearer: []
tags:
  - name: DeviceRegister
    description: Operations for managing device registers, such as executing commands on device registers and querying device register states.
  - name: Graph
    description: Cozify Graph is the unified gateway to data and actions in Cozify One. In place of per-resource REST endpoints, a single pair of endpoints - `PUT /graph/command` to change state and `POST /graph/query` to read it - dispatches a polymorphic set of typed commands and queries, each selected by its `type` discriminator. Commands that start long-running work return an operation you can track to completion, and server-side changes are delivered live as push messages over stream.
  - name: Hub
    description: Operations related to the Cozify Hub, including command execution and querying the state of the hub and its connected devices.
  - name: Hubs
    description: Operations related to the Cozify Hubs services, including command execution and querying the state of the fleet.
  - name: Service
    description: Service-level operational endpoints, such as the anonymous status/version probe.
paths:
  /status:
    get:
      operationId: Status
      summary: Status
      description: Returns service status, including the running version. Anonymous - no authentication is required.
      tags:
        - Service
      security: []
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceStatus'
        '429':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
  /graph/query:
    post:
      operationId: Query
      summary: Query
      description: Allows the execution of a specific query.
      tags:
        - Graph
      requestBody:
        description: Request object for query.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueryRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /graph/command:
    put:
      operationId: Command
      summary: Command
      description: Allows the execution of a specific command.
      tags:
        - Graph
      requestBody:
        description: Request object for command.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CommandRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommandResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /graph/push:
    post:
      operationId: Push
      summary: Push
      description: 'Marker endpoint for the SignalR `Push` streaming method. Server-to-client push messages are delivered over the SignalR hub `Push` stream, not over HTTP - calling this HTTP endpoint always returns 400. It exists to publish the `PushMessage` shape delivered over the stream. SignalR method: `Push`.'
      tags:
        - Graph
      requestBody:
        description: Schema marker only. Documents the shape of the `PushMessage` delivered over the SignalR `Push` stream; this HTTP endpoint does not consume a request body and always returns 400.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PushMessage'
      responses:
        '400':
          $ref: '#/components/responses/Problem'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/Problem'
  /Providers/Cozify.Hub/{hubId}/Command:
    put:
      operationId: HubCommand
      summary: HubCommand
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/command
      description: Deprecated. Use /graph/command with migrated hub Graph commands instead.
      tags:
        - Hub
      parameters:
        - $ref: '#/components/parameters/HubId'
      requestBody:
        description: Request object for command.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HubCommandRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubCommandResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /Providers/Cozify.Hub/{hubId}/Query:
    post:
      operationId: HubQuery
      summary: HubQuery
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/query
      description: Deprecated. Use /graph/query with migrated hub Graph queries instead.
      tags:
        - Hub
      parameters:
        - $ref: '#/components/parameters/HubId'
      requestBody:
        description: Request object for query.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HubQueryRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubQueryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /Providers/Cozify.Hubs/Query:
    post:
      operationId: HubsQuery
      summary: HubsQuery
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/query
      description: Deprecated. Use /graph/query with migrated hubs Graph queries instead.
      tags:
        - Hubs
      requestBody:
        description: Request object for query.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HubsQueryRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubsQueryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /Providers/Cozify.DeviceRegister/{deviceRegisterId}/Command:
    put:
      operationId: DeviceRegisterCommand
      summary: DeviceRegisterCommand
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/command
      description: Deprecated. Use /graph/command with migrated device register Graph commands instead.
      tags:
        - DeviceRegister
      parameters:
        - $ref: '#/components/parameters/DeviceRegisterId'
      requestBody:
        description: Request object for command.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceRegisterCommandRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceRegisterCommandResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
  /Providers/Cozify.DeviceRegister/{deviceRegisterId}/Query:
    post:
      operationId: DeviceRegisterQuery
      summary: DeviceRegisterQuery
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/query
      description: Deprecated. Use /graph/query with migrated device register Graph queries instead.
      tags:
        - DeviceRegister
      parameters:
        - $ref: '#/components/parameters/DeviceRegisterId'
      requestBody:
        description: Request object for query.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceRegisterQueryRequest'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceRegisterQueryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
components:
  securitySchemes:
    Bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    Problem:
      type: object
      additionalProperties: true
      minProperties: 1
      description: The Problem Details JSON Object [[RFC7807](https://tools.ietf.org/html/rfc7807)].
      properties:
        type:
          type: string
          description: A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that identifies the problem type. It should provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
          format: uri
        title:
          type: string
          description: A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
        status:
          type: integer
          description: The HTTP status code.
          minimum: 400
          maximum: 599
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence of the problem.
        instance:
          type: string
          description: A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
    ServiceStatus:
      type: object
      description: Service status information.
      additionalProperties: false
      properties:
        version:
          type: string
          description: The running service's informational assembly version (SemVer, optionally with build metadata).
          example: 3.0.1+build.42
      required:
        - version
    Query:
      type: object
      x-abstract: true
      description: Base type for queries. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          GetDefaultDeviceConfigurationTemplateQuery: '#/components/schemas/GetDefaultDeviceConfigurationTemplateQuery'
          GetDeviceConfigurationQuery: '#/components/schemas/GetDeviceConfigurationQuery'
          GetDeviceConfigurationTemplateQuery: '#/components/schemas/GetDeviceConfigurationTemplateQuery'
          GetDeviceDefinitionTemplateQuery: '#/components/schemas/GetDeviceDefinitionTemplateQuery'
          GetDeviceRegisterEntryColumnsQuery: '#/components/schemas/GetDeviceRegisterEntryColumnsQuery'
          GetDeviceRegisterEntryQuery: '#/components/schemas/GetDeviceRegisterEntryQuery'
          GetDeviceRegisterQuery: '#/components/schemas/GetDeviceRegisterQuery'
          GetDeviceStateQuery: '#/components/schemas/GetDeviceStateQuery'
          ListDeviceConfigurationStatusesQuery: '#/components/schemas/ListDeviceConfigurationStatusesQuery'
          ListDeviceConfigurationTemplatesQuery: '#/components/schemas/ListDeviceConfigurationTemplatesQuery'
          ListDeviceDefinitionTemplatesQuery: '#/components/schemas/ListDeviceDefinitionTemplatesQuery'
          ListDeviceRegisterEntriesQuery: '#/components/schemas/ListDeviceRegisterEntriesQuery'
          ListHubUserAssignmentsQuery: '#/components/schemas/ListHubUserAssignmentsQuery'
          GetDeviceRegisterKeyVaultQuery: '#/components/schemas/GetDeviceRegisterKeyVaultQuery'
          GetTenantKeyVaultQuery: '#/components/schemas/GetTenantKeyVaultQuery'
          ListDeviceRegisterKeyVaultQuery: '#/components/schemas/ListDeviceRegisterKeyVaultQuery'
          ListTenantKeyVaultQuery: '#/components/schemas/ListTenantKeyVaultQuery'
          GetOperationQuery: '#/components/schemas/GetOperationQuery'
          ListOperationsQuery: '#/components/schemas/ListOperationsQuery'
          GetSiteDashboardTemplateQuery: '#/components/schemas/GetSiteDashboardTemplateQuery'
          GetSiteEgressStatusQuery: '#/components/schemas/GetSiteEgressStatusQuery'
          GetSiteEgressTargetQuery: '#/components/schemas/GetSiteEgressTargetQuery'
          GetSiteEntityDeviceQuery: '#/components/schemas/GetSiteEntityDeviceQuery'
          GetSiteEntityDeviceStateQuery: '#/components/schemas/GetSiteEntityDeviceStateQuery'
          GetSiteEntityQuery: '#/components/schemas/GetSiteEntityQuery'
          GetSitePropertiesQuery: '#/components/schemas/GetSitePropertiesQuery'
          GetSiteQuery: '#/components/schemas/GetSiteQuery'
          GetSiteSchemaQuery: '#/components/schemas/GetSiteSchemaQuery'
          GetSiteSchemaTemplateQuery: '#/components/schemas/GetSiteSchemaTemplateQuery'
          ListSiteDashboardTemplatesQuery: '#/components/schemas/ListSiteDashboardTemplatesQuery'
          ListSiteEgressStatusesQuery: '#/components/schemas/ListSiteEgressStatusesQuery'
          ListSiteEgressTargetsQuery: '#/components/schemas/ListSiteEgressTargetsQuery'
          ListSiteEntitiesQuery: '#/components/schemas/ListSiteEntitiesQuery'
          ListSiteSchemaTemplatesQuery: '#/components/schemas/ListSiteSchemaTemplatesQuery'
          ListSpotPricesQuery: '#/components/schemas/ListSpotPricesQuery'
          CheckResourceNameValidityQuery: '#/components/schemas/CheckResourceNameValidityQuery'
          GetResourceGroupQuery: '#/components/schemas/GetResourceGroupQuery'
          GetResourceQuery: '#/components/schemas/GetResourceQuery'
          GetSubscriptionQuery: '#/components/schemas/GetSubscriptionQuery'
          ListResourceGroupsQuery: '#/components/schemas/ListResourceGroupsQuery'
          ListResourcesQuery: '#/components/schemas/ListResourcesQuery'
          ListSubscriptionsQuery: '#/components/schemas/ListSubscriptionsQuery'
          GetCurrentTenantQuery: '#/components/schemas/GetCurrentTenantQuery'
          ListTenantsQuery: '#/components/schemas/ListTenantsQuery'
      required:
        - type
    DeviceType:
      type: string
      description: The device type in device register provider.
      minLength: 1
      maxLength: 50
      pattern: ^([A-Z0-9_])+$
      example: MY_CUSTOM_DEVICE
    GetDefaultDeviceConfigurationTemplateQuery:
      type: object
      description: Get the default device configuration template for a device type in the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
      required:
        - deviceType
    DeviceRegisterId:
      type: string
      description: Globally unique device register identifier, used as a DNS label in URLs such as `{deviceRegisterId}.{region}.cozify.io` — letters (any case), digits, and interior hyphens (no leading or trailing hyphen). Case-insensitive (the casing you send is preserved, but identity folds case).
      minLength: 3
      maxLength: 63
      pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$
      example: default-devices
    DeviceId:
      type: string
      description: |-
        The identifier of the device within a device register. Letters (any case), digits, and hyphens so
        it is safe as a path segment in URLs and storage keys. Case-insensitive: the casing you send is
        preserved, but identity folds case.
      minLength: 1
      maxLength: 64
      pattern: ^([A-Za-z0-9-])+$
      example: 123e4567-e89b-12d3-a456-426655440000
    GetDeviceConfigurationQuery:
      type: object
      description: Query to retrieve the desired configuration and revision state of a device.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
    TemplateId:
      type: string
      description: Caller-assigned template id, unique within its template collection. Lowercase letters, digits, and hyphens.
      minLength: 1
      maxLength: 64
      pattern: ^([a-z0-9-])+$
      example: default
    GetDeviceConfigurationTemplateQuery:
      type: object
      description: Get a single device configuration template by device type and id.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
      required:
        - deviceType
        - templateId
    GetDeviceDefinitionTemplateQuery:
      type: object
      description: Get a single device definition template by device type and id.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
      required:
        - deviceType
        - templateId
    GetDeviceRegisterEntryColumnsQuery:
      type: object
      description: |-
        Query for the distinct values available when filtering device entries (types, capabilities,
        manufacturers, models). Used to populate filter controls. Set a flag to include that column's
        known values in the result.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceType:
          description: Include the array of known device types in the result.
          type: boolean
          default: false
        capabilities:
          description: Include the array of known device capabilities in the result.
          type: boolean
          default: false
        manufacturer:
          description: Include the array of known device manufacturers in the result.
          type: boolean
          default: false
        model:
          description: Include the array of known device models in the result.
          type: boolean
          default: false
      required:
        - deviceRegisterId
    GetDeviceRegisterEntryQuery:
      type: object
      description: Query to retrieve a single device entry from a device register.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
    GetDeviceRegisterQuery:
      type: object
      description: Retrieve a device register's metadata.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
      required:
        - deviceRegisterId
    GetDeviceStateQuery:
      type: object
      description: Query to read a single device's current reported state from a device register.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
    QuerySkip:
      type: integer
      description: Specifies the number of items to skip for query.
      format: int64
      minimum: 0
      example: 0
    QueryLimit:
      type: integer
      description: Specifies the maximum number of items to include in query result.
      format: int64
      minimum: 1
      maximum: 2000
      example: 10
    ListDeviceConfigurationStatusesQuery:
      type: object
      description: Query to list the configuration revision state of all devices in a register.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
      required:
        - deviceRegisterId
        - skip
        - limit
    ListDeviceConfigurationTemplatesQuery:
      type: object
      description: List device configuration templates for the caller's tenant, optionally filtered to a single device type.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
      required:
        - skip
        - limit
    ListDeviceDefinitionTemplatesQuery:
      type: object
      description: List device definition templates for the caller's tenant, optionally filtered to a single device type.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
      required:
        - skip
        - limit
    ListDeviceRegisterEntriesQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing device register entries. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListDeviceRegisterEntriesQueryKeywordFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryKeywordFilter'
          ListDeviceRegisterEntriesQueryNativeIdFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryNativeIdFilter'
          ListDeviceRegisterEntriesQuerySerialNumberFilter: '#/components/schemas/ListDeviceRegisterEntriesQuerySerialNumberFilter'
          ListDeviceRegisterEntriesQueryHubRoutingEntryFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryHubRoutingEntryFilter'
          ListDeviceRegisterEntriesQueryDeviceRoutingEntryFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryDeviceRoutingEntryFilter'
          ListDeviceRegisterEntriesQueryDeviceTypeFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryDeviceTypeFilter'
          ListDeviceRegisterEntriesQueryCapabilityFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryCapabilityFilter'
          ListDeviceRegisterEntriesQueryManufacturerFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryManufacturerFilter'
          ListDeviceRegisterEntriesQueryModelFilter: '#/components/schemas/ListDeviceRegisterEntriesQueryModelFilter'
          ListDeviceRegisterEntriesQuerySiteLinkFilter: '#/components/schemas/ListDeviceRegisterEntriesQuerySiteLinkFilter'
      required:
        - type
    QueryKeyword:
      type: string
      description: The keyword to search for.
      minLength: 2
    ListDeviceRegisterEntriesQueryKeywordFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          $ref: '#/components/schemas/QueryKeyword'
      required:
        - keyword
    DeviceNativeId:
      type: string
      description: The native identifier of the device.
      maxLength: 50
      pattern: ^([a-zA-Z0-9_\-\s])+$
      example: 3RD_PARTY_1_6_DEVICE_ID
    ListDeviceRegisterEntriesQueryNativeIdFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
      required:
        - nativeId
    DeviceSerialNumber:
      type: string
      description: The serial number of the device.
      minLength: 2
      maxLength: 50
      pattern: ^([a-zA-Z0-9_\-\s])+$
      example: 4CE0460D0G
    ListDeviceRegisterEntriesQuerySerialNumberFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
      required:
        - serialNumber
    HubId:
      type: string
      description: The identifier of the hub.
      format: uuid
    ListDeviceRegisterEntriesQueryHubRoutingEntryFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
      required:
        - hubId
    ListDeviceRegisterEntriesQueryDeviceRoutingEntryFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceId
    ListDeviceRegisterEntriesQueryDeviceTypeFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
          example:
            - COZIFY_HUB
            - SIGNAL
            - MULTISENSOR
      required:
        - deviceType
    Capability:
      type: string
      description: Defines the capability of the device.
      minLength: 1
      maxLength: 50
      pattern: ^([A-Z0-9_])+$
      example: SELF_MOTION
    ListDeviceRegisterEntriesQueryCapabilityFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        capability:
          $ref: '#/components/schemas/Capability'
          example:
            - DEVICE
            - ON_OFF
            - TEMPERATURE
      required:
        - capability
    DeviceManufacturer:
      type: string
      description: The manufacturer of the device.
      maxLength: 50
      pattern: ^([a-zA-Z0-9_.,\-'()&/:+#@!?\s\u0080-\uFFFF]+)$
      example: My Cömpany Ltd.
    ListDeviceRegisterEntriesQueryManufacturerFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
          example:
            - Cozify Oy
            - My Cömpany Ltd.
      required:
        - manufacturer
    DeviceModel:
      type: string
      description: The model of the device.
      maxLength: 50
      pattern: ^([a-zA-Z0-9_.,\-'()&/:+#@!?\s\u0080-\uFFFF]+)$
      example: Über IoT Device
    ListDeviceRegisterEntriesQueryModelFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        model:
          $ref: '#/components/schemas/DeviceModel'
          example:
            - ION
            - ZEN
            - DIN
            - Über IoT Device
      required:
        - model
    ListDeviceRegisterEntriesQuerySiteLinkFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      additionalProperties: false
      properties:
        siteId:
          description: |
            The identifier of the site to match.

            Use **NULL** to match entries without a site.
            Use '*' to match entries with any site.
          type: string
          pattern: ^(\*|.{2,})$
    ListDeviceRegisterEntriesQuery:
      type: object
      description: Query to list device entries in a device register.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListDeviceRegisterEntriesQueryFilter'
      required:
        - deviceRegisterId
        - skip
        - limit
    UserIdProperty:
      type: string
      description: The identifier of the user.
      format: uuid
      example: 3ee5d62c-fa38-42a0-a5ac-0c4b315d75fb
    ListHubUserAssignmentsQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing hub user assignments. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the filter type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListHubUserAssignmentsQueryKeywordFilter: '#/components/schemas/ListHubUserAssignmentsQueryKeywordFilter'
      required:
        - type
    ListHubUserAssignmentsQueryKeywordFilter:
      type: object
      description: Filter hub user assignments using a keyword matched against email, nickname, or phone number.
      allOf:
        - $ref: '#/components/schemas/ListHubUserAssignmentsQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          type: string
          minLength: 2
          description: Keyword matched against email, nickname, and phone number.
      required:
        - keyword
    ListHubUserAssignmentsQuery:
      type: object
      description: List hub user assignments.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          type: array
          description: Optional filters for refining the query.
          items:
            $ref: '#/components/schemas/ListHubUserAssignmentsQueryFilter'
      required:
        - hubId
        - skip
        - limit
    KeyId:
      type: string
      description: Identifier of the key vault entry. Letters (any case), digits, and the separators '-', '_', ':'.
      minLength: 1
      maxLength: 64
      pattern: ^([A-Za-z0-9_:-])+$
      example: my-service_key:v1
    GetDeviceRegisterKeyVaultQuery:
      type: object
      description: Query to retrieve a specific device register key vault entry based on the provided device register identifier and key identifier.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        keyId:
          $ref: '#/components/schemas/KeyId'
      required:
        - deviceRegisterId
        - keyId
    GetTenantKeyVaultQuery:
      type: object
      description: Query to retrieve a specific tenant key vault entry based on the provided key identifier.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        keyId:
          $ref: '#/components/schemas/KeyId'
      required:
        - keyId
    ListDeviceRegisterKeyVaultQuery:
      type: object
      description: Query to retrieve a list of device register key vault entries.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
      required:
        - deviceRegisterId
        - skip
        - limit
    ListTenantKeyVaultQuery:
      type: object
      description: Query to retrieve a list of tenant key vault entries.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
      required:
        - skip
        - limit
    GetOperationQuery:
      type: object
      description: Retrieve a single operation's status by id.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        operationId:
          type: string
          format: uuid
          description: The id of the operation to retrieve.
      required:
        - operationId
    OperationScope:
      type: string
      description: Visibility scope of an operation.
      enum:
        - Undefined
        - System
        - Tenant
        - User
    OperationStatus:
      type: string
      description: Lifecycle status of an operation.
      enum:
        - Undefined
        - Pending
        - Running
        - Succeeded
        - Faulted
        - Cancelled
    ListOperationsQueryOrder:
      type: object
      description: Ordering options applied when listing operations.
      additionalProperties: false
      properties:
        field:
          type: string
          description: Field to order the results by.
          enum:
            - undefined
            - createdAt
            - startedAt
            - completedAt
            - status
          default: createdAt
        descending:
          type: boolean
          description: Whether the results are ordered in descending order.
          default: true
      required:
        - field
    ListOperationsQuery:
      type: object
      description: List operations within a visibility scope, optionally filtered by type and status.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        scope:
          $ref: '#/components/schemas/OperationScope'
          description: Visibility scope to list within. Defaults to user (the caller's own operations); tenant lists the caller's tenant; system lists system operations.
        scopeId:
          type: string
          description: Filter to operations with this exact scope id (e.g. a system sub-scope, or a specific tenant/user id when widening the scope is permitted).
        operationType:
          type: string
          description: Filter to operations of this type.
        correlationId:
          type: string
          format: uuid
          description: Filter to operations in this correlation group (deployment).
        resourceId:
          type: string
          description: Filter to operations acting on this target resource id.
        status:
          $ref: '#/components/schemas/OperationStatus'
          description: Filter to operations in this status.
        order:
          $ref: '#/components/schemas/ListOperationsQueryOrder'
      required:
        - skip
        - limit
    GetSiteDashboardTemplateQuery:
      type: object
      description: Get a single dashboard template by id.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
      required:
        - templateId
    SiteId:
      type: string
      description: Globally unique site identifier, used as a DNS label in URLs such as `{siteId}.{region}.cozify.io` — letters (any case), digits, and interior hyphens (no leading or trailing hyphen). Case-insensitive (the casing you send is preserved, but identity folds case).
      minLength: 3
      maxLength: 63
      pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$
    GetSiteEgressStatusQuery:
      type: object
      description: Retrieve status for a configured site egress target.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        targetId:
          type: string
          description: Identifier of the site egress target.
          minLength: 3
      required:
        - siteId
        - targetId
    GetSiteEgressTargetQuery:
      type: object
      description: Get a site egress target.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        targetId:
          type: string
      required:
        - siteId
        - targetId
    SiteEntityPath:
      type: string
      description: Canonical Site entity path. Paths must start with `/`, contain type/name segment pairs, and use lowercase letters, numbers, and hyphens only.
      maxLength: 1024
      pattern: ^/(?:[a-z0-9-]{1,64}/[a-z0-9-]{1,64})(?:/[a-z0-9-]{1,64}/[a-z0-9-]{1,64})*$
      example: /building/1/floor/2/room/kitchen
    GetSiteEntityDeviceQuery:
      type: object
      description: Read the device behind a site entity, addressed by its site path. The site entity hides the underlying device (its register and id); this resolves that link on the site plane and returns the device's register entry, so callers can read the device's details through the site's virtual view without addressing the device register directly. The result carries an error (E_NOT_FOUND) when the entity is not a device, the site has no device register, or the linked device no longer exists in the register (a stale link).
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        path:
          $ref: '#/components/schemas/SiteEntityPath'
      required:
        - siteId
        - path
    GetSiteEntityDeviceStateQuery:
      type: object
      description: Read the current reported state of the device behind a site entity, addressed by its site path. The site entity hides the underlying device (its register and id); this returns that device's state, so callers can read it through the site's virtual view without knowing the device's identity.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        path:
          $ref: '#/components/schemas/SiteEntityPath'
      required:
        - siteId
        - path
    GetSiteEntityQuery:
      type: object
      description: Get a single site entity by path.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        path:
          $ref: '#/components/schemas/SiteEntityPath'
      required:
        - siteId
        - path
    GetSitePropertiesQuery:
      type: object
      description: Retrieve site properties.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
      required:
        - siteId
    GetSiteQuery:
      type: object
      description: Retrieve site metadata.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
      required:
        - siteId
    GetSiteSchemaQuery:
      type: object
      description: Retrieve site definition/schema.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
      required:
        - siteId
    GetSiteSchemaTemplateQuery:
      type: object
      description: Get a single schema template by id.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
      required:
        - templateId
    ListSiteDashboardTemplatesQuery:
      type: object
      description: List the dashboard templates for the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
      required:
        - skip
        - limit
    ListSiteEgressStatusesQuery:
      type: object
      description: Retrieve statuses for all configured site egress targets.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        siteId:
          $ref: '#/components/schemas/SiteId'
      required:
        - siteId
        - skip
        - limit
    ListSiteEgressTargetsQuery:
      type: object
      description: List site egress targets.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        siteId:
          $ref: '#/components/schemas/SiteId'
      required:
        - siteId
        - skip
        - limit
    SiteEntityPathGlobPattern:
      type: string
      description: Site entity path glob pattern. Supports exact paths, `*`, `+`, `++`, `?`, character classes (`[...]`), and alternatives (`{a,b}`) over lowercase Site entity paths.
      maxLength: 1024
      pattern: ^[a-z0-9\-/*+?{},\[\]^]{1,1024}$
      examples:
        - '*'
        - /building/+/floor/+
        - /++/room/+
        - /building/{1,2}/++
    ListSiteEntitiesQuery:
      type: object
      description: List site entities matching a glob pattern.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        globPattern:
          $ref: '#/components/schemas/SiteEntityPathGlobPattern'
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
      required:
        - siteId
        - globPattern
        - skip
        - limit
    ListSiteSchemaTemplatesQuery:
      type: object
      description: List the schema templates for the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
      required:
        - skip
        - limit
    ListSpotPricesQuery:
      type: object
      description: Retrieve validated spot prices for a market area over a time range.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        area:
          type: string
          description: ENTSO-E market area code (e.g. FI, SE1, DE).
          pattern: ^([A-Z0-9]+)$
          maxLength: 16
          example: FI
        start:
          type: string
          format: date-time
          description: Inclusive start of the time range (UTC).
        stop:
          type: string
          format: date-time
          description: End of the time range (UTC). Must be after start and no more than 7 days from it.
      required:
        - area
        - start
        - stop
    SubscriptionId:
      type: string
      description: The identifier of the subscription.
      format: uuid
      example: dd8993e6-d956-4957-aba5-5e3cdb0b4498
    ResourceProvider:
      type: string
      description: 'The provider that backs the resource. Supported values: `Cozify.Sites` and `Cozify.DeviceRegister` (with `Cozify.Site` accepted as an alias for `Cozify.Sites` on input). Clients should present these as a fixed choice rather than free text.'
      example: Cozify.Sites
    CheckResourceNameValidityQuery:
      type: object
      description: Check whether a proposed resource name is valid and available before creating it. Validates the name format (generic and provider-specific) and that the name is not already taken, so the create dialog can give immediate feedback instead of waiting for the create command to fail.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group the resource would be created in.
        resourceProvider:
          $ref: '#/components/schemas/ResourceProvider'
        resourceName:
          type: string
          description: The proposed resource name to validate.
      required:
        - subscriptionId
        - resourceGroup
        - resourceProvider
        - resourceName
    GetResourceGroupQuery:
      type: object
      description: Retrieve a specific resource group from a subscription.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
      required:
        - subscriptionId
        - resourceGroup
    GetResourceQuery:
      type: object
      description: Retrieve a specific resource from a resource group.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        resourceName:
          type: string
          description: Name of the resource.
      required:
        - subscriptionId
        - resourceGroup
        - resourceName
    GetSubscriptionQuery:
      type: object
      description: Retrieve a specific subscription.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
      required:
        - subscriptionId
    ListResourceGroupsQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing resource groups. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the filter type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListResourceGroupsQueryKeywordFilter: '#/components/schemas/ListResourceGroupsQueryKeywordFilter'
          ListResourceGroupsQueryNameFilter: '#/components/schemas/ListResourceGroupsQueryNameFilter'
          ListResourceGroupsQueryLocationFilter: '#/components/schemas/ListResourceGroupsQueryLocationFilter'
      required:
        - type
    ListResourceGroupsQueryKeywordFilter:
      type: object
      description: Searches resource groups by a keyword matched (case-insensitive substring) against the name and location.
      allOf:
        - $ref: '#/components/schemas/ListResourceGroupsQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          $ref: '#/components/schemas/QueryKeyword'
      required:
        - keyword
    ListResourceGroupsQueryNameFilter:
      type: object
      description: Filters resource groups whose name starts with the given value (case-insensitive).
      allOf:
        - $ref: '#/components/schemas/ListResourceGroupsQueryFilter'
      additionalProperties: false
      properties:
        name:
          type: string
          description: Name of the resource group.
      required:
        - name
    ResourceLocation:
      type: string
      description: Geographic location of the resource — one of the owning tenant's available locations (see `TenantEntry.locations`, retrievable via `GetTenantByIdQuery`). Clients should present these as a fixed choice (e.g. a dropdown) rather than free text.
    ListResourceGroupsQueryLocationFilter:
      type: object
      description: Filters resource groups by location.
      allOf:
        - $ref: '#/components/schemas/ListResourceGroupsQueryFilter'
      additionalProperties: false
      properties:
        location:
          $ref: '#/components/schemas/ResourceLocation'
      required:
        - location
    QueryOrderDescending:
      type: boolean
      description: Whether the results are ordered in descending order.
      default: false
    ListResourceGroupsQueryOrder:
      type: object
      description: Ordering options applied when listing resource groups.
      additionalProperties: false
      properties:
        field:
          type: string
          description: Field to order the results by.
          enum:
            - name
            - location
            - createdAt
            - modifiedAt
            - createdBy
            - modifiedBy
          default: name
        descending:
          $ref: '#/components/schemas/QueryOrderDescending'
      required:
        - field
    ListResourceGroupsQuery:
      type: object
      description: Retrieve a list of resource groups for a subscription.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListResourceGroupsQueryFilter'
        order:
          $ref: '#/components/schemas/ListResourceGroupsQueryOrder'
      required:
        - subscriptionId
        - skip
        - limit
    ListResourcesQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing resources. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the filter type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListResourcesQueryKeywordFilter: '#/components/schemas/ListResourcesQueryKeywordFilter'
          ListResourcesQueryNameFilter: '#/components/schemas/ListResourcesQueryNameFilter'
          ListResourcesQueryDisplayNameFilter: '#/components/schemas/ListResourcesQueryDisplayNameFilter'
          ListResourcesQueryResourceProviderFilter: '#/components/schemas/ListResourcesQueryResourceProviderFilter'
      required:
        - type
    ListResourcesQueryKeywordFilter:
      type: object
      description: Searches resources by a keyword matched (case-insensitive substring) against the name, display name and location.
      allOf:
        - $ref: '#/components/schemas/ListResourcesQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          $ref: '#/components/schemas/QueryKeyword'
      required:
        - keyword
    ListResourcesQueryNameFilter:
      type: object
      description: Filters resources whose name starts with the given value (case-insensitive).
      allOf:
        - $ref: '#/components/schemas/ListResourcesQueryFilter'
      additionalProperties: false
      properties:
        name:
          type: string
          description: Name of the resource.
      required:
        - name
    DisplayName:
      type: string
      description: Human-readable identifier intended to provide a clear and concise name.
      minLength: 1
      maxLength: 64
      pattern: ^([a-zA-Z0-9_.,\-'()&/:+#@!?\s\u0080-\uFFFF]+)$
      example: Brown Fox
    ListResourcesQueryDisplayNameFilter:
      type: object
      description: Filters resources by display name.
      allOf:
        - $ref: '#/components/schemas/ListResourcesQueryFilter'
      additionalProperties: false
      properties:
        displayName:
          $ref: '#/components/schemas/DisplayName'
      required:
        - displayName
    ListResourcesQueryResourceProviderFilter:
      type: object
      description: Filters resources by resource provider.
      allOf:
        - $ref: '#/components/schemas/ListResourcesQueryFilter'
      additionalProperties: false
      properties:
        resourceProvider:
          $ref: '#/components/schemas/ResourceProvider'
      required:
        - resourceProvider
    ListResourcesQueryOrder:
      type: object
      description: Ordering options applied when listing resources.
      additionalProperties: false
      properties:
        field:
          type: string
          description: Field to order the results by.
          enum:
            - name
            - displayName
            - resourceProvider
            - createdAt
            - modifiedAt
            - createdBy
            - modifiedBy
          default: name
        descending:
          $ref: '#/components/schemas/QueryOrderDescending'
      required:
        - field
    ListResourcesQuery:
      type: object
      description: Retrieve a list of resources for a subscription.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListResourcesQueryFilter'
        order:
          $ref: '#/components/schemas/ListResourcesQueryOrder'
      required:
        - subscriptionId
        - resourceGroup
        - skip
        - limit
    ListSubscriptionsQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing subscriptions. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the filter type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListSubscriptionsQueryKeywordFilter: '#/components/schemas/ListSubscriptionsQueryKeywordFilter'
          ListSubscriptionsQueryDisplayNameFilter: '#/components/schemas/ListSubscriptionsQueryDisplayNameFilter'
      required:
        - type
    ListSubscriptionsQueryKeywordFilter:
      type: object
      description: Searches subscriptions by a keyword matched against the display name and subscription id.
      allOf:
        - $ref: '#/components/schemas/ListSubscriptionsQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          $ref: '#/components/schemas/QueryKeyword'
      required:
        - keyword
    ListSubscriptionsQueryDisplayNameFilter:
      type: object
      description: Filters subscriptions whose display name starts with the given value (case-insensitive).
      allOf:
        - $ref: '#/components/schemas/ListSubscriptionsQueryFilter'
      additionalProperties: false
      properties:
        displayName:
          $ref: '#/components/schemas/DisplayName'
      required:
        - displayName
    ListSubscriptionsQueryOrder:
      type: object
      description: Ordering options applied when listing subscriptions.
      additionalProperties: false
      properties:
        field:
          type: string
          description: Field to order the results by.
          enum:
            - subscriptionId
            - displayName
            - createdAt
            - modifiedAt
            - createdBy
            - modifiedBy
          default: subscriptionId
        descending:
          $ref: '#/components/schemas/QueryOrderDescending'
      required:
        - field
    ListSubscriptionsQuery:
      type: object
      description: Retrieve a list of subscriptions.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListSubscriptionsQueryFilter'
        order:
          $ref: '#/components/schemas/ListSubscriptionsQueryOrder'
      required:
        - skip
        - limit
    GetCurrentTenantQuery:
      type: object
      description: Query to retrieve the current tenant.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
    TenantId:
      type: string
      description: The identifier of the tenant.
      format: uuid
      example: dd8993e6-d956-4957-aba5-5e3cdb0b4498
    ListTenantsQueryFilter:
      type: object
      x-abstract: true
      description: Base type for filters used when listing tenants. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the filter type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          ListTenantsQueryKeywordFilter: '#/components/schemas/ListTenantsQueryKeywordFilter'
          ListTenantsQueryTenantIdFilter: '#/components/schemas/ListTenantsQueryTenantIdFilter'
          ListTenantsQueryDisplayNameFilter: '#/components/schemas/ListTenantsQueryDisplayNameFilter'
      required:
        - type
    ListTenantsQueryKeywordFilter:
      type: object
      description: Searches tenants by a keyword matched against the display name.
      allOf:
        - $ref: '#/components/schemas/ListTenantsQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          $ref: '#/components/schemas/QueryKeyword'
      required:
        - keyword
    ListTenantsQueryTenantIdFilter:
      type: object
      description: Filters tenants by tenant id.
      allOf:
        - $ref: '#/components/schemas/ListTenantsQueryFilter'
      additionalProperties: false
      properties:
        tenantId:
          $ref: '#/components/schemas/TenantId'
      required:
        - tenantId
    ListTenantsQueryDisplayNameFilter:
      type: object
      description: Filters tenants by display name.
      allOf:
        - $ref: '#/components/schemas/ListTenantsQueryFilter'
      additionalProperties: false
      properties:
        displayName:
          $ref: '#/components/schemas/DisplayName'
      required:
        - displayName
    ListTenantsQueryOrder:
      type: object
      description: Ordering options applied when listing tenants.
      additionalProperties: false
      properties:
        field:
          type: string
          description: Field to order the results by.
          enum:
            - tenantId
            - displayName
            - createdAt
            - modifiedAt
            - createdBy
            - modifiedBy
          default: tenantId
        descending:
          $ref: '#/components/schemas/QueryOrderDescending'
      required:
        - field
    ListTenantsQuery:
      type: object
      description: Retrieve a list of tenants in the system.
      allOf:
        - $ref: '#/components/schemas/Query'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListTenantsQueryFilter'
        order:
          $ref: '#/components/schemas/ListTenantsQueryOrder'
      required:
        - skip
        - limit
    CorrelationId:
      type: string
      description: Client-chosen opaque identifier for an operation. Supplied on the request and echoed back on the response, and attached to server logs and traces so the caller can correlate their request with server-side activity.
      minLength: 1
      maxLength: 128
    Traceparent:
      type: string
      description: W3C Trace Context traceparent ("00-<trace-id>-<span-id>-<trace-flags>"). On a request it continues the caller's distributed trace on the server, carried in the body so it also works on transports without headers (SignalR); over HTTP the traceparent header takes precedence. On a response it is the server-side trace of the operation, for support and log/trace lookup.
      pattern: ^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$
    QueryRequest:
      type: object
      description: Request object for query.
      additionalProperties: false
      properties:
        query:
          $ref: '#/components/schemas/Query'
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        traceparent:
          $ref: '#/components/schemas/Traceparent'
      required:
        - query
    QueryResult:
      type: object
      x-abstract: true
      description: Base type for query results. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          GetDefaultDeviceConfigurationTemplateQueryResult: '#/components/schemas/GetDefaultDeviceConfigurationTemplateQueryResult'
          GetDeviceConfigurationQueryResult: '#/components/schemas/GetDeviceConfigurationQueryResult'
          GetDeviceConfigurationTemplateQueryResult: '#/components/schemas/GetDeviceConfigurationTemplateQueryResult'
          GetDeviceDefinitionTemplateQueryResult: '#/components/schemas/GetDeviceDefinitionTemplateQueryResult'
          GetDeviceRegisterEntryColumnsQueryResult: '#/components/schemas/GetDeviceRegisterEntryColumnsQueryResult'
          GetDeviceRegisterEntryQueryResult: '#/components/schemas/GetDeviceRegisterEntryQueryResult'
          GetDeviceRegisterQueryResult: '#/components/schemas/GetDeviceRegisterQueryResult'
          GetDeviceStateQueryResult: '#/components/schemas/GetDeviceStateQueryResult'
          ListDeviceConfigurationStatusesQueryResult: '#/components/schemas/ListDeviceConfigurationStatusesQueryResult'
          ListDeviceConfigurationTemplatesQueryResult: '#/components/schemas/ListDeviceConfigurationTemplatesQueryResult'
          ListDeviceDefinitionTemplatesQueryResult: '#/components/schemas/ListDeviceDefinitionTemplatesQueryResult'
          ListDeviceRegisterEntriesQueryResult: '#/components/schemas/ListDeviceRegisterEntriesQueryResult'
          ListHubUserAssignmentsQueryResult: '#/components/schemas/ListHubUserAssignmentsQueryResult'
          GetDeviceRegisterKeyVaultQueryResult: '#/components/schemas/GetDeviceRegisterKeyVaultQueryResult'
          GetTenantKeyVaultQueryResult: '#/components/schemas/GetTenantKeyVaultQueryResult'
          ListDeviceRegisterKeyVaultQueryResult: '#/components/schemas/ListDeviceRegisterKeyVaultQueryResult'
          ListTenantKeyVaultQueryResult: '#/components/schemas/ListTenantKeyVaultQueryResult'
          GetOperationQueryResult: '#/components/schemas/GetOperationQueryResult'
          ListOperationsQueryResult: '#/components/schemas/ListOperationsQueryResult'
          GetSiteDashboardTemplateQueryResult: '#/components/schemas/GetSiteDashboardTemplateQueryResult'
          GetSiteEgressStatusQueryResult: '#/components/schemas/GetSiteEgressStatusQueryResult'
          GetSiteEgressTargetQueryResult: '#/components/schemas/GetSiteEgressTargetQueryResult'
          GetSiteEntityDeviceQueryResult: '#/components/schemas/GetSiteEntityDeviceQueryResult'
          GetSiteEntityDeviceStateQueryResult: '#/components/schemas/GetSiteEntityDeviceStateQueryResult'
          GetSiteEntityQueryResult: '#/components/schemas/GetSiteEntityQueryResult'
          GetSitePropertiesQueryResult: '#/components/schemas/GetSitePropertiesQueryResult'
          GetSiteQueryResult: '#/components/schemas/GetSiteQueryResult'
          GetSiteSchemaQueryResult: '#/components/schemas/GetSiteSchemaQueryResult'
          GetSiteSchemaTemplateQueryResult: '#/components/schemas/GetSiteSchemaTemplateQueryResult'
          ListSiteDashboardTemplatesQueryResult: '#/components/schemas/ListSiteDashboardTemplatesQueryResult'
          ListSiteEgressStatusesQueryResult: '#/components/schemas/ListSiteEgressStatusesQueryResult'
          ListSiteEgressTargetsQueryResult: '#/components/schemas/ListSiteEgressTargetsQueryResult'
          ListSiteEntitiesQueryResult: '#/components/schemas/ListSiteEntitiesQueryResult'
          ListSiteSchemaTemplatesQueryResult: '#/components/schemas/ListSiteSchemaTemplatesQueryResult'
          ListSpotPricesQueryResult: '#/components/schemas/ListSpotPricesQueryResult'
          CheckResourceNameValidityQueryResult: '#/components/schemas/CheckResourceNameValidityQueryResult'
          GetResourceGroupQueryResult: '#/components/schemas/GetResourceGroupQueryResult'
          GetResourceQueryResult: '#/components/schemas/GetResourceQueryResult'
          GetSubscriptionQueryResult: '#/components/schemas/GetSubscriptionQueryResult'
          ListResourceGroupsQueryResult: '#/components/schemas/ListResourceGroupsQueryResult'
          ListResourcesQueryResult: '#/components/schemas/ListResourcesQueryResult'
          ListSubscriptionsQueryResult: '#/components/schemas/ListSubscriptionsQueryResult'
          GetCurrentTenantQueryResult: '#/components/schemas/GetCurrentTenantQueryResult'
          ListTenantsQueryResult: '#/components/schemas/ListTenantsQueryResult'
      required:
        - type
    RawTemplateContentJson:
      type: string
      description: Raw JSON template content.
    TemplateContentRevision:
      type: integer
      format: int32
      description: Server-owned revision, incremented on each content change.
    TemplateIsDefault:
      type: boolean
      description: Whether this template is the default for its collection.
    DeviceConfigurationTemplateEntry:
      type: object
      description: A device configuration template stored for a device type under the register's tenant.
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/RawTemplateContentJson'
        revision:
          $ref: '#/components/schemas/TemplateContentRevision'
        isDefault:
          $ref: '#/components/schemas/TemplateIsDefault'
      required:
        - deviceType
        - templateId
        - displayName
        - contentJson
        - revision
        - isDefault
    GetDefaultDeviceConfigurationTemplateQueryResult:
      type: object
      description: Result of GetDefaultDeviceConfigurationTemplateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceConfigurationTemplateEntry'
    DeviceConfigurationJson:
      type: string
      description: The desired device configuration as a JSON object, serialized to a JSON string.
    DeviceConfigurationStatusEntry:
      type: object
      description: The desired-versus-applied configuration revision state of a device.
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        desiredRevision:
          description: The latest desired configuration revision set for the device.
          type: integer
          format: int32
        appliedRevision:
          description: The configuration revision the device last confirmed as applied.
          type: integer
          format: int32
        appliedAt:
          description: The time the device last confirmed an applied configuration.
          type: string
          format: date-time
        revisedAt:
          description: The time the desired configuration revision was last set.
          type: string
          format: date-time
        hasConfiguration:
          description: Whether a desired configuration has been set for the device.
          type: boolean
        inSync:
          description: Whether the device has applied the latest desired configuration.
          type: boolean
      required:
        - deviceId
        - desiredRevision
        - appliedRevision
        - hasConfiguration
        - inSync
    GetDeviceConfigurationQueryResult:
      type: object
      description: Result of the GetDeviceConfigurationQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        configurationJson:
          $ref: '#/components/schemas/DeviceConfigurationJson'
        status:
          $ref: '#/components/schemas/DeviceConfigurationStatusEntry'
    GetDeviceConfigurationTemplateQueryResult:
      type: object
      description: Result of GetDeviceConfigurationTemplateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceConfigurationTemplateEntry'
    DeviceDefinitionTemplateEntry:
      type: object
      description: A device definition template stored for a device type under the register's tenant.
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/RawTemplateContentJson'
        revision:
          $ref: '#/components/schemas/TemplateContentRevision'
        isDefault:
          $ref: '#/components/schemas/TemplateIsDefault'
      required:
        - deviceType
        - templateId
        - displayName
        - contentJson
        - revision
        - isDefault
    GetDeviceDefinitionTemplateQueryResult:
      type: object
      description: Result of GetDeviceDefinitionTemplateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceDefinitionTemplateEntry'
    GetDeviceRegisterEntryColumnsQueryResult:
      type: object
      description: Result of the GetDeviceRegisterEntryColumnsQuery; each array is present only when its flag was set.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        deviceType:
          description: Known device types, when requested.
          type: array
          items:
            $ref: '#/components/schemas/DeviceType'
        capabilities:
          description: Known device capabilities, when requested.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        manufacturer:
          description: Known device manufacturers, when requested.
          type: array
          items:
            $ref: '#/components/schemas/DeviceManufacturer'
        model:
          description: Known device models, when requested.
          type: array
          items:
            $ref: '#/components/schemas/DeviceModel'
    ScopePath:
      type: string
      description: Hierarchical, ARM-style resource path identifying a node in the resource hierarchy. Always starts with "/" and is made of "/"-separated, URL-friendly segments. It is commonly "/<type>/<name>" pairs (e.g. "/site/{siteId}"), but provider-style paths may carry additional segments (e.g. "/subscriptions/{id}/resourceGroups/{name}/providers/{provider}/{name}"). The root scope is "/".
      pattern: ^/([A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*)?$
    CreatedAt:
      type: string
      description: Date and time when the resource was created.
      format: date-time
    ModifiedAt:
      type: string
      description: Date and time when the resource was last modified.
      format: date-time
    DeviceName:
      type: string
      description: The human readable name of the device.
      maxLength: 50
      pattern: ^([a-zA-Z0-9_.,\-'()&/:+#@!?\s\u0080-\uFFFF]+)$
      example: SuPa cool IoT gadget
    Tags:
      type: object
      description: |
        Tags are name/value pairs for categorising resources — apply the same tag across resources to
        group and filter them. Names are case-insensitive; values are case-sensitive.
      additionalProperties:
        type: string
        minLength: 1
        maxLength: 100
      propertyNames:
        type: string
        minLength: 1
        maxLength: 100
    DeviceGateway:
      type: boolean
      description: Defines if the device is a acting as an gateway device to other devices.
      default: false
    DeviceRegisterRoutingEntry:
      type: object
      x-abstract: true
      description: Base type for a device register routing entry (how a registered device is reached). Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          DeviceRegisterHubRoutingEntry: '#/components/schemas/DeviceRegisterHubRoutingEntry'
          DeviceRegisterDeviceRoutingEntry: '#/components/schemas/DeviceRegisterDeviceRoutingEntry'
      required:
        - type
    DeviceRegisterHubRoutingEntry:
      type: object
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
      required:
        - hubId
    DeviceRegisterDeviceRoutingEntry:
      type: object
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceId
    DeviceState:
      type: object
      additionalProperties:
        type: string
    DeviceRegisterDeviceEntry:
      type: object
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ScopePath'
          description: Unique resource id of the device, as a hierarchical scope path ("/deviceregister/{deviceRegisterId}/device/{deviceId}"). Role assignments target this path (or an ancestor) to grant access to the device.
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        name:
          $ref: '#/components/schemas/DeviceName'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        gateway:
          $ref: '#/components/schemas/DeviceGateway'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
        state:
          $ref: '#/components/schemas/DeviceState'
      required:
        - id
        - deviceId
        - deviceType
        - name
        - capabilities
        - tags
        - gateway
        - state
    GetDeviceRegisterEntryQueryResult:
      type: object
      description: Result of the GetDeviceRegisterEntryQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    CreatedBy:
      type: string
      description: Identifier of the creator of the resource.
      maxLength: 50
      example: Jacob Brave
    ModifiedBy:
      type: string
      description: Identifier that last modified the resource.
      maxLength: 50
      example: Jacob Braver
    DeviceRegisterMetadataEntry:
      type: object
      description: Device register metadata.
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ScopePath'
          description: Unique resource id of the device register, as a hierarchical scope path ("/deviceregister/{deviceRegisterId}"). Role assignments target this path (or an ancestor) to grant access to the register and its devices.
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group the device register belongs to.
        location:
          $ref: '#/components/schemas/ResourceLocation'
        tags:
          $ref: '#/components/schemas/Tags'
        createdBy:
          $ref: '#/components/schemas/CreatedBy'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedBy:
          $ref: '#/components/schemas/ModifiedBy'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
      required:
        - id
        - deviceRegisterId
        - displayName
        - subscriptionId
        - resourceGroup
        - location
        - createdBy
        - createdAt
        - modifiedBy
        - modifiedAt
    GetDeviceRegisterQueryResult:
      type: object
      description: Result for retrieving a device register's metadata.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterMetadataEntry'
    DeviceStateJson:
      type: string
      description: The device's current reported state as a JSON object of name/value pairs, serialized to a JSON string.
    GetDeviceStateQueryResult:
      type: object
      description: Result of the GetDeviceStateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        stateJson:
          $ref: '#/components/schemas/DeviceStateJson'
    QueryTotalCount:
      type: integer
      description: Provides the total number of items available in query result.
      format: int64
      minimum: 0
      default: 0
      example: 2000
    ListDeviceConfigurationStatusesQueryResult:
      type: object
      description: Result of the ListDeviceConfigurationStatusesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          description: The configuration revision state of each device in the register.
          type: array
          items:
            $ref: '#/components/schemas/DeviceConfigurationStatusEntry'
    ListDeviceConfigurationTemplatesQueryResult:
      type: object
      description: Result of ListDeviceConfigurationTemplatesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: The device configuration templates, each tagged with its device type.
          items:
            $ref: '#/components/schemas/DeviceConfigurationTemplateEntry'
    ListDeviceDefinitionTemplatesQueryResult:
      type: object
      description: Result of ListDeviceDefinitionTemplatesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: The device definition templates, each tagged with its device type.
          items:
            $ref: '#/components/schemas/DeviceDefinitionTemplateEntry'
    ListDeviceRegisterEntriesQueryResult:
      type: object
      description: Result of the ListDeviceRegisterEntriesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          description: The device entries matching the query criteria.
          type: array
          items:
            $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    HubIdProperty:
      type: string
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: The identifier of the Cozify Hub.
      format: uuid
      example: 3ee5d62c-fa38-42a0-a5ac-0c4b315d75fb
    HubMetadata:
      type: object
      description: Hub metadata information.
      additionalProperties: false
      properties:
        connected:
          description: Whether the Hub is connected to the Cozify services.
          type: boolean
          example: true
        features:
          description: List of features enabled on Hub.
          type: array
          items:
            type: integer
          example:
            - 3
            - 6
            - 8
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
        name:
          description: User given name of the Hub.
          type: string
          example: Hub 1234
        state:
          description: |-
            State of the Hub.
             * **factory_new**: Factory new hub, no owner.
             * **claimed**: Claimed by a user, has an owner.
          type: string
          enum:
            - factory_new
            - claimed
          example: claimed
        version:
          description: Version of the software.
          type: string
          example: '1.14'
      required:
        - version
        - state
        - hubId
        - features
        - connected
    HubUserRole:
      type: string
      description: |-
        Defines the role of a user in the Cozify Hub. Each role has different levels
        of access and privileges:
          * **Anonymous**: Minimal access, typically for unauthenticated users. Limited to basic, non-personalized interactions.
          * **Guest**: Basic access to view certain resources without making changes. Suitable for temporary or limited access.
          * **RemoteGuest**: Similar to Guest, but specifically for remote access. Intended for users needing to view resources from a remote location.
          * **User**: Standard access with abilities to perform common tasks and operations. This is the default role for most authenticated users.
          * **Admin**: Elevated privileges including management and configuration capabilities. Admins can alter settings and manage other users.
          * **Owner**: Highest level of access, with full control over all settings and operations within the Cozify Hub. The Owner role typically has all permissions.
      enum:
        - Anonymous
        - Guest
        - RemoteGuest
        - User
        - Admin
        - Owner
    HubUserAssignment:
      type: object
      description: Defines the assignment of a user to a Cozify Hub.
      additionalProperties: false
      properties:
        userId:
          description: The identifier of the user.
          type: string
          format: uuid
        email:
          description: The email address of the user.
          type: string
          format: email
        role:
          $ref: '#/components/schemas/HubUserRole'
      required:
        - userId
        - email
        - role
    ListHubUserAssignmentsQueryResult:
      type: object
      description: Result of listing hub user assignments.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of hub user assignments matching the query criteria.
          items:
            $ref: '#/components/schemas/HubUserAssignment'
    KeyNotBefore:
      type: string
      format: date-time
      description: The time before which the primary key is not valid. If not specified, the key becomes valid immediately.
    KeyVaultEntry:
      type: object
      description: Represents a key vault entry, containing the key identifier and associated secrets.
      additionalProperties: false
      properties:
        keyId:
          $ref: '#/components/schemas/KeyId'
        primary:
          type: string
          description: Primary secret.
        secondary:
          type: string
          description: Secondary secret accepted during key rotation.
        displayName:
          $ref: '#/components/schemas/DisplayName'
        tags:
          $ref: '#/components/schemas/Tags'
        notBefore:
          $ref: '#/components/schemas/KeyNotBefore'
      required:
        - keyId
        - primary
        - notBefore
    GetDeviceRegisterKeyVaultQueryResult:
      type: object
      description: Result of querying a device register key vault entry, containing the key identifier and associated secrets.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        entry:
          $ref: '#/components/schemas/KeyVaultEntry'
    GetTenantKeyVaultQueryResult:
      type: object
      description: Result of querying a tenant key vault entry, containing the key identifier and associated secrets.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/KeyVaultEntry'
    ListDeviceRegisterKeyVaultQueryResult:
      type: object
      description: Result of querying a list of device register key vault entries.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of key vault entries matching the query criteria.
          items:
            $ref: '#/components/schemas/KeyVaultEntry'
    ListTenantKeyVaultQueryResult:
      type: object
      description: Result of querying a list of tenant key vault entries.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of key vault entries matching the query criteria.
          items:
            $ref: '#/components/schemas/KeyVaultEntry'
    OperationEntry:
      type: object
      x-abstract: true
      description: A long-running service operation (task) and its current status. Polymorphic by operation type - each type carries its own properties and result. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          type: string
          description: Discriminator identifying the operation type (which service action it represents).
          example: RefreshCurrencyExchangeOperationEntry
        operationId:
          type: string
          format: uuid
          description: Server-assigned unique id of the operation.
        status:
          $ref: '#/components/schemas/OperationStatus'
        startedBy:
          type: string
          description: Identifier of the user who started the operation.
        scope:
          $ref: '#/components/schemas/OperationScope'
        scopeId:
          type: string
          description: Scope id interpreted per scope - a tenant id (tenant), a user id (user), or an optional system sub-scope such as a region/control path (system); absent when unqualified.
        correlationId:
          type: string
          format: uuid
          description: Groups related operations into one logical action (a deployment). Operations sharing a correlationId belong together; absent for operations created before correlation was recorded.
        targetResourceId:
          type: string
          description: Full ARM-style resource id path the operation acts on, if any.
        createdAt:
          type: string
          format: date-time
          description: When the operation was created.
        startedAt:
          type: string
          format: date-time
          description: When the operation started running, if it has.
        completedAt:
          type: string
          format: date-time
          description: When the operation reached a terminal status, if it has.
        progressPercent:
          type: number
          format: double
          description: Best-effort completion percentage (0-100). Absent (null) means progress is indeterminate - the operation is making intermediate progress that cannot be expressed as a percentage.
        result:
          $ref: '#/components/schemas/OperationResult'
          description: The operation's outcome once terminal - the error on failure, or type-specific data on success; absent while pending or running.
        steps:
          type: array
          description: Ordered step-level detail of the operation's progress.
          items:
            $ref: '#/components/schemas/OperationStepEntry'
      discriminator:
        propertyName: type
        mapping:
          RouteDeviceRegisterOperationEntry: '#/components/schemas/RouteDeviceRegisterOperationEntry'
      required:
        - operationId
        - type
        - status
        - startedBy
        - scope
        - createdAt
        - steps
    RouteDeviceRegisterOperationEntry:
      type: object
      description: A device register routing operation and its current status. Carries no type-specific properties beyond the base operation entry.
      allOf:
        - $ref: '#/components/schemas/OperationEntry'
      additionalProperties: false
    OperationResult:
      type: object
      x-abstract: true
      description: Base type for a long-running operation's outcome - carries the error on failure and, per operation type, the success payload. Polymorphic by operation type. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the operation result type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          RouteDeviceRegisterOperationResult: '#/components/schemas/RouteDeviceRegisterOperationResult'
      required:
        - type
    RouteDeviceRegisterOperationResult:
      type: object
      description: Result of a device register routing operation - the resulting link, absent when the device was unrouted.
      allOf:
        - $ref: '#/components/schemas/OperationResult'
      additionalProperties: false
      properties:
        routing:
          $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
    GraphCode:
      type: string
      description: |-
        Result code for a command or query (see `GraphError`). All values denote an error
        except `E_DEPRECATED`, which is a non-fatal advisory.
        * **E_UNKNOWN**: An unexpected error with no more specific code.
        * **E_NOT_FOUND**: The requested resource does not exist.
        * **E_SERVICE_ERROR**: A service or subsystem failed while processing the request.
        * **E_INVALID_DATA**: A field value is missing or malformed (wrong type, format, or range).
        * **E_UNPROCESSABLE_CONTENT**: The input is well-formed but failed validation or a business rule.
        * **E_ACCESS_DENIED**: The caller is authenticated but not permitted to perform this operation.
        * **E_NOT_SUPPORTED**: The operation is not supported for this resource or in its current state.
        * **E_CONFLICT**: The operation conflicts with the current state of the resource.
        * **E_OPERATION_CANCELLED**: The operation was cancelled before it completed.
        * **E_TIMEOUT**: The operation did not complete within its time limit.
        * **E_NO_CONNECTION**: A required dependency could not be reached.
        * **E_TOO_MANY_REQUESTS**: The caller has been rate limited for sending too many requests.
        * **E_RESOURCE_LIMIT_REACHED**: A resource limit or quota has been reached.
        * **E_BAD_REQUEST**: The request envelope was malformed or used an unsupported transport.
        * **E_ALREADY_EXISTS**: A resource with the same identity already exists.
        * **E_PRECONDITION_FAILED**: An expected precondition did not hold, such as a version or revision mismatch from a concurrent change.
        * **E_DEPENDENCY_FAILED**: A downstream dependency returned an error while handling the request.
        * **E_NOT_AVAILABLE**: The resource or feature is currently unavailable or disabled.
        * **E_INTERNAL_SERVER_ERROR**: An unexpected internal fault prevented the request from completing.
        * **E_DEPRECATED**: Non-fatal - the request used a deprecated command, query, or field and should be migrated.
        * **E_SESSION_EXPIRED**: The session or its authentication has expired; re-authenticate and retry.
        * **E_INVALID_TOKEN**: The authentication token is missing, malformed, or has been revoked.
        * **E_NO_HUB_LINKED**: The resource exists but is not linked to a hub, so a hub-scoped operation cannot be routed.
        * **E_NO_PARENT_LINKED**: The resource exists but is not linked to a parent, so a parent-scoped operation cannot be routed.
        * **E_NO_DEVICE_LINKED**: The resource exists but is not linked to a device, so a device-scoped operation cannot be routed.
      enum:
        - E_UNKNOWN
        - E_NOT_FOUND
        - E_SERVICE_ERROR
        - E_INVALID_DATA
        - E_UNPROCESSABLE_CONTENT
        - E_ACCESS_DENIED
        - E_NOT_SUPPORTED
        - E_CONFLICT
        - E_OPERATION_CANCELLED
        - E_TIMEOUT
        - E_NO_CONNECTION
        - E_TOO_MANY_REQUESTS
        - E_RESOURCE_LIMIT_REACHED
        - E_BAD_REQUEST
        - E_ALREADY_EXISTS
        - E_PRECONDITION_FAILED
        - E_DEPENDENCY_FAILED
        - E_NOT_AVAILABLE
        - E_INTERNAL_SERVER_ERROR
        - E_DEPRECATED
        - E_SESSION_EXPIRED
        - E_INVALID_TOKEN
        - E_NO_HUB_LINKED
        - E_NO_PARENT_LINKED
        - E_NO_DEVICE_LINKED
    GraphError:
      type: object
      description: Error object for the results of commands and queries.
      additionalProperties: false
      properties:
        code:
          $ref: '#/components/schemas/GraphCode'
        message:
          description: A human-readable message describing the error.
          type: string
          minLength: 1
        details:
          description: Additional details about the error.
          type: object
          additionalProperties:
            type: string
        errors:
          description: Nested errors if request contained multiple operations or validation errors.
          type: array
          items:
            $ref: '#/components/schemas/GraphError'
      required:
        - code
    OperationStepEntry:
      type: object
      description: A single step within an operation's execution.
      additionalProperties: false
      properties:
        name:
          type: string
          description: Name of the step.
        status:
          type: string
          description: Status of the step.
        startedAt:
          type: string
          format: date-time
          description: When the step started.
        completedAt:
          type: string
          format: date-time
          description: When the step completed, if it has.
        message:
          type: string
          description: Optional human-readable detail about the step.
      required:
        - name
        - status
        - startedAt
    GetOperationQueryResult:
      type: object
      description: Result containing a single operation's status.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
    ListOperationsQueryResult:
      type: object
      description: Result listing operations.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: The operations.
          items:
            $ref: '#/components/schemas/OperationEntry'
    SiteDashboardTemplateEntry:
      type: object
      description: A dashboard template stored under a site's tenant.
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/RawTemplateContentJson'
        revision:
          $ref: '#/components/schemas/TemplateContentRevision'
        isDefault:
          $ref: '#/components/schemas/TemplateIsDefault'
      required:
        - templateId
        - displayName
        - contentJson
        - revision
        - isDefault
    GetSiteDashboardTemplateQueryResult:
      type: object
      description: Result of GetSiteDashboardTemplateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteDashboardTemplateEntry'
    SiteEgressHealthStatus:
      type: string
      description: Egress health indicator.
      enum:
        - Unknown
        - Working
        - Slow
        - Failing
        - Disabled
        - Late
        - Idle
    SiteEgressLatencyStatsEntry:
      type: object
      description: Latency statistics in milliseconds.
      additionalProperties: false
      properties:
        count:
          type: integer
          format: int64
        minMs:
          type: integer
          format: int64
        maxMs:
          type: integer
          format: int64
        avgMs:
          type: number
          format: double
      required:
        - count
        - minMs
        - maxMs
        - avgMs
    SiteEgressStatusEntry:
      type: object
      description: Latest status for a site egress target.
      additionalProperties: false
      properties:
        targetId:
          type: string
        healthStatus:
          $ref: '#/components/schemas/SiteEgressHealthStatus'
        updatedAt:
          type: integer
          format: int64
        windowStartedAt:
          type: integer
          format: int64
        windowEndedAt:
          type: integer
          format: int64
        batchCount:
          type: integer
          format: int64
        successfulBatchCount:
          type: integer
          format: int64
        failedBatchCount:
          type: integer
          format: int64
        eventCount:
          type: integer
          format: int64
        failedEventCount:
          type: integer
          format: int64
        pipelineLatency:
          $ref: '#/components/schemas/SiteEgressLatencyStatsEntry'
        externalCallLatency:
          $ref: '#/components/schemas/SiteEgressLatencyStatsEntry'
        lastSuccessAt:
          type: integer
          format: int64
        lastFailureAt:
          type: integer
          format: int64
        lastEventAt:
          type: integer
          format: int64
          description: Unix time (ms) of the most recent event batch. Heartbeats do not update it.
        consecutiveFailures:
          type: integer
          format: int64
        lastError:
          type: string
      required:
        - targetId
        - healthStatus
        - updatedAt
        - windowStartedAt
        - windowEndedAt
        - batchCount
        - successfulBatchCount
        - failedBatchCount
        - eventCount
        - failedEventCount
        - pipelineLatency
        - externalCallLatency
        - lastSuccessAt
        - lastFailureAt
        - lastEventAt
        - consecutiveFailures
    GetSiteEgressStatusQueryResult:
      type: object
      description: Result of retrieving site egress status.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEgressStatusEntry'
    SiteEgressTargetEntry:
      type: object
      x-abstract: true
      description: Base type for polymorphic site egress target configuration. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          type: string
          description: Site egress target type discriminator.
        targetId:
          type: string
          minLength: 3
          maxLength: 50
          pattern: ^[a-zA-Z0-9]+$
        isEnabled:
          type: boolean
        fetchMaxEvents:
          type: integer
          format: int32
        fetchWaitMaxMs:
          type: integer
          format: int32
        healthLateAfterMs:
          type: integer
          format: int32
        healthIdleAfterMs:
          type: integer
          format: int32
        backPressureTimeoutMs:
          type: integer
          format: int32
          description: How long to keep retrying delivery of a single batch to this target before giving up (head-of-line back-pressure). Must be at least the target's request timeout; the effective value is raised to at least one full retry cycle. Defaults to 24h when omitted.
          maximum: 86400000
      discriminator:
        propertyName: type
        mapping:
          rest: '#/components/schemas/RestSiteEgressTargetEntry'
      required:
        - type
        - targetId
        - isEnabled
        - fetchMaxEvents
        - fetchWaitMaxMs
    RestSiteEgressTargetEntry:
      type: object
      description: REST site egress target configuration.
      allOf:
        - $ref: '#/components/schemas/SiteEgressTargetEntry'
      additionalProperties: false
      properties:
        url:
          type: string
          format: uri
        method:
          type: string
          enum:
            - POST
            - PUT
        headers:
          type: object
          additionalProperties:
            type: string
        serverScript:
          type: string
        requestTimeoutSeconds:
          type: number
          format: double
      required:
        - url
        - method
    GetSiteEgressTargetQueryResult:
      type: object
      description: Result of getting a site egress target.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEgressTargetEntry'
    GetSiteEntityDeviceQueryResult:
      type: object
      description: Result of the GetSiteEntityDeviceQuery. Carries the linked device's register entry when the site entity's device link is live; the result carries an error instead when the entity is not a device or the linked device no longer exists in its register.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    GetSiteEntityDeviceStateQueryResult:
      type: object
      description: Result of the GetSiteEntityDeviceStateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        stateJson:
          $ref: '#/components/schemas/DeviceStateJson'
    SiteAttributeValueEntry:
      type: object
      x-abstract: true
      description: Base type for polymorphic site attribute values. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          type: string
          description: Attribute value type discriminator.
        name:
          $ref: '#/components/schemas/SiteAttributeName'
      discriminator:
        propertyName: type
        mapping:
          string: '#/components/schemas/StringSiteAttributeValueEntry'
          number: '#/components/schemas/NumberSiteAttributeValueEntry'
          bool: '#/components/schemas/BoolSiteAttributeValueEntry'
          json: '#/components/schemas/JsonSiteAttributeValueEntry'
      required:
        - type
        - name
    StringSiteAttributeValueEntry:
      type: object
      description: String site attribute value.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeValueEntry'
      additionalProperties: false
      properties:
        value:
          type: string
          description: String attribute value.
      required:
        - value
    NumberSiteAttributeValueEntry:
      type: object
      description: Numeric site attribute value.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeValueEntry'
      additionalProperties: false
      properties:
        value:
          type: number
          format: double
          description: Numeric attribute value.
      required:
        - value
    BoolSiteAttributeValueEntry:
      type: object
      description: Boolean site attribute value.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeValueEntry'
      additionalProperties: false
      properties:
        value:
          type: boolean
          description: Boolean attribute value.
      required:
        - value
    JsonSiteAttributeValueEntry:
      type: object
      description: JSON site attribute value.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeValueEntry'
      additionalProperties: false
      properties:
        value:
          type: string
          description: Raw JSON attribute value.
      required:
        - value
    SiteAttributeName:
      type: string
      description: Site attribute name.
    SiteEntityEntry:
      type: object
      description: Site entity metadata.
      additionalProperties: false
      properties:
        path:
          $ref: '#/components/schemas/SiteEntityPath'
        siteEntityId:
          type: string
          format: uuid
        displayName:
          $ref: '#/components/schemas/DisplayName'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
      required:
        - path
        - siteEntityId
        - displayName
        - createdAt
        - modifiedAt
        - attributes
    GetSiteEntityQueryResult:
      type: object
      description: Result of getting a single site entity.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEntityEntry'
    SiteTypeEntry:
      type: object
      x-abstract: true
      description: Base type for polymorphic site kind settings. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: Site kind discriminator.
          $ref: '#/components/schemas/SiteKind'
      discriminator:
        propertyName: type
        mapping:
          unknown: '#/components/schemas/UnknownSiteTypeEntry'
          hub: '#/components/schemas/HubSiteTypeEntry'
          knx: '#/components/schemas/KnxSiteTypeEntry'
      required:
        - type
    UnknownSiteTypeEntry:
      type: object
      description: Site type settings for a site with unknown kind.
      allOf:
        - $ref: '#/components/schemas/SiteTypeEntry'
      additionalProperties: false
    HubSiteTypeEntry:
      type: object
      description: Site type settings for a hub site.
      allOf:
        - $ref: '#/components/schemas/SiteTypeEntry'
      additionalProperties: false
    KnxSiteTypeEntry:
      type: object
      description: Site type settings for a KNX site.
      allOf:
        - $ref: '#/components/schemas/SiteTypeEntry'
      additionalProperties: false
      properties:
        awaySceneSave:
          type: boolean
          description: KNX away scene save setting.
      required:
        - awaySceneSave
    SiteKind:
      type: string
      description: Site kind discriminator. Values use lower-case JSON tokens.
      enum:
        - unknown
        - knx
        - hub
    SiteFeatureEntry:
      type: object
      description: Feature base for a site.
      additionalProperties: false
      properties:
        enabled:
          type: boolean
      required:
        - enabled
    DeviceRegisterSiteFeatureEntry:
      type: object
      description: Device register feature for a site.
      allOf:
        - $ref: '#/components/schemas/SiteFeatureEntry'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        generateDeviceName:
          type: boolean
        generateGatewayChildDevices:
          type: boolean
          description: Whether gateway child devices are generated.
        forceGenerateChildDevicesAtRoot:
          type: boolean
      required:
        - generateDeviceName
        - generateGatewayChildDevices
        - forceGenerateChildDevicesAtRoot
    SiteFeaturesEntry:
      type: object
      description: Site feature settings.
      additionalProperties: false
      properties:
        consumptionHistory:
          $ref: '#/components/schemas/SiteFeatureEntry'
        conditionsHistory:
          $ref: '#/components/schemas/SiteFeatureEntry'
        compareWater:
          $ref: '#/components/schemas/SiteFeatureEntry'
        compareElectricity:
          $ref: '#/components/schemas/SiteFeatureEntry'
        deviceRegister:
          $ref: '#/components/schemas/DeviceRegisterSiteFeatureEntry'
        siteEvents:
          $ref: '#/components/schemas/SiteFeatureEntry'
      required:
        - consumptionHistory
        - conditionsHistory
        - compareWater
        - compareElectricity
        - deviceRegister
        - siteEvents
    SitePropertiesEntry:
      type: object
      description: Site properties.
      additionalProperties: false
      properties:
        siteType:
          $ref: '#/components/schemas/SiteTypeEntry'
        timezone:
          type: string
        features:
          $ref: '#/components/schemas/SiteFeaturesEntry'
      required:
        - siteType
        - timezone
        - features
    GetSitePropertiesQueryResult:
      type: object
      description: Result for retrieving site properties.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SitePropertiesEntry'
    SiteMetadataEntry:
      type: object
      description: Site metadata.
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ScopePath'
          description: Unique resource id of the site, as a hierarchical scope path ("/site/{siteId}"). Role assignments target this path (or an ancestor) to grant access to the site and its sub-resources.
        displayName:
          $ref: '#/components/schemas/DisplayName'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
      required:
        - id
        - displayName
        - createdAt
        - modifiedAt
        - attributes
    GetSiteQueryResult:
      type: object
      description: Result for retrieving site metadata.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteMetadataEntry'
    SiteAttributeSchemaEntry:
      type: object
      x-abstract: true
      description: Base type for a polymorphic site attribute definition. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          type: string
          description: Attribute definition type discriminator.
        name:
          $ref: '#/components/schemas/SiteAttributeName'
        required:
          type: boolean
          description: Whether a value for this attribute is required.
        system:
          type: boolean
          description: Whether the attribute is system-managed.
        defaultValueJson:
          type:
            - string
            - 'null'
          description: Optional raw JSON default value for the attribute; null when no default is set. Independent of `required` — a required attribute may still declare a default.
      discriminator:
        propertyName: type
        mapping:
          StringSiteAttributeSchemaEntry: '#/components/schemas/StringSiteAttributeSchemaEntry'
          NumberSiteAttributeSchemaEntry: '#/components/schemas/NumberSiteAttributeSchemaEntry'
          BooleanSiteAttributeSchemaEntry: '#/components/schemas/BooleanSiteAttributeSchemaEntry'
          JsonSiteAttributeSchemaEntry: '#/components/schemas/JsonSiteAttributeSchemaEntry'
      required:
        - type
        - name
        - required
        - system
    StringSiteAttributeSchemaEntry:
      type: object
      description: String site attribute definition.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeSchemaEntry'
      additionalProperties: false
    NumberSiteAttributeSchemaEntry:
      type: object
      description: Number site attribute definition.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeSchemaEntry'
      additionalProperties: false
    BooleanSiteAttributeSchemaEntry:
      type: object
      description: Boolean site attribute definition.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeSchemaEntry'
      additionalProperties: false
    JsonSiteAttributeSchemaEntry:
      type: object
      description: JSON site attribute definition.
      allOf:
        - $ref: '#/components/schemas/SiteAttributeSchemaEntry'
      additionalProperties: false
      properties:
        typeSchemaName:
          type:
            - string
            - 'null'
          description: Name of the JSON schema (from the site schema's schemas) used to validate the attribute's JSON value; null when the attribute has no bound schema.
    SiteEntitySegment:
      type: string
      description: Site entity path segment. Segments use lowercase letters, numbers, and hyphens only.
      minLength: 1
      maxLength: 64
      pattern: ^[a-z0-9-]{1,64}$
      example: room
    SiteEntitySchemaEntry:
      type: object
      description: Site entity definition.
      additionalProperties: false
      properties:
        entityType:
          $ref: '#/components/schemas/SiteEntitySegment'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeSchemaEntry'
        scopes:
          type: array
          items:
            $ref: '#/components/schemas/SiteEntityPathGlobPattern'
        leaf:
          type: boolean
          default: false
          description: When true, entities of this type are leaves and cannot have child entities (for example device entities). Optional; defaults to false for backward compatibility.
      required:
        - entityType
        - attributes
        - scopes
    SiteSchemaEntry:
      type: object
      description: Site definition/schema.
      additionalProperties: false
      properties:
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeSchemaEntry'
        entities:
          type: array
          items:
            $ref: '#/components/schemas/SiteEntitySchemaEntry'
        schemas:
          type: object
          additionalProperties:
            type: string
        defaultProperties:
          $ref: '#/components/schemas/SitePropertiesEntry'
      required:
        - attributes
        - entities
        - schemas
    GetSiteSchemaQueryResult:
      type: object
      description: Result for retrieving site definition/schema.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteSchemaEntry'
    SiteSchemaTemplateEntry:
      type: object
      description: A schema template stored under a site's tenant.
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        content:
          description: The site schema stored in this template.
          $ref: '#/components/schemas/SiteSchemaEntry'
        revision:
          $ref: '#/components/schemas/TemplateContentRevision'
        isDefault:
          $ref: '#/components/schemas/TemplateIsDefault'
      required:
        - templateId
        - displayName
        - content
        - revision
        - isDefault
    GetSiteSchemaTemplateQueryResult:
      type: object
      description: Result of GetSiteSchemaTemplateQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteSchemaTemplateEntry'
    SitesWorkerStatusEntry:
      type: object
      description: Current Sites worker status.
      additionalProperties: false
      properties:
        enabled:
          type: boolean
          description: Whether the Sites worker is enabled in the current activation.
        reminderRegistered:
          type: boolean
          description: Whether the persistent Orleans reminder is registered.
        timerRegistered:
          type: boolean
          description: Whether the in-memory Orleans grain timer is registered.
        checkedAt:
          type: integer
          format: int64
          description: Unix time in milliseconds when the status was checked.
        nextRunAt:
          type: integer
          format: int64
          description: Estimated Unix time in milliseconds for the next scheduled run, or 0 when disabled.
      required:
        - enabled
        - reminderRegistered
        - timerRegistered
        - checkedAt
        - nextRunAt
    ListSiteDashboardTemplatesQueryResult:
      type: object
      description: Result of ListSiteDashboardTemplatesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: The dashboard templates.
          items:
            $ref: '#/components/schemas/SiteDashboardTemplateEntry'
    ListSiteEgressStatusesQueryResult:
      type: object
      description: Result of listing site egress statuses.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of site egress statuses.
          items:
            $ref: '#/components/schemas/SiteEgressStatusEntry'
    ListSiteEgressTargetsQueryResult:
      type: object
      description: Result of listing site egress targets.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          items:
            $ref: '#/components/schemas/SiteEgressTargetEntry'
    ListSiteEntitiesQueryResult:
      type: object
      description: Result of listing site entities.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          items:
            $ref: '#/components/schemas/SiteEntityEntry'
    ListSiteSchemaTemplatesQueryResult:
      type: object
      description: Result of ListSiteSchemaTemplatesQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: The schema templates.
          items:
            $ref: '#/components/schemas/SiteSchemaTemplateEntry'
    SpotPriceEntry:
      type: object
      description: A validated spot price for a single market time slot.
      additionalProperties: false
      properties:
        startTime:
          type: string
          format: date-time
          description: Inclusive start of the price slot.
        endTime:
          type: string
          format: date-time
          description: End of the price slot.
        price:
          type: number
          format: double
          description: VAT-inclusive spot price for the slot, in the area currency.
          example: 4.52
        currency:
          type: string
          description: ISO currency code the price is expressed in.
          maxLength: 3
          example: EUR
      required:
        - startTime
        - endTime
        - price
        - currency
    ListSpotPricesQueryResult:
      type: object
      description: Result listing validated spot prices for a market area.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entries:
          type: array
          description: The spot prices ordered by start time.
          items:
            $ref: '#/components/schemas/SpotPriceEntry'
    CheckResourceNameValidityQueryResult:
      type: object
      description: Result of validating a proposed resource name. The name is valid and available when the result has no error; otherwise the base error carries the reason and a code - E_INVALID_DATA for a malformed name or unsupported provider, E_CONFLICT when the name is already in use.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
    ResourceId:
      type: string
      description: Resource identifier.
    ResourceGroupName:
      type: string
      description: Name of a resource group.
      minLength: 1
      maxLength: 149
      pattern: ^[A-Za-z0-9][A-Za-z0-9._-]*[A-Za-z0-9]$|^[A-Za-z0-9]$
    ResourceGroupEntry:
      type: object
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ResourceId'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        name:
          $ref: '#/components/schemas/ResourceGroupName'
        location:
          $ref: '#/components/schemas/ResourceLocation'
        tags:
          $ref: '#/components/schemas/Tags'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        createdBy:
          $ref: '#/components/schemas/CreatedBy'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        modifiedBy:
          $ref: '#/components/schemas/ModifiedBy'
      required:
        - id
        - subscriptionId
        - name
        - location
        - tags
        - createdAt
        - createdBy
        - modifiedAt
        - modifiedBy
    GetResourceGroupQueryResult:
      type: object
      description: Result of retrieving a specific resource group.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceGroupEntry'
    ResourceEntry:
      type: object
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ResourceId'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        name:
          type: string
          description: Name of the resource.
        displayName:
          $ref: '#/components/schemas/DisplayName'
        location:
          $ref: '#/components/schemas/ResourceLocation'
        tags:
          $ref: '#/components/schemas/Tags'
        resourceProvider:
          $ref: '#/components/schemas/ResourceProvider'
        properties:
          type: object
          description: Additional properties of the resource.
          readOnly: true
          additionalProperties:
            type: string
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        createdBy:
          $ref: '#/components/schemas/CreatedBy'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        modifiedBy:
          $ref: '#/components/schemas/ModifiedBy'
      required:
        - id
        - subscriptionId
        - resourceGroup
        - name
        - displayName
        - location
        - tags
        - resourceProvider
        - properties
        - createdAt
        - createdBy
        - modifiedAt
        - modifiedBy
    GetResourceQueryResult:
      type: object
      description: Result of retrieving a specific resource from a resource group.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceEntry'
    SubscriptionEntry:
      type: object
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ResourceId'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        tags:
          $ref: '#/components/schemas/Tags'
        managedByTenants:
          type: array
          description: A list of tenants that are managing the subscription.
          items:
            $ref: '#/components/schemas/TenantId'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        createdBy:
          $ref: '#/components/schemas/CreatedBy'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        modifiedBy:
          $ref: '#/components/schemas/ModifiedBy'
      required:
        - id
        - subscriptionId
        - displayName
        - tags
        - managedByTenants
        - createdAt
        - createdBy
        - modifiedAt
        - modifiedBy
    GetSubscriptionQueryResult:
      type: object
      description: Result of a query to retrieve a list of subscriptions.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SubscriptionEntry'
    ListResourceGroupsQueryResult:
      type: object
      description: Result of a query to retrieve a list of resource groups of a subscription.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of resource groups matching the query criteria.
          items:
            $ref: '#/components/schemas/ResourceGroupEntry'
    ListResourcesQueryResult:
      type: object
      description: Result of a query to retrieve a list of resources of a subscription.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of resources matching the query criteria.
          items:
            $ref: '#/components/schemas/ResourceEntry'
    ListSubscriptionsQueryResult:
      type: object
      description: Result of a query to retrieve a list of subscriptions.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of subscriptions matching the query criteria.
          items:
            $ref: '#/components/schemas/SubscriptionEntry'
    TenantEntry:
      type: object
      description: Summary about your tenant that is publicly displayed to users in other tenants.
      additionalProperties: false
      properties:
        id:
          $ref: '#/components/schemas/ResourceId'
        tenantId:
          $ref: '#/components/schemas/TenantId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        locations:
          type: array
          description: Available locations for the tenant. This is the allowed set of values for a resource group's `location` (see `CreateResourceGroupCommand.location`); there is no separate "list locations" query — this is the source of truth.
          items:
            type: string
        tags:
          $ref: '#/components/schemas/Tags'
        createdBy:
          $ref: '#/components/schemas/CreatedBy'
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedBy:
          $ref: '#/components/schemas/ModifiedBy'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
      required:
        - id
        - tenantId
        - displayName
        - locations
        - createdBy
        - createdAt
        - modifiedBy
        - modifiedAt
    GetCurrentTenantQueryResult:
      type: object
      description: Result of the GetCurrentTenantQuery.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/TenantEntry'
    Revision:
      type: integer
      format: int32
      minimum: 1
      description: Server-owned revision, incremented on each successful set. Supply it as the concurrency guard on the next set. A never-set resource reports revision 1.
      example: 1
    MaxConcurrentOperations:
      type: integer
      format: int32
      minimum: 1
      default: 4
      description: Maximum number of operations the tenant may run concurrently.
      example: 4
    TenantPropertiesEntry:
      type: object
      description: Tenant properties.
      additionalProperties: false
      properties:
        revision:
          $ref: '#/components/schemas/Revision'
        maxConcurrentOperations:
          $ref: '#/components/schemas/MaxConcurrentOperations'
      required:
        - revision
        - maxConcurrentOperations
    ListTenantsQueryResult:
      type: object
      description: Result of a query to retrieve a list of tenants in the system.
      allOf:
        - $ref: '#/components/schemas/QueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        entries:
          type: array
          description: A list of tenants matching the query criteria.
          items:
            $ref: '#/components/schemas/TenantEntry'
    QueryResponse:
      type: object
      description: Response object for query result.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/QueryResult'
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        traceparent:
          $ref: '#/components/schemas/Traceparent'
      required:
        - result
    Command:
      type: object
      x-abstract: true
      description: Base type commands. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          AddDeviceConfigurationTemplateCommand: '#/components/schemas/AddDeviceConfigurationTemplateCommand'
          AddDeviceDefinitionTemplateCommand: '#/components/schemas/AddDeviceDefinitionTemplateCommand'
          ClearConfigurationCommand: '#/components/schemas/ClearConfigurationCommand'
          CreateDeviceRegisterEntryCommand: '#/components/schemas/CreateDeviceRegisterEntryCommand'
          DeleteDeviceConfigurationTemplateCommand: '#/components/schemas/DeleteDeviceConfigurationTemplateCommand'
          DeleteDeviceDefinitionTemplateCommand: '#/components/schemas/DeleteDeviceDefinitionTemplateCommand'
          DeleteDeviceRegisterEntryCommand: '#/components/schemas/DeleteDeviceRegisterEntryCommand'
          ExecuteDeviceCommand: '#/components/schemas/ExecuteDeviceCommand'
          RegisterHubDeviceCommand: '#/components/schemas/RegisterHubDeviceCommand'
          ResetConfigurationRevisionCommand: '#/components/schemas/ResetConfigurationRevisionCommand'
          SendDeviceCommand: '#/components/schemas/SendDeviceCommand'
          SetDeviceConfigurationCommand: '#/components/schemas/SetDeviceConfigurationCommand'
          StartRouteDeviceRegisterToHubCommand: '#/components/schemas/StartRouteDeviceRegisterToHubCommand'
          StartRouteDeviceRegisterToParentCommand: '#/components/schemas/StartRouteDeviceRegisterToParentCommand'
          StartUnrouteDeviceRegisterCommand: '#/components/schemas/StartUnrouteDeviceRegisterCommand'
          UpdateDeviceConfigurationTemplateCommand: '#/components/schemas/UpdateDeviceConfigurationTemplateCommand'
          UpdateDeviceDefinitionTemplateCommand: '#/components/schemas/UpdateDeviceDefinitionTemplateCommand'
          UpdateDeviceRegisterEntryCommand: '#/components/schemas/UpdateDeviceRegisterEntryCommand'
          CreateHubUserAssignmentCommand: '#/components/schemas/CreateHubUserAssignmentCommand'
          DeleteHubUserAssignmentCommand: '#/components/schemas/DeleteHubUserAssignmentCommand'
          RebootHubDeviceCommand: '#/components/schemas/RebootHubDeviceCommand'
          RestartHubDeviceCommand: '#/components/schemas/RestartHubDeviceCommand'
          CreateDeviceRegisterKeyVaultCommand: '#/components/schemas/CreateDeviceRegisterKeyVaultCommand'
          CreateTenantKeyVaultCommand: '#/components/schemas/CreateTenantKeyVaultCommand'
          RevokeDeviceRegisterKeyVaultCommand: '#/components/schemas/RevokeDeviceRegisterKeyVaultCommand'
          RevokeTenantKeyVaultCommand: '#/components/schemas/RevokeTenantKeyVaultCommand'
          CancelOperationCommand: '#/components/schemas/CancelOperationCommand'
          AddSiteDashboardTemplateCommand: '#/components/schemas/AddSiteDashboardTemplateCommand'
          AddSiteSchemaTemplateCommand: '#/components/schemas/AddSiteSchemaTemplateCommand'
          CreateSiteEgressTargetCommand: '#/components/schemas/CreateSiteEgressTargetCommand'
          CreateSiteEntityCommand: '#/components/schemas/CreateSiteEntityCommand'
          DeleteSiteDashboardTemplateCommand: '#/components/schemas/DeleteSiteDashboardTemplateCommand'
          DeleteSiteEgressTargetCommand: '#/components/schemas/DeleteSiteEgressTargetCommand'
          DeleteSiteEntityCommand: '#/components/schemas/DeleteSiteEntityCommand'
          DeleteSiteSchemaTemplateCommand: '#/components/schemas/DeleteSiteSchemaTemplateCommand'
          MoveDeviceToParentSiteEntityCommand: '#/components/schemas/MoveDeviceToParentSiteEntityCommand'
          MoveDeviceToSiteEntityCommand: '#/components/schemas/MoveDeviceToSiteEntityCommand'
          SetSitePropertiesCommand: '#/components/schemas/SetSitePropertiesCommand'
          UpdateSiteCommand: '#/components/schemas/UpdateSiteCommand'
          UpdateSiteDashboardTemplateCommand: '#/components/schemas/UpdateSiteDashboardTemplateCommand'
          UpdateSiteEgressTargetCommand: '#/components/schemas/UpdateSiteEgressTargetCommand'
          UpdateSiteEntityCommand: '#/components/schemas/UpdateSiteEntityCommand'
          UpdateSiteSchemaCommand: '#/components/schemas/UpdateSiteSchemaCommand'
          UpdateSiteSchemaTemplateCommand: '#/components/schemas/UpdateSiteSchemaTemplateCommand'
          CreateResourceCommand: '#/components/schemas/CreateResourceCommand'
          CreateResourceGroupCommand: '#/components/schemas/CreateResourceGroupCommand'
          CreateSubscriptionCommand: '#/components/schemas/CreateSubscriptionCommand'
          DeleteResourceCommand: '#/components/schemas/DeleteResourceCommand'
          DeleteResourceGroupCommand: '#/components/schemas/DeleteResourceGroupCommand'
          DeleteSubscriptionCommand: '#/components/schemas/DeleteSubscriptionCommand'
          UpdateResourceCommand: '#/components/schemas/UpdateResourceCommand'
          UpdateResourceGroupCommand: '#/components/schemas/UpdateResourceGroupCommand'
          UpdateSubscriptionCommand: '#/components/schemas/UpdateSubscriptionCommand'
          SetCurrentTenantCommand: '#/components/schemas/SetCurrentTenantCommand'
      required:
        - type
    TemplateContentJson:
      type: string
      description: Template content as a JSON object, serialized to a JSON string.
    SetTemplateAsDefault:
      type: boolean
      description: Set this template as the default for the device type.
    AddDeviceConfigurationTemplateCommand:
      type: object
      description: Add a device configuration template for a device type in the caller's tenant. The server assigns revision 1.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetTemplateAsDefault'
      required:
        - deviceType
        - templateId
        - displayName
        - contentJson
    AddDeviceDefinitionTemplateCommand:
      type: object
      description: Add a device definition template for a device type in the caller's tenant. The server assigns revision 1.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetTemplateAsDefault'
      required:
        - deviceType
        - templateId
        - displayName
        - contentJson
    ClearConfigurationCommand:
      type: object
      description: Command to clear a device's desired configuration, de-configuring it (its configuration status returns to "no configuration"). Bumps the desired revision so devices re-apply and clear their configuration.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
    CreateDeviceRegisterEntryCommand:
      type: object
      description: Command to create a device entry in a device register.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        name:
          $ref: '#/components/schemas/DeviceName'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
          deprecated: true
          description: Deprecated. Link a device with the dedicated routing operations (StartRouteDeviceRegisterToHubCommand, StartRouteDeviceRegisterToParentCommand, StartUnrouteDeviceRegisterCommand) instead of setting routing on create.
      required:
        - deviceRegisterId
        - deviceId
        - deviceType
        - name
    TemplateRevision:
      type: integer
      format: int32
      minimum: 1
      description: The template revision this update is based on — the revision the caller last read (from the template's `revision` field). If it does not match the stored revision, meaning the template was updated by someone else first, the update is rejected with a conflict so the caller can reload and re-apply.
      example: 1
    DeleteDeviceConfigurationTemplateCommand:
      type: object
      description: Delete a device configuration template for a device type in the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          description: Optional concurrency guard. When set, the template is deleted only if its current revision matches; a mismatch is rejected with a precondition failure. Omit to delete unconditionally.
          $ref: '#/components/schemas/TemplateRevision'
      required:
        - deviceType
        - templateId
    DeleteDeviceDefinitionTemplateCommand:
      type: object
      description: Delete a device definition template for a device type in the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          description: Optional concurrency guard. When set, the template is deleted only if its current revision matches; a mismatch is rejected with a precondition failure. Omit to delete unconditionally.
          $ref: '#/components/schemas/TemplateRevision'
      required:
        - deviceType
        - templateId
    DeleteDeviceRegisterEntryCommand:
      type: object
      description: Command to delete a device entry from a device register.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        recursive:
          type: boolean
          description: |
            If true, all child device entries will also be deleted. (default: true)
          default: true
      required:
        - deviceRegisterId
        - deviceId
    DeviceContentType:
      type: string
      description: MIME content type of the device request or response content. Defaults to application/json for a request when omitted.
    DeviceRequestContentJson:
      type: string
      description: The request content sent to the device as a JSON object, serialized to a JSON string.
    ExecuteDeviceCommand:
      type: object
      description: Command to send a request to a device via its device register and return the device's response. Waits up to the command timeout (45 seconds) for the device to respond; a timeout is reported as E_TIMEOUT, an offline device as E_NO_CONNECTION, an unknown device as E_NOT_FOUND, and a device or hub error as E_DEPENDENCY_FAILED.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        contentType:
          $ref: '#/components/schemas/DeviceContentType'
        contentJson:
          $ref: '#/components/schemas/DeviceRequestContentJson'
      required:
        - deviceRegisterId
        - deviceId
        - contentJson
    RegisterHubDeviceCommand:
      type: object
      description: Command to register a Cozify hub, identified by its serial number, as a device entry in a device register. If the hub is not yet claimed it is claimed to the register's tenant first.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        name:
          $ref: '#/components/schemas/DeviceName'
        tags:
          $ref: '#/components/schemas/Tags'
      required:
        - deviceRegisterId
        - serialNumber
    ResetConfigurationRevisionCommand:
      type: object
      description: Administrative command to reset a device's desired configuration revision, for recovery when an external configuration system has lost track of revisions. Resets the revision counter to the target value (defaults to 1, the first expected configuration), keeps the current configuration payload, and clears applied tracking so devices re-apply against the reset baseline. Targets a single device when deviceId is given, otherwise every device in the register.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        revision:
          description: The desired revision to reset to. Defaults to 1 when omitted (the first expected configuration).
          type: integer
          format: int32
      required:
        - deviceRegisterId
    DeviceCommandPayloadJson:
      type: string
      description: The device command payload as a JSON object, serialized to a JSON string.
    SendDeviceCommand:
      type: object
      description: Command to send a runtime command to a device via its device register. The command is dispatched to the device through its hub and returns as soon as the hub accepts it for delivery; it does not wait for the device to execute or acknowledge it. Use ExecuteDeviceCommand when the device's response is required.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        payloadJson:
          $ref: '#/components/schemas/DeviceCommandPayloadJson'
      required:
        - deviceRegisterId
        - deviceId
        - payloadJson
    ConfigurationRevision:
      type: integer
      format: int32
      minimum: 0
      description: The desired configuration revision this change is based on — the revision the caller last read (the `desiredRevision` from the device's configuration status). If it does not match the stored desired revision, meaning the configuration was changed by someone else first, the update is rejected as a precondition failure (`E_PRECONDITION_FAILED`) so the caller can reload and re-apply. Use 0 for a device that has no configuration yet.
      example: 0
    SetDeviceConfigurationCommand:
      type: object
      description: Command to set the desired configuration for a device, creating a new desired revision. The change must be based on the current desired revision; it is rejected with a precondition failure (`E_PRECONDITION_FAILED`) if another change landed first.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        revision:
          $ref: '#/components/schemas/ConfigurationRevision'
        configurationJson:
          $ref: '#/components/schemas/DeviceConfigurationJson'
      required:
        - deviceRegisterId
        - deviceId
        - revision
        - configurationJson
    StartRouteDeviceRegisterToHubCommand:
      type: object
      description: Start an operation that links a device register entry to a hub.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        hubId:
          $ref: '#/components/schemas/HubId'
      required:
        - deviceRegisterId
        - deviceId
        - hubId
    StartRouteDeviceRegisterToParentCommand:
      type: object
      description: Start an operation that links a device register entry to a parent device.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        parentDeviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
        - parentDeviceId
    StartUnrouteDeviceRegisterCommand:
      type: object
      description: Start an operation that removes a device register entry's routing link.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceRegisterId
        - deviceId
    UpdateDeviceConfigurationTemplateCommand:
      type: object
      description: Update a device configuration template's content and display name. The server increments the revision.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          $ref: '#/components/schemas/TemplateRevision'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetTemplateAsDefault'
      required:
        - deviceType
        - templateId
        - revision
        - displayName
        - contentJson
    UpdateDeviceDefinitionTemplateCommand:
      type: object
      description: Update a device definition template's content and display name. The server increments the revision.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          $ref: '#/components/schemas/TemplateRevision'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetTemplateAsDefault'
      required:
        - deviceType
        - templateId
        - revision
        - displayName
        - contentJson
    UpdateDeviceRegisterEntryCommand:
      type: object
      description: Command to update a device entry in a device register.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        name:
          $ref: '#/components/schemas/DeviceName'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/DeviceRegisterRoutingEntry'
          deprecated: true
          description: Deprecated. Change a device's link with the dedicated routing operations (StartRouteDeviceRegisterToHubCommand, StartRouteDeviceRegisterToParentCommand, StartUnrouteDeviceRegisterCommand) instead of setting routing on update.
      required:
        - deviceRegisterId
        - deviceId
    UserEmailProperty:
      type: string
      description: Email of the user.
      format: email
      example: some.user@example.com
    CreateHubUserAssignmentCommand:
      type: object
      description: Command to invite or create a user assignment for a hub.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
        email:
          $ref: '#/components/schemas/UserEmailProperty'
        role:
          $ref: '#/components/schemas/HubUserRole'
        skipCreate:
          type: boolean
          description: When true, requires the user to already exist instead of creating one for the email.
          default: false
      required:
        - hubId
        - email
        - role
    DeleteHubUserAssignmentCommand:
      type: object
      description: Command to revoke a user assignment from a hub, identifying the user by userId or email.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
        userId:
          $ref: '#/components/schemas/UserIdProperty'
          description: The user whose assignment is revoked. At least one of userId or email must be provided.
        email:
          $ref: '#/components/schemas/UserEmailProperty'
          description: The user whose assignment is revoked, identified by email. At least one of userId or email must be provided.
      required:
        - hubId
    RebootHubDeviceCommand:
      type: object
      description: Command to reboot a hub.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
      required:
        - hubId
    RestartHubDeviceCommand:
      type: object
      description: Command to restart a hub.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubId'
      required:
        - hubId
    CreateDeviceRegisterKeyVaultCommand:
      type: object
      description: Command to add a new device register key and rotate existing key material.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        keyId:
          $ref: '#/components/schemas/KeyId'
        secret:
          type: string
          description: New key material that becomes the primary key.
        displayName:
          $ref: '#/components/schemas/DisplayName'
        tags:
          $ref: '#/components/schemas/Tags'
        notBefore:
          $ref: '#/components/schemas/KeyNotBefore'
      required:
        - deviceRegisterId
        - keyId
        - secret
    CreateTenantKeyVaultCommand:
      type: object
      description: Command to create a tenant key vault entry.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        keyId:
          $ref: '#/components/schemas/KeyId'
        secret:
          type: string
          description: Secret associated with the key vault entry.
        displayName:
          $ref: '#/components/schemas/DisplayName'
        tags:
          $ref: '#/components/schemas/Tags'
        notBefore:
          $ref: '#/components/schemas/KeyNotBefore'
      required:
        - keyId
        - secret
    RevokeDeviceRegisterKeyVaultCommand:
      type: object
      description: Command to revoke a device register key and rotate existing key material.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        keyId:
          $ref: '#/components/schemas/KeyId'
      required:
        - deviceRegisterId
        - keyId
    RevokeTenantKeyVaultCommand:
      type: object
      description: Command to delete a tenant key vault entry.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        keyId:
          $ref: '#/components/schemas/KeyId'
      required:
        - keyId
    CancelOperationCommand:
      type: object
      description: Request cancellation of a running operation.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        operationId:
          type: string
          format: uuid
          description: The id of the operation to cancel.
      required:
        - operationId
    SetDashboardTemplateAsDefault:
      type: boolean
      description: Set this template as the dashboard default.
    AddSiteDashboardTemplateCommand:
      type: object
      description: Add a dashboard template for the caller's tenant. The server assigns revision 1.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetDashboardTemplateAsDefault'
      required:
        - templateId
        - displayName
        - contentJson
    SetSchemaTemplateAsDefault:
      type: boolean
      description: Set this template as the schema default.
    AddSiteSchemaTemplateCommand:
      type: object
      description: Add a schema template for the caller's tenant. The server assigns revision 1.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        content:
          description: The site schema to store as the template content.
          $ref: '#/components/schemas/SiteSchemaEntry'
        setAsDefault:
          $ref: '#/components/schemas/SetSchemaTemplateAsDefault'
      required:
        - templateId
        - displayName
        - content
    CreateSiteEgressTargetCommand:
      type: object
      description: Create a site egress target.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        target:
          $ref: '#/components/schemas/SiteEgressTargetEntry'
      required:
        - siteId
        - target
    SiteEntityParentPath:
      type: string
      description: Canonical parent Site entity path. Use an empty string to create a root-level entity.
      maxLength: 1024
      pattern: ^(?:|/(?:[a-z0-9-]{1,64}/[a-z0-9-]{1,64})(?:/[a-z0-9-]{1,64}/[a-z0-9-]{1,64})*)$
      example: /building/1/floor/2
    CreateSiteEntityCommand:
      type: object
      description: Create a site entity.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        parentPath:
          $ref: '#/components/schemas/SiteEntityParentPath'
        entityType:
          $ref: '#/components/schemas/SiteEntitySegment'
        name:
          $ref: '#/components/schemas/SiteEntitySegment'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
      required:
        - siteId
        - parentPath
        - entityType
        - name
    DeleteSiteDashboardTemplateCommand:
      type: object
      description: Delete a dashboard template from the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          description: Optional concurrency guard. When set, the template is deleted only if its current revision matches; a mismatch is rejected with a precondition failure. Omit to delete unconditionally.
          $ref: '#/components/schemas/TemplateRevision'
      required:
        - templateId
    DeleteSiteEgressTargetCommand:
      type: object
      description: Delete a site egress target.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        targetId:
          type: string
      required:
        - siteId
        - targetId
    DeleteSiteEntityCommand:
      type: object
      description: Delete a site entity.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        path:
          $ref: '#/components/schemas/SiteEntityPath'
      required:
        - siteId
        - path
    DeleteSiteSchemaTemplateCommand:
      type: object
      description: Delete a schema template from the caller's tenant.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          description: Optional concurrency guard. When set, the template is deleted only if its current revision matches; a mismatch is rejected with a precondition failure. Omit to delete unconditionally.
          $ref: '#/components/schemas/TemplateRevision'
      required:
        - templateId
    MoveDeviceToParentSiteEntityCommand:
      type: object
      description: Move a device site entity under a new parent.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        source:
          $ref: '#/components/schemas/SiteEntityPath'
        targetParent:
          $ref: '#/components/schemas/SiteEntityPath'
        routeDeviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - siteId
        - source
        - targetParent
    MoveDeviceToSiteEntityCommand:
      type: object
      description: Move or clone a device site entity to a target entity path.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        source:
          $ref: '#/components/schemas/SiteEntityPath'
        target:
          $ref: '#/components/schemas/SiteEntityPath'
        routeDeviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - siteId
        - source
        - target
    SetSitePropertiesCommand:
      type: object
      description: Set site properties.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        properties:
          $ref: '#/components/schemas/SitePropertiesEntry'
      required:
        - siteId
        - properties
    UpdateSiteCommand:
      type: object
      description: Update site metadata.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
      required:
        - siteId
    UpdateSiteDashboardTemplateCommand:
      type: object
      description: Update a dashboard template's content and display name. The server increments the revision.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          $ref: '#/components/schemas/TemplateRevision'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        contentJson:
          $ref: '#/components/schemas/TemplateContentJson'
        setAsDefault:
          $ref: '#/components/schemas/SetDashboardTemplateAsDefault'
      required:
        - templateId
        - revision
        - displayName
        - contentJson
    UpdateSiteEgressTargetCommand:
      type: object
      description: Update a site egress target.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        target:
          $ref: '#/components/schemas/SiteEgressTargetEntry'
      required:
        - siteId
        - target
    UpdateSiteEntityCommand:
      type: object
      description: Update a site entity.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        path:
          $ref: '#/components/schemas/SiteEntityPath'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        changeParentPath:
          $ref: '#/components/schemas/SiteEntityParentPath'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
      required:
        - siteId
        - path
    UpdateSiteSchemaCommand:
      type: object
      description: Update site definition/schema.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        siteId:
          $ref: '#/components/schemas/SiteId'
        definition:
          $ref: '#/components/schemas/SiteSchemaEntry'
        dryRun:
          type: boolean
          description: |
            When true, the proposed definition is validated against the site's existing entities but not persisted, so a caller can confirm the change is savable without committing it.
          default: false
      required:
        - siteId
        - definition
    UpdateSiteSchemaTemplateCommand:
      type: object
      description: Update a schema template's content and display name. The server increments the revision.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
        revision:
          $ref: '#/components/schemas/TemplateRevision'
        displayName:
          $ref: '#/components/schemas/DisplayName'
        content:
          description: The site schema to store as the template content.
          $ref: '#/components/schemas/SiteSchemaEntry'
        setAsDefault:
          $ref: '#/components/schemas/SetSchemaTemplateAsDefault'
      required:
        - templateId
        - revision
        - displayName
        - content
    ResourceDefinition:
      type: object
      x-abstract: true
      description: Base type for resource creation definitions. The type value identifies the definition shape; the resourceProvider command field identifies the provider to create. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          type: string
          description: Resource definition shape discriminator.
      discriminator:
        propertyName: type
        mapping:
          site: '#/components/schemas/SiteResourceDefinition'
          deviceRegister: '#/components/schemas/DeviceRegisterResourceDefinition'
          provider: '#/components/schemas/ProviderResourceDefinition'
      required:
        - type
    SiteResourceDefinition:
      type: object
      description: Site-specific resource creation definition for Cozify.Sites resources.
      allOf:
        - $ref: '#/components/schemas/ResourceDefinition'
      additionalProperties: false
      properties:
        displayName:
          description: Display name for the site metadata.
          $ref: '#/components/schemas/DisplayName'
        properties:
          description: Initial site properties.
          $ref: '#/components/schemas/SitePropertiesEntry'
        attributes:
          type: array
          description: Initial site metadata attributes.
          items:
            $ref: '#/components/schemas/SiteAttributeValueEntry'
        definition:
          description: Initial site schema definition.
          $ref: '#/components/schemas/SiteSchemaEntry'
    DeviceRegisterResourceDefinition:
      type: object
      description: Device-register resource creation definition.
      allOf:
        - $ref: '#/components/schemas/ResourceDefinition'
      additionalProperties: false
    ProviderResourceDefinition:
      type: object
      description: Generic provider resource creation definition for providers without a typed definition schema.
      allOf:
        - $ref: '#/components/schemas/ResourceDefinition'
      additionalProperties: false
      properties:
        properties:
          type: object
          description: Provider-specific creation properties.
          additionalProperties:
            type: string
    CreateResourceCommand:
      type: object
      description: Command to create a resource in a resource group.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        resourceName:
          type: string
          description: Name of the resource.
        resourceProvider:
          $ref: '#/components/schemas/ResourceProvider'
        displayName:
          description: Display name for the resource.
          $ref: '#/components/schemas/DisplayName'
        tags:
          description: Tags for the resource.
          $ref: '#/components/schemas/Tags'
        definition:
          description: Optional provider-specific resource definition.
          $ref: '#/components/schemas/ResourceDefinition'
      required:
        - subscriptionId
        - resourceGroup
        - resourceName
        - resourceProvider
    CreateResourceGroupCommand:
      type: object
      description: Command to create a resource group in a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        name:
          $ref: '#/components/schemas/ResourceGroupName'
        location:
          $ref: '#/components/schemas/ResourceLocation'
        tags:
          description: Tags for the resource group.
          $ref: '#/components/schemas/Tags'
      required:
        - subscriptionId
        - name
        - location
    CreateSubscriptionCommand:
      type: object
      description: Command to create a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        displayName:
          $ref: '#/components/schemas/DisplayName'
        tags:
          $ref: '#/components/schemas/Tags'
      required:
        - displayName
    DeleteResourceCommand:
      type: object
      description: Command to delete a resource from a resource group.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        resourceName:
          type: string
          description: Name of the resource.
      required:
        - subscriptionId
        - resourceGroup
        - resourceName
    DeleteResourceGroupCommand:
      type: object
      description: Command to delete an empty resource group from a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
      required:
        - subscriptionId
        - resourceGroup
    DeleteSubscriptionCommand:
      type: object
      description: Command to delete a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
      required:
        - subscriptionId
    UpdateResourceCommand:
      type: object
      description: Command to update resource metadata.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
        resourceGroup:
          type: string
          description: Name of the resource group.
        resourceName:
          type: string
          description: Name of the resource.
        displayName:
          description: New display name for the resource (leave empty to keep the same).
          $ref: '#/components/schemas/DisplayName'
        tags:
          description: Replacement tags for the resource (leave empty to keep the same).
          $ref: '#/components/schemas/Tags'
      required:
        - subscriptionId
        - resourceGroup
        - resourceName
    UpdateResourceGroupCommand:
      type: object
      description: Command to update a resource group in a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          description: Subscription that owns the resource group to update.
          $ref: '#/components/schemas/SubscriptionId'
        name:
          $ref: '#/components/schemas/ResourceGroupName'
        tags:
          description: New tags for the resource group (leave empty to keep the same).
          $ref: '#/components/schemas/Tags'
      required:
        - subscriptionId
        - name
    UpdateSubscriptionCommand:
      type: object
      description: Command to update a subscription.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        subscriptionId:
          description: Targeted subscription with the given subscriptionId will be updated.
          $ref: '#/components/schemas/SubscriptionId'
        displayName:
          description: New display name for the subscription (leave empty to keep the same).
          $ref: '#/components/schemas/DisplayName'
        tags:
          description: New tags for the subscription (leave empty to keep the same).
          $ref: '#/components/schemas/Tags'
      required:
        - subscriptionId
    SetCurrentTenantCommand:
      type: object
      description: Command to set the current tenant. This command is used to switch the context to a specific tenant for subsequent operations.
      allOf:
        - $ref: '#/components/schemas/Command'
      additionalProperties: false
      properties:
        tenantId:
          description: The identifier of the tenant to set as the current tenant.
          $ref: '#/components/schemas/TenantId'
      required:
        - tenantId
    CommandRequest:
      type: object
      description: Request object for command.
      additionalProperties: false
      properties:
        command:
          $ref: '#/components/schemas/Command'
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        traceparent:
          $ref: '#/components/schemas/Traceparent'
      required:
        - command
    CommandResult:
      type: object
      x-abstract: true
      description: Base type for all hub command results. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          AddDeviceConfigurationTemplateCommandResult: '#/components/schemas/AddDeviceConfigurationTemplateCommandResult'
          AddDeviceDefinitionTemplateCommandResult: '#/components/schemas/AddDeviceDefinitionTemplateCommandResult'
          ClearConfigurationCommandResult: '#/components/schemas/ClearConfigurationCommandResult'
          CreateDeviceRegisterEntryCommandResult: '#/components/schemas/CreateDeviceRegisterEntryCommandResult'
          DeleteDeviceConfigurationTemplateCommandResult: '#/components/schemas/DeleteDeviceConfigurationTemplateCommandResult'
          DeleteDeviceDefinitionTemplateCommandResult: '#/components/schemas/DeleteDeviceDefinitionTemplateCommandResult'
          DeleteDeviceRegisterEntryCommandResult: '#/components/schemas/DeleteDeviceRegisterEntryCommandResult'
          ExecuteDeviceCommandResult: '#/components/schemas/ExecuteDeviceCommandResult'
          RegisterHubDeviceCommandResult: '#/components/schemas/RegisterHubDeviceCommandResult'
          ResetConfigurationRevisionCommandResult: '#/components/schemas/ResetConfigurationRevisionCommandResult'
          SendDeviceCommandResult: '#/components/schemas/SendDeviceCommandResult'
          SetDeviceConfigurationCommandResult: '#/components/schemas/SetDeviceConfigurationCommandResult'
          StartRouteDeviceRegisterToHubCommandResult: '#/components/schemas/StartRouteDeviceRegisterToHubCommandResult'
          StartRouteDeviceRegisterToParentCommandResult: '#/components/schemas/StartRouteDeviceRegisterToParentCommandResult'
          StartUnrouteDeviceRegisterCommandResult: '#/components/schemas/StartUnrouteDeviceRegisterCommandResult'
          UpdateDeviceConfigurationTemplateCommandResult: '#/components/schemas/UpdateDeviceConfigurationTemplateCommandResult'
          UpdateDeviceDefinitionTemplateCommandResult: '#/components/schemas/UpdateDeviceDefinitionTemplateCommandResult'
          UpdateDeviceRegisterEntryCommandResult: '#/components/schemas/UpdateDeviceRegisterEntryCommandResult'
          CreateHubUserAssignmentCommandResult: '#/components/schemas/CreateHubUserAssignmentCommandResult'
          DeleteHubUserAssignmentCommandResult: '#/components/schemas/DeleteHubUserAssignmentCommandResult'
          RebootHubDeviceCommandResult: '#/components/schemas/RebootHubDeviceCommandResult'
          RestartHubDeviceCommandResult: '#/components/schemas/RestartHubDeviceCommandResult'
          CreateDeviceRegisterKeyVaultCommandResult: '#/components/schemas/CreateDeviceRegisterKeyVaultCommandResult'
          CreateTenantKeyVaultCommandResult: '#/components/schemas/CreateTenantKeyVaultCommandResult'
          RevokeDeviceRegisterKeyVaultCommandResult: '#/components/schemas/RevokeDeviceRegisterKeyVaultCommandResult'
          RevokeTenantKeyVaultCommandResult: '#/components/schemas/RevokeTenantKeyVaultCommandResult'
          CancelOperationCommandResult: '#/components/schemas/CancelOperationCommandResult'
          AddSiteDashboardTemplateCommandResult: '#/components/schemas/AddSiteDashboardTemplateCommandResult'
          AddSiteSchemaTemplateCommandResult: '#/components/schemas/AddSiteSchemaTemplateCommandResult'
          CreateSiteEgressTargetCommandResult: '#/components/schemas/CreateSiteEgressTargetCommandResult'
          CreateSiteEntityCommandResult: '#/components/schemas/CreateSiteEntityCommandResult'
          DeleteSiteDashboardTemplateCommandResult: '#/components/schemas/DeleteSiteDashboardTemplateCommandResult'
          DeleteSiteEgressTargetCommandResult: '#/components/schemas/DeleteSiteEgressTargetCommandResult'
          DeleteSiteEntityCommandResult: '#/components/schemas/DeleteSiteEntityCommandResult'
          DeleteSiteSchemaTemplateCommandResult: '#/components/schemas/DeleteSiteSchemaTemplateCommandResult'
          MoveDeviceToParentSiteEntityCommandResult: '#/components/schemas/MoveDeviceToParentSiteEntityCommandResult'
          MoveDeviceToSiteEntityCommandResult: '#/components/schemas/MoveDeviceToSiteEntityCommandResult'
          SetSitePropertiesCommandResult: '#/components/schemas/SetSitePropertiesCommandResult'
          UpdateSiteCommandResult: '#/components/schemas/UpdateSiteCommandResult'
          UpdateSiteDashboardTemplateCommandResult: '#/components/schemas/UpdateSiteDashboardTemplateCommandResult'
          UpdateSiteEgressTargetCommandResult: '#/components/schemas/UpdateSiteEgressTargetCommandResult'
          UpdateSiteEntityCommandResult: '#/components/schemas/UpdateSiteEntityCommandResult'
          UpdateSiteSchemaCommandResult: '#/components/schemas/UpdateSiteSchemaCommandResult'
          UpdateSiteSchemaTemplateCommandResult: '#/components/schemas/UpdateSiteSchemaTemplateCommandResult'
          CreateResourceCommandResult: '#/components/schemas/CreateResourceCommandResult'
          CreateResourceGroupCommandResult: '#/components/schemas/CreateResourceGroupCommandResult'
          CreateSubscriptionCommandResult: '#/components/schemas/CreateSubscriptionCommandResult'
          DeleteResourceCommandResult: '#/components/schemas/DeleteResourceCommandResult'
          DeleteResourceGroupCommandResult: '#/components/schemas/DeleteResourceGroupCommandResult'
          DeleteSubscriptionCommandResult: '#/components/schemas/DeleteSubscriptionCommandResult'
          UpdateResourceCommandResult: '#/components/schemas/UpdateResourceCommandResult'
          UpdateResourceGroupCommandResult: '#/components/schemas/UpdateResourceGroupCommandResult'
          UpdateSubscriptionCommandResult: '#/components/schemas/UpdateSubscriptionCommandResult'
          SetCurrentTenantCommandResult: '#/components/schemas/SetCurrentTenantCommandResult'
      required:
        - type
    AddDeviceConfigurationTemplateCommandResult:
      type: object
      description: Result of AddDeviceConfigurationTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceConfigurationTemplateEntry'
    AddDeviceDefinitionTemplateCommandResult:
      type: object
      description: Result of AddDeviceDefinitionTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceDefinitionTemplateEntry'
    ClearConfigurationCommandResult:
      type: object
      description: Result of the ClearConfigurationCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        status:
          $ref: '#/components/schemas/DeviceConfigurationStatusEntry'
    CreateDeviceRegisterEntryCommandResult:
      type: object
      description: Result of the CreateDeviceRegisterEntryCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    DeleteDeviceConfigurationTemplateCommandResult:
      type: object
      description: Result of DeleteDeviceConfigurationTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
    DeleteDeviceDefinitionTemplateCommandResult:
      type: object
      description: Result of DeleteDeviceDefinitionTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
    DeleteDeviceRegisterEntryCommandResult:
      type: object
      description: Result of the DeleteDeviceRegisterEntryCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entries:
          description: The device entries that were deleted from the register.
          type: array
          items:
            $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    DeviceResponseContentJson:
      type: string
      description: The response content returned by the device as a JSON object, serialized to a JSON string.
    ExecuteDeviceCommandResult:
      type: object
      description: Result of the ExecuteDeviceCommand — the device's response. Present on success; on failure the standard error code is set instead (E_TIMEOUT when the device did not respond in time, E_NO_CONNECTION when it is offline, E_NOT_FOUND when it is unknown, E_DEPENDENCY_FAILED when the device or hub reports an error).
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        contentType:
          $ref: '#/components/schemas/DeviceContentType'
        contentJson:
          $ref: '#/components/schemas/DeviceResponseContentJson'
    RegisterHubDeviceCommandResult:
      type: object
      description: Result of the RegisterHubDeviceCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    ResetConfigurationRevisionCommandResult:
      type: object
      description: Result of the ResetConfigurationRevisionCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        deviceCount:
          description: The number of devices whose configuration revision was reset.
          type: integer
          format: int32
    SendDeviceCommandResult:
      type: object
      description: Result of the SendDeviceCommand. Empty on success — the command was accepted for delivery to the device's hub. Delivery failures are reported through the standard error code (E_NOT_FOUND when the device is unknown, E_NO_CONNECTION when it is offline).
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    SetDeviceConfigurationCommandResult:
      type: object
      description: Result of the SetDeviceConfigurationCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        status:
          $ref: '#/components/schemas/DeviceConfigurationStatusEntry'
    StartRouteDeviceRegisterToHubCommandResult:
      type: object
      description: Result of starting a route-to-hub operation, containing the created operation.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
    StartRouteDeviceRegisterToParentCommandResult:
      type: object
      description: Result of starting a route-to-parent operation, containing the created operation.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
    StartUnrouteDeviceRegisterCommandResult:
      type: object
      description: Result of starting an unroute operation, containing the created operation.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
    UpdateDeviceConfigurationTemplateCommandResult:
      type: object
      description: Result of UpdateDeviceConfigurationTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceConfigurationTemplateEntry'
    UpdateDeviceDefinitionTemplateCommandResult:
      type: object
      description: Result of UpdateDeviceDefinitionTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/DeviceDefinitionTemplateEntry'
    UpdateDeviceRegisterEntryCommandResult:
      type: object
      description: Result of the UpdateDeviceRegisterEntryCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterDeviceEntry'
    CreateHubUserAssignmentCommandResult:
      type: object
      description: Result of creating a hub user assignment.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/HubUserAssignment'
    DeleteHubUserAssignmentCommandResult:
      type: object
      description: Result of deleting a hub user assignment.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    RebootHubDeviceCommandResult:
      type: object
      description: Result of rebooting a hub.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    RestartHubDeviceCommandResult:
      type: object
      description: Result of restarting a hub.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    CreateDeviceRegisterKeyVaultCommandResult:
      type: object
      description: Result of adding or rotating device register key material.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        deviceRegisterId:
          $ref: '#/components/schemas/DeviceRegisterId'
        entry:
          $ref: '#/components/schemas/KeyVaultEntry'
    CreateTenantKeyVaultCommandResult:
      type: object
      description: Result of the command to create a tenant key vault entry.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/KeyVaultEntry'
    RevokeDeviceRegisterKeyVaultCommandResult:
      type: object
      description: Result of revoking a device register key.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    RevokeTenantKeyVaultCommandResult:
      type: object
      description: Result of the command to delete a tenant key vault entry.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    CancelOperationCommandResult:
      type: object
      description: Result of requesting operation cancellation, with the operation's current status.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
    AddSiteDashboardTemplateCommandResult:
      type: object
      description: Result of AddSiteDashboardTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteDashboardTemplateEntry'
    AddSiteSchemaTemplateCommandResult:
      type: object
      description: Result of AddSiteSchemaTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteSchemaTemplateEntry'
    CreateSiteEgressTargetCommandResult:
      type: object
      description: Result of creating a site egress target.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEgressTargetEntry'
    CreateSiteEntityCommandResult:
      type: object
      description: Result of creating a site entity.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEntityEntry'
    DeleteSiteDashboardTemplateCommandResult:
      type: object
      description: Result of DeleteSiteDashboardTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
    DeleteSiteEgressTargetCommandResult:
      type: object
      description: Result of deleting a site egress target.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    DeleteSiteEntityCommandResult:
      type: object
      description: Result of deleting a site entity.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    DeleteSiteSchemaTemplateCommandResult:
      type: object
      description: Result of DeleteSiteSchemaTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        templateId:
          $ref: '#/components/schemas/TemplateId'
    MoveDeviceToParentSiteEntityCommandResult:
      type: object
      description: Result of moving a device site entity under a new parent.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEntityEntry'
    MoveDeviceToSiteEntityCommandResult:
      type: object
      description: Result of moving or cloning a device site entity.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEntityEntry'
    SetSitePropertiesCommandResult:
      type: object
      description: Result for setting site properties.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SitePropertiesEntry'
    UpdateSiteCommandResult:
      type: object
      description: Result for updating site metadata.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteMetadataEntry'
    UpdateSiteDashboardTemplateCommandResult:
      type: object
      description: Result of UpdateSiteDashboardTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteDashboardTemplateEntry'
    UpdateSiteEgressTargetCommandResult:
      type: object
      description: Result of updating a site egress target.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEgressTargetEntry'
    UpdateSiteEntityCommandResult:
      type: object
      description: Result of updating a site entity.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteEntityEntry'
    UpdateSiteSchemaCommandResult:
      type: object
      description: |
        Result for updating site definition/schema. When there is no error the change is savable; on a dry run the returned entry is the validated proposed definition that was not persisted, and on failure the error message names the offending entity path so an editor can show what would break.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SiteSchemaEntry'
        dryRun:
          type: boolean
          description: |
            True when the update was a validation-only dry run, so the definition was validated against existing entities but not persisted.
          default: false
    UpdateSiteSchemaTemplateCommandResult:
      type: object
      description: Result of UpdateSiteSchemaTemplateCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        template:
          $ref: '#/components/schemas/SiteSchemaTemplateEntry'
    CreateResourceCommandResult:
      type: object
      description: Result of creating a resource.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceEntry'
    CreateResourceGroupCommandResult:
      type: object
      description: Result of creating a resource group.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceGroupEntry'
    CreateSubscriptionCommandResult:
      type: object
      description: Result of the CreateSubscriptionCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SubscriptionEntry'
    DeleteResourceCommandResult:
      type: object
      description: Result of deleting a resource from a resource group.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    DeleteResourceGroupCommandResult:
      type: object
      description: Result of deleting a resource group.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    DeleteSubscriptionCommandResult:
      type: object
      description: Result of the DeleteSubscriptionCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
    UpdateResourceCommandResult:
      type: object
      description: Result of updating resource metadata.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceEntry'
    UpdateResourceGroupCommandResult:
      type: object
      description: Result of the UpdateResourceGroupCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/ResourceGroupEntry'
    UpdateSubscriptionCommandResult:
      type: object
      description: Result of the UpdateSubscriptionCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/SubscriptionEntry'
    SetCurrentTenantCommandResult:
      type: object
      description: Result of the SetCurrentTenantCommand.
      allOf:
        - $ref: '#/components/schemas/CommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/TenantEntry'
    CommandResponse:
      type: object
      description: Response object for command result.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/CommandResult'
        correlationId:
          $ref: '#/components/schemas/CorrelationId'
        traceparent:
          $ref: '#/components/schemas/Traceparent'
      required:
        - result
    Push:
      type: object
      x-abstract: true
      description: Base type for server-to-client push messages delivered over the Graph hub stream. Abstract base; never instantiated directly. Use a concrete subtype.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          HeartbeatPush: '#/components/schemas/HeartbeatPush'
          OperationStatusPush: '#/components/schemas/OperationStatusPush'
      required:
        - type
    HeartbeatPush:
      type: object
      description: Server-to-client keep-alive heartbeat carrying the server timestamp.
      allOf:
        - $ref: '#/components/schemas/Push'
      additionalProperties: false
      properties:
        at:
          description: The server time when the heartbeat was emitted.
          type: string
          format: date-time
      required:
        - at
    OperationStatusPush:
      type: object
      description: Live status update for a long-running operation, pushed to the user who started it.
      allOf:
        - $ref: '#/components/schemas/Push'
      additionalProperties: false
      properties:
        operation:
          $ref: '#/components/schemas/OperationEntry'
      required:
        - operation
    PushMessage:
      type: object
      description: Envelope for a single server-to-client message delivered over the Graph hub push stream.
      additionalProperties: false
      properties:
        push:
          $ref: '#/components/schemas/Push'
      required:
        - push
    HubCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph hub commands through /graph/command.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hub/InviteUserHubCommand: '#/components/schemas/InviteUserHubCommand'
          Cozify.Hub/RevokeUserHubCommand: '#/components/schemas/RevokeUserHubCommand'
          Cozify.Hub/RebootHubCommand: '#/components/schemas/RebootHubCommand'
          Cozify.Hub/RestartHubCommand: '#/components/schemas/RestartHubCommand'
      required:
        - type
    InviteUserHubCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: CreateHubUserAssignmentCommand
      allOf:
        - $ref: '#/components/schemas/HubCommand'
      additionalProperties: false
      description: Deprecated. Use the internal hub user-assignment Graph command instead.
      properties:
        email:
          description: The email address of the user to invite.
          type: string
          format: email
        role:
          $ref: '#/components/schemas/HubUserRole'
        skipCreate:
          description: |-
            Determines whether the user should be automatically created if needed.

            If this is set to **true**, the user must already exist.
          type: boolean
          default: false
      required:
        - email
        - role
    RevokeUserHubCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: DeleteHubUserAssignmentCommand
      description: Deprecated. Use the internal hub user-assignment Graph command instead.
      allOf:
        - $ref: '#/components/schemas/HubCommand'
      additionalProperties: false
      properties:
        userId:
          $ref: '#/components/schemas/UserIdProperty'
        email:
          $ref: '#/components/schemas/UserEmailProperty'
    RebootHubCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: RebootHubDeviceCommand
      description: Deprecated. Use the internal hub reboot Graph command instead.
      allOf:
        - $ref: '#/components/schemas/HubCommand'
      additionalProperties: false
    RestartHubCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: RestartHubDeviceCommand
      description: Deprecated. Use the internal hub restart Graph command instead.
      allOf:
        - $ref: '#/components/schemas/HubCommand'
      additionalProperties: false
    HubCommandRequest:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use Graph CommandRequest with migrated hub commands.
      additionalProperties: false
      properties:
        command:
          $ref: '#/components/schemas/HubCommand'
      required:
        - command
    HubCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph command results for hub operations.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hub/InviteUserHubCommandResult: '#/components/schemas/InviteUserHubCommandResult'
          Cozify.Hub/RevokeUserHubCommandResult: '#/components/schemas/RevokeUserHubCommandResult'
          Cozify.Hub/RebootHubCommandResult: '#/components/schemas/RebootHubCommandResult'
          Cozify.Hub/RestartHubCommandResult: '#/components/schemas/RestartHubCommandResult'
      required:
        - type
    InviteUserHubCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of command to invite a user to the Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubCommandResult'
      additionalProperties: false
      properties:
        userAssignment:
          $ref: '#/components/schemas/HubUserAssignment'
    RevokeUserHubCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of command to revoke a user's access to the Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubCommandResult'
      additionalProperties: false
    RebootHubCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of command to reboot the Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubCommandResult'
      additionalProperties: false
    RestartHubCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of command to restart the Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubCommandResult'
      additionalProperties: false
    HubCommandResponse:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: |
        Deprecated. Use Graph CommandResponse with migrated hub commands.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/HubCommandResult'
      required:
        - result
    HubQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph hub queries through /graph/query.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hub/GetUserAssignmentHubQuery: '#/components/schemas/GetUserAssignmentHubQuery'
          Cozify.Hub/ListUserAssignmentsPagedHubQuery: '#/components/schemas/ListUserAssignmentsPagedHubQuery'
          Cozify.Hub/GetMetadataHubQuery: '#/components/schemas/GetMetadataHubQuery'
      required:
        - type
    GetUserAssignmentHubQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: GetHubUserAssignmentQuery
      description: Deprecated. Use the internal hub user-assignment Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubQuery'
      additionalProperties: false
      properties:
        userId:
          description: The identifier of the user to get the assignment for.
          type: string
          format: uuid
      required:
        - userId
    QueryPage:
      type: integer
      description: Specifies the page number of the result set.
      format: int32
      minimum: 1
      example: 1
    QueryPageSize:
      type: integer
      description: |-
        Determines the number of results to display per page.
        Adjusting this value can help balance the amount of data returned with performance considerations.
      format: int32
      minimum: 1
      maximum: 2000
      default: 100
      example: 100
    ListUserAssignmentsHubQueryFilter:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use the internal hub user-assignment Graph query filter instead.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/ListUserAssignmentsHubQuery/KeywordFilter: '#/components/schemas/ListUserAssignmentsHubQueryKeywordFilter'
      required:
        - type
    ListUserAssignmentsHubQueryKeywordFilter:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use the internal hub user-assignment Graph query filter instead.
      allOf:
        - $ref: '#/components/schemas/ListUserAssignmentsHubQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          description: A keyword to filter the results by. The keyword is compared against the user's email address, nickname and phone number.
          type: string
          minLength: 2
      required:
        - keyword
    ListUserAssignmentsPagedHubQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: ListHubUserAssignmentsQuery
      description: Deprecated. Use the internal hub user-assignment Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubQuery'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryPage'
        pageSize:
          $ref: '#/components/schemas/QueryPageSize'
        filters:
          description: An optional array of filters that can be applied to refine the user assignments query. Each filter in the array should adhere to a specified filter schema, allowing for complex querying capabilities.
          type: array
          items:
            $ref: '#/components/schemas/ListUserAssignmentsHubQueryFilter'
      required:
        - page
        - pageSize
    GetMetadataHubQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: GetHubMetadataQuery
      description: Deprecated. Use the internal hub metadata Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubQuery'
      additionalProperties: false
    HubQueryRequest:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use Graph QueryRequest with migrated hub queries.
      additionalProperties: false
      properties:
        query:
          $ref: '#/components/schemas/HubQuery'
      required:
        - query
    HubQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph query results for hub operations.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hub/GetUserAssignmentHubQueryResult: '#/components/schemas/GetUserAssignmentHubQueryResult'
          Cozify.Hub/ListUserAssignmentsPagedHubQueryResult: '#/components/schemas/ListUserAssignmentsPagedHubQueryResult'
          Cozify.Hub/GetMetadataHubQueryResult: '#/components/schemas/GetMetadataHubQueryResult'
      required:
        - type
    GetUserAssignmentHubQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query to get a user assignment for a Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubQueryResult'
      additionalProperties: false
      properties:
        userAssignment:
          $ref: '#/components/schemas/HubUserAssignment'
    QueryResultPage:
      type: integer
      description: Indicates the current page number returned in this result.
      format: int32
      minimum: 0
      default: 0
      example: 1
    QueryResultPageSize:
      type: integer
      description: Reflects the number of items per page for this result, corresponding to the requested page size in the query. This helps in understanding the scope of the data returned.
      format: int32
      minimum: 0
      maximum: 2000
      default: 0
      example: 100
    ListUserAssignmentsPagedHubQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query for paged listing of user assignments.
      allOf:
        - $ref: '#/components/schemas/HubQueryResult'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryResultPage'
        pageSize:
          $ref: '#/components/schemas/QueryResultPageSize'
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        data:
          description: Contains the actual array of user assignments for the current page.
          type: array
          items:
            $ref: '#/components/schemas/HubUserAssignment'
    GetMetadataHubQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query to get metadata from a Cozify Hub.
      allOf:
        - $ref: '#/components/schemas/HubQueryResult'
      additionalProperties: false
      properties:
        metadata:
          $ref: '#/components/schemas/HubMetadata'
    HubQueryResponse:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: |
        Deprecated. Use Graph QueryResponse with migrated hub queries.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/HubQueryResult'
      required:
        - result
    HubsQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Base type for all hubs queries.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hubs/GetDetailsHubsQuery: '#/components/schemas/GetDetailsHubsQuery'
          Cozify.Hubs/GetEntryHubsQuery: '#/components/schemas/GetEntryHubsQuery'
          Cozify.Hubs/ListHubsQuery: '#/components/schemas/ListHubsQuery'
          Cozify.Hubs/ListPagedHubsQuery: '#/components/schemas/ListPagedHubsQuery'
      required:
        - type
    GetDetailsHubsQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: GetHubAdminEntryQuery
      description: Deprecated. Use the internal GetHubAdminEntryQuery Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubsQuery'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
      required:
        - hubId
    GetEntryHubsQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: GetHubAdminEntryQuery
      description: Deprecated. Use the internal GetHubAdminEntryQuery Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubsQuery'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
      required:
        - hubId
    ListHubsQueryFilter:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hubs/ListHubsQuery/NameFilter: '#/components/schemas/ListHubsQueryNameFilter'
          Cozify.Hubs/ListHubsQuery/SerialNumberFilter: '#/components/schemas/ListHubsQuerySerialNumberFilter'
      required:
        - type
    HubNameProperty:
      type: string
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: The human readable name of the Hub.
      maxLength: 50
      pattern: ^([a-zA-Z0-9_.,\-'()&/:+#@!?\s\u0080-\uFFFF]+)$
      example: HUB-00001
    ListHubsQueryNameFilter:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      allOf:
        - $ref: '#/components/schemas/ListHubsQueryFilter'
      additionalProperties: false
      properties:
        name:
          $ref: '#/components/schemas/HubNameProperty'
      required:
        - name
    HubSerialNumberProperty:
      type: string
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: The serial number of the Hub.
      maxLength: 64
      pattern: ^([a-zA-Z0-9-\s])+$
      example: 20240101-1-00000
    ListHubsQuerySerialNumberFilter:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      allOf:
        - $ref: '#/components/schemas/ListHubsQueryFilter'
      additionalProperties: false
      properties:
        serialNumber:
          $ref: '#/components/schemas/HubSerialNumberProperty'
      required:
        - serialNumber
    ListHubsQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: ListHubsAdminQuery
      description: Deprecated. Use the internal ListHubsAdminQuery Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubsQuery'
      additionalProperties: false
      properties:
        skip:
          $ref: '#/components/schemas/QuerySkip'
        limit:
          $ref: '#/components/schemas/QueryLimit'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListHubsQueryFilter'
      required:
        - skip
        - limit
    ListPagedHubsQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: ListHubsAdminQuery
      description: Deprecated. Use the internal ListHubsAdminQuery Graph query instead.
      allOf:
        - $ref: '#/components/schemas/HubsQuery'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryPage'
        pageSize:
          $ref: '#/components/schemas/QueryPageSize'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListHubsQueryFilter'
      required:
        - page
        - pageSize
    HubsQueryRequest:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Request object for hubs queries.
      additionalProperties: false
      properties:
        query:
          $ref: '#/components/schemas/HubsQuery'
      required:
        - query
    HubsQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Base type for all hubs query results.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          Cozify.Hubs/GetDetailsHubsQueryResult: '#/components/schemas/GetDetailsHubsQueryResult'
          Cozify.Hubs/GetEntryHubsQueryResult: '#/components/schemas/GetEntryHubsQueryResult'
          Cozify.Hubs/ListHubsQueryResult: '#/components/schemas/ListHubsQueryResult'
          Cozify.Hubs/ListPagedHubsQueryResult: '#/components/schemas/ListPagedHubsQueryResult'
      required:
        - type
    GetDetailsHubsQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query to get Hub details with given hub id.
      allOf:
        - $ref: '#/components/schemas/HubsQueryResult'
      additionalProperties: false
      properties:
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
        name:
          $ref: '#/components/schemas/HubNameProperty'
        serialNumber:
          $ref: '#/components/schemas/HubSerialNumberProperty'
        deviceRegisterToken:
          description: The device register token if Hub is connected to any.
          type: string
    HubEntry:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      additionalProperties: false
      properties:
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
        name:
          $ref: '#/components/schemas/HubNameProperty'
        serialNumber:
          $ref: '#/components/schemas/HubSerialNumberProperty'
        desiredVersion:
          description: The desired version of hub firmware.
          type: string
          maxLength: 16
          example: 1.1.1
        reportedVersion:
          description: The last reported version of hub firmware.
          type: string
          maxLength: 16
          example: 1.1.1
        model:
          description: The model of the hub.
          type: string
          maxLength: 64
      required:
        - createdAt
        - modifiedAt
        - hubId
        - name
        - serialNumber
        - desiredVersion
        - reportedVersion
        - model
    GetEntryHubsQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query to get Hub entry with given hub id.
      allOf:
        - $ref: '#/components/schemas/HubsQueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/HubEntry'
    ListHubsQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query for listing of hubs.
      allOf:
        - $ref: '#/components/schemas/HubsQueryResult'
      additionalProperties: false
      properties:
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        data:
          description: Contains the array of entries.
          type: array
          items:
            $ref: '#/components/schemas/HubEntry'
    ListPagedHubsQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Result of query for paged listing of hubs.
      allOf:
        - $ref: '#/components/schemas/HubsQueryResult'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryResultPage'
        pageSize:
          $ref: '#/components/schemas/QueryResultPageSize'
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        data:
          description: Contains the actual array of device entries for the current page.
          type: array
          items:
            $ref: '#/components/schemas/HubEntry'
    HubsQueryResponse:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: |
        Response object for query result.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/HubsQueryResult'
      required:
        - result
    DeviceRegisterCommand:
      type: object
      description: Base type for all device register commands.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/HubDeviceRegisterCommand: '#/components/schemas/HubDeviceRegisterCommand'
          Cozify.DeviceRegister/CreateEntryDeviceRegisterCommand: '#/components/schemas/CreateEntryDeviceRegisterCommand'
          Cozify.DeviceRegister/DeleteEntryDeviceRegisterCommand: '#/components/schemas/DeleteEntryDeviceRegisterCommand'
          Cozify.DeviceRegister/UpdateEntryDeviceRegisterCommand: '#/components/schemas/UpdateEntryDeviceRegisterCommand'
      required:
        - type
    HubDeviceRegisterCommand:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/command
      description: Deprecated. Use base Graph hub commands through /graph/command.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommand'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        command:
          $ref: '#/components/schemas/HubCommand'
      required:
        - deviceId
        - command
    RoutingEntry:
      type: object
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/HubRoutingEntry: '#/components/schemas/HubRoutingEntry'
          Cozify.DeviceRegister/DeviceRoutingEntry: '#/components/schemas/DeviceRoutingEntry'
      required:
        - type
    HubRoutingEntry:
      type: object
      allOf:
        - $ref: '#/components/schemas/RoutingEntry'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
      required:
        - hubId
    DeviceRoutingEntry:
      type: object
      allOf:
        - $ref: '#/components/schemas/RoutingEntry'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceId
    CreateEntryDeviceRegisterCommand:
      type: object
      description: Command to create device entry at device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommand'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        name:
          $ref: '#/components/schemas/DeviceName'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/RoutingEntry'
      required:
        - deviceId
        - deviceType
        - name
    DeleteEntryDeviceRegisterCommand:
      type: object
      description: Command to delete device entry from device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommand'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        recursive:
          type: boolean
          description: |
            If true, all child device entries will be also deleted. (default: is true)
          default: true
      required:
        - deviceId
    UpdateEntryDeviceRegisterCommand:
      type: object
      description: Command to update device entry at device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommand'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        name:
          $ref: '#/components/schemas/DeviceName'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/RoutingEntry'
      required:
        - deviceId
    DeviceRegisterCommandRequest:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Request object for device register commands.
      additionalProperties: false
      properties:
        command:
          $ref: '#/components/schemas/DeviceRegisterCommand'
      required:
        - command
    DeviceRegisterCommandResult:
      type: object
      description: Base type for all device register command results.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/HubDeviceRegisterCommandResult: '#/components/schemas/HubDeviceRegisterCommandResult'
          Cozify.DeviceRegister/CreateEntryDeviceRegisterCommandResult: '#/components/schemas/CreateEntryDeviceRegisterCommandResult'
          Cozify.DeviceRegister/DeleteEntryDeviceRegisterCommandResult: '#/components/schemas/DeleteEntryDeviceRegisterCommandResult'
          Cozify.DeviceRegister/UpdateEntryDeviceRegisterCommandResult: '#/components/schemas/UpdateEntryDeviceRegisterCommandResult'
      required:
        - type
    HubDeviceRegisterCommandResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph command results for hub operations.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommandResult'
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/HubCommandResult'
    DeviceRegisterEntry:
      type: object
      additionalProperties: false
      properties:
        createdAt:
          $ref: '#/components/schemas/CreatedAt'
        modifiedAt:
          $ref: '#/components/schemas/ModifiedAt'
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        deviceType:
          $ref: '#/components/schemas/DeviceType'
        name:
          $ref: '#/components/schemas/DeviceName'
        capabilities:
          description: The capabilities of the device.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
        tags:
          $ref: '#/components/schemas/Tags'
        gateway:
          $ref: '#/components/schemas/DeviceGateway'
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
        model:
          $ref: '#/components/schemas/DeviceModel'
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
        routing:
          $ref: '#/components/schemas/RoutingEntry'
        state:
          $ref: '#/components/schemas/DeviceState'
      required:
        - deviceId
        - deviceType
        - name
        - capabilities
        - tags
        - gateway
        - state
    CreateEntryDeviceRegisterCommandResult:
      type: object
      description: Result of command to create device entry at device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterEntry'
    DeleteEntryDeviceRegisterCommandResult:
      type: object
      description: Result of command to delete device entry from device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommandResult'
      additionalProperties: false
      properties:
        entries:
          description: Contains the array of device entries deleted from registry.
          type: array
          items:
            $ref: '#/components/schemas/DeviceRegisterEntry'
    UpdateEntryDeviceRegisterCommandResult:
      type: object
      description: Result of command to update device entry at device register.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterCommandResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterEntry'
    DeviceRegisterCommandResponse:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: |
        Response object for command result.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/DeviceRegisterCommandResult'
      required:
        - result
    DeviceRegisterQuery:
      type: object
      description: Base type for all device register queries.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/GetEntryDeviceRegisterQuery: '#/components/schemas/GetEntryDeviceRegisterQuery'
          Cozify.DeviceRegister/ListEntriesPagedDeviceRegisterQuery: '#/components/schemas/ListEntriesPagedDeviceRegisterQuery'
          Cozify.DeviceRegister/HubDeviceRegisterQuery: '#/components/schemas/HubDeviceRegisterQuery'
          Cozify.DeviceRegister/GetListEntriesColumnParamsDeviceRegisterQuery: '#/components/schemas/GetListEntriesColumnParamsDeviceRegisterQuery'
      required:
        - type
    GetEntryDeviceRegisterQuery:
      type: object
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQuery'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceId
    ListEntriesDeviceRegisterQueryFilter:
      type: object
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/KeywordFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryKeywordFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/NativeIdFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryNativeIdFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/SerialNumberFilter: '#/components/schemas/ListEntriesDeviceRegisterQuerySerialNumberFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/HubRoutingEntryFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryHubRoutingEntryFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/DeviceRoutingEntryFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryDeviceRoutingEntryFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/DeviceTypeFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryDeviceTypeFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/CapabilityFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryCapabilityFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/ManufacturerFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryManufacturerFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/ModelFilter: '#/components/schemas/ListEntriesDeviceRegisterQueryModelFilter'
          Cozify.DeviceRegister/ListEntriesDeviceRegisterQuery/SiteLinkFilter: '#/components/schemas/ListEntriesDeviceRegisterQuerySiteLinkFilter'
      required:
        - type
    ListEntriesDeviceRegisterQueryKeywordFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        keyword:
          description: The keyword to search for.
          type: string
          minLength: 2
      required:
        - keyword
    ListEntriesDeviceRegisterQueryNativeIdFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        nativeId:
          $ref: '#/components/schemas/DeviceNativeId'
      required:
        - nativeId
    ListEntriesDeviceRegisterQuerySerialNumberFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        serialNumber:
          $ref: '#/components/schemas/DeviceSerialNumber'
      required:
        - serialNumber
    ListEntriesDeviceRegisterQueryHubRoutingEntryFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        hubId:
          $ref: '#/components/schemas/HubIdProperty'
      required:
        - hubId
    ListEntriesDeviceRegisterQueryDeviceRoutingEntryFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
      required:
        - deviceId
    ListEntriesDeviceRegisterQueryDeviceTypeFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        deviceType:
          $ref: '#/components/schemas/DeviceType'
          example:
            - COZIFY_HUB
            - SIGNAL
            - MULTISENSOR
      required:
        - deviceType
    ListEntriesDeviceRegisterQueryCapabilityFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        capability:
          $ref: '#/components/schemas/Capability'
          example:
            - DEVICE
            - ON_OFF
            - TEMPERATURE
      required:
        - capability
    ListEntriesDeviceRegisterQueryManufacturerFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        manufacturer:
          $ref: '#/components/schemas/DeviceManufacturer'
          example:
            - Cozify Oy
            - My Cömpany Ltd.
      required:
        - manufacturer
    ListEntriesDeviceRegisterQueryModelFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        model:
          $ref: '#/components/schemas/DeviceModel'
          example:
            - ION
            - ZEN
            - DIN
            - Über IoT Device
      required:
        - model
    ListEntriesDeviceRegisterQuerySiteLinkFilter:
      type: object
      allOf:
        - $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      additionalProperties: false
      properties:
        siteId:
          description: |
            The identifier of the site to match.

            Use **NULL** to match entries without a site.
            Use '*' to match entries with any site.
          type: string
          pattern: ^(\*|.{2,})$
    ListEntriesPagedDeviceRegisterQuery:
      type: object
      description: Query for paged listing of device register entries.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQuery'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryPage'
        pageSize:
          $ref: '#/components/schemas/QueryPageSize'
        filters:
          description: Filters to apply to the query.
          type: array
          items:
            $ref: '#/components/schemas/ListEntriesDeviceRegisterQueryFilter'
      required:
        - page
        - pageSize
    HubDeviceRegisterQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: /graph/query
      description: Deprecated. Use base Graph hub queries through /graph/query.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQuery'
      additionalProperties: false
      properties:
        deviceId:
          $ref: '#/components/schemas/DeviceId'
        query:
          $ref: '#/components/schemas/HubQuery'
      required:
        - deviceId
        - query
    GetListEntriesColumnParamsDeviceRegisterQuery:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      x-replaced-by: GetDeviceRegisterEntryColumnsQuery
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQuery'
      additionalProperties: false
      properties:
        deviceType:
          description: Include array of known device types in the result.
          type: boolean
          default: false
          example: false
        capabilities:
          description: Include array of known device capabilities in the result.
          type: boolean
          default: false
          example: false
        manufacturer:
          description: Include array of known device manufacturers in the result.
          type: boolean
          default: false
          example: false
        model:
          description: Include array of known device models in the result.
          type: boolean
          default: false
          example: false
    DeviceRegisterQueryRequest:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Request object for device register queries.
      additionalProperties: false
      properties:
        query:
          $ref: '#/components/schemas/DeviceRegisterQuery'
      required:
        - query
    DeviceRegisterQueryResult:
      type: object
      description: Base type for all device register query results.
      additionalProperties: false
      properties:
        type:
          description: A discriminator to identify the type.
          type: string
        error:
          $ref: '#/components/schemas/GraphError'
      discriminator:
        propertyName: type
        mapping:
          Cozify.DeviceRegister/GetEntryDeviceRegisterQueryResult: '#/components/schemas/GetEntryDeviceRegisterQueryResult'
          Cozify.DeviceRegister/ListEntriesPagedDeviceRegisterQueryResult: '#/components/schemas/ListEntriesPagedDeviceRegisterQueryResult'
          Cozify.DeviceRegister/HubDeviceRegisterQueryResult: '#/components/schemas/HubDeviceRegisterQueryResult'
          Cozify.DeviceRegister/GetListEntriesColumnParamsDeviceRegisterQueryResult: '#/components/schemas/GetListEntriesColumnParamsDeviceRegisterQueryResult'
      required:
        - type
    GetEntryDeviceRegisterQueryResult:
      type: object
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQueryResult'
      additionalProperties: false
      properties:
        entry:
          $ref: '#/components/schemas/DeviceRegisterEntry'
    ListEntriesPagedDeviceRegisterQueryResult:
      type: object
      description: Result of query for paged listing of device register entries.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQueryResult'
      additionalProperties: false
      properties:
        page:
          $ref: '#/components/schemas/QueryResultPage'
        pageSize:
          $ref: '#/components/schemas/QueryResultPageSize'
        totalCount:
          $ref: '#/components/schemas/QueryTotalCount'
        data:
          description: Contains the actual array of device entries for the current page.
          type: array
          items:
            $ref: '#/components/schemas/DeviceRegisterEntry'
    HubDeviceRegisterQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: Deprecated. Use base Graph query results for hub operations.
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQueryResult'
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/HubQueryResult'
    GetListEntriesColumnParamsDeviceRegisterQueryResult:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      allOf:
        - $ref: '#/components/schemas/DeviceRegisterQueryResult'
      additionalProperties: false
      properties:
        deviceType:
          description: Include array of known device types in the result.
          type: array
          items:
            $ref: '#/components/schemas/DeviceType'
          example:
            - COZIFY_HUB
            - SIGNAL
            - MULTISENSOR
        capabilities:
          description: Include array of known device capabilities in the result.
          type: array
          items:
            $ref: '#/components/schemas/Capability'
          example:
            - DEVICE
            - ON_OFF
            - TEMPERATURE
        manufacturer:
          description: Include array of known device manufacturers in the result.
          type: array
          items:
            $ref: '#/components/schemas/DeviceManufacturer'
          example:
            - Cozify Oy
            - My Cömpany Ltd.
        model:
          description: Include array of known device models in the result.
          type: array
          items:
            $ref: '#/components/schemas/DeviceModel'
          example:
            - ION
            - ZEN
            - DIN
            - Über IoT Device
    DeviceRegisterQueryResponse:
      type: object
      deprecated: true
      x-deprecated-since: '3.0'
      x-sunset: '2026-12-31'
      description: |
        Response object for query result.
      additionalProperties: false
      properties:
        result:
          $ref: '#/components/schemas/DeviceRegisterQueryResult'
      required:
        - result
  responses:
    Problem:
      description: Problem
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: The request requires user authentication.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: The specified resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Problem'
  parameters:
    HubId:
      name: hubId
      in: path
      description: The identifier of the Cozify Hub.
      schema:
        $ref: '#/components/schemas/HubIdProperty'
      required: true
    DeviceRegisterId:
      name: deviceRegisterId
      in: path
      description: Globally unique device register identifier.
      schema:
        $ref: '#/components/schemas/DeviceRegisterId'
      required: true
