ThingsBoard Devices API

Provision, list, retrieve, update, assign, and delete IoT devices and device profiles. Includes device connectivity helpers and OTA package management for over-the-air firmware updates. 40 endpoints across device, device-profile, device-connectivity, and ota-package controllers.

ThingsBoard Devices API is one of 15 APIs that ThingsBoard publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 1 machine-runnable capability that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko and 2 JSON Schema definitions.

Tagged areas include IoT, Devices, Provisioning, and OTA. The published artifact set on APIs.io includes API documentation, an OpenAPI specification, 1 Naftiko capability spec, and 2 JSON Schemas.

OpenAPI Specification

thingsboard-devices-openapi.yml Raw ↑
# ThingsBoard ThingsBoard Devices API
# Source: https://demo.thingsboard.io/v3/api-docs (Apache 2.0)
openapi: 3.1.0
info:
  title: ThingsBoard Devices API
  description: "ThingsBoard Devices API \u2014 subset of the ThingsBoard REST API (open-source IoT platform). Covers: Device, Device Profile, Device Connectivity, Ota Package."
  version: 4.3.0.3DEMO
  contact:
    name: ThingsBoard team
    url: https://thingsboard.io
    email: [email protected]
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
servers:
- url: https://demo.thingsboard.io
  description: ThingsBoard Live Demo
- url: http://localhost:8080
  description: Local ThingsBoard server
tags:
- name: device-controller
  description: Device
- name: device-profile-controller
  description: Device Profile
- name: device-connectivity-controller
  description: Device Connectivity
- name: ota-package-controller
  description: Ota Package
paths:
  /api/tenant/{tenantId}/device/{deviceId}:
    post:
      tags:
      - device-controller
      summary: Assign Device to Tenant (assignDeviceToTenant)
      description: 'Creates assignment of the device to tenant. Thereafter tenant will be able to reassign the device to a customer.


        Available for users with ''TENANT_ADMIN'' authority.'
      operationId: assignDeviceToTenant
      parameters:
      - name: tenantId
        in: path
        description: A string value representing the tenant id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      - name: deviceId
        in: path
        description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
  /api/otaPackage:
    post:
      tags:
      - ota-package-controller
      summary: Create or Update OTA Package Info (saveOtaPackageInfo)
      description: "Create or update the OTA Package Info. When creating OTA Package Info, platform generates OTA Package id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)).\
        \ The newly created OTA Package id will be present in the response. Specify existing OTA Package id to update the OTA Package Info. Referencing non-existing OTA Package Id will cause 'Not Found'\
        \ error. \n\nOTA Package combination of the title with the version is unique in the scope of tenant. \n\nAvailable for users with 'TENANT_ADMIN' authority."
      operationId: saveOtaPackageInfo
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SaveOtaPackageInfoRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OtaPackageInfo'
  /api/otaPackage/{otaPackageId}:
    get:
      tags:
      - ota-package-controller
      summary: Get OTA Package (getOtaPackageById)
      description: "Fetch the OTA Package object based on the provided OTA Package Id. The server checks that the OTA Package is owned by the same tenant. OTA Package is a heavyweight object that includes\
        \ main information about the OTA Package and also data. \n\nAvailable for users with 'TENANT_ADMIN' authority."
      operationId: getOtaPackageById
      parameters:
      - name: otaPackageId
        in: path
        description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OtaPackage'
    post:
      tags:
      - ota-package-controller
      summary: Save OTA Package Data (saveOtaPackageData)
      description: 'Update the OTA Package. Adds the date to the existing OTA Package Info


        Available for users with ''TENANT_ADMIN'' authority.'
      operationId: saveOtaPackageData
      parameters:
      - name: otaPackageId
        in: path
        description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      - name: checksum
        in: query
        description: OTA Package checksum. For example, '0xd87f7e0c'
        required: false
        schema:
          type: string
      - name: checksumAlgorithm
        in: query
        description: OTA Package checksum algorithm.
        required: true
        schema:
          type: string
          enum:
          - MD5
          - SHA256
          - SHA384
          - SHA512
          - CRC32
          - MURMUR3_32
          - MURMUR3_128
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: OTA Package data.
              required:
              - file
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OtaPackageInfo'
    delete:
      tags:
      - ota-package-controller
      summary: Delete OTA Package (deleteOtaPackage)
      description: 'Deletes the OTA Package. Referencing non-existing OTA Package Id will cause an error. Can''t delete the OTA Package if it is referenced by existing devices or device profile.


        Available for users with ''TENANT_ADMIN'' authority.'
      operationId: deleteOtaPackage
      parameters:
      - name: otaPackageId
        in: path
        description: A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
  /api/edge/{edgeId}/device/{deviceId}:
    post:
      tags:
      - device-controller
      summary: Assign Device to Edge (assignDeviceToEdge)
      description: 'Creates assignment of an existing device to an instance of The Edge. Assignment works in async way - first, notification event pushed to edge service queue on platform. Second, remote
        edge service will receive a copy of assignment device (Edge will receive this instantly, if it''s currently connected, or once it''s going to be connected to platform). Third, once device will be
        delivered to edge service, it''s going to be available for usage on remote edge instance.


        Available for users with ''TENANT_ADMIN'' authority.'
      operationId: assignDeviceToEdge
      parameters:
      - name: edgeId
        in: path
        description: A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      - name: deviceId
        in: path
        description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
    delete:
      tags:
      - device-controller
      summary: Unassign Device from Edge (unassignDeviceFromEdge)
      description: 'Clears assignment of the device to the edge. Unassignment works in async way - first, ''unassign'' notification event pushed to edge queue on platform. Second, remote edge service will
        receive an ''unassign'' command to remove device (Edge will receive this instantly, if it''s currently connected, or once it''s going to be connected to platform). Third, once ''unassign'' command
        will be delivered to edge service, it''s going to remove device locally.


        Available for users with ''TENANT_ADMIN'' authority.'
      operationId: unassignDeviceFromEdge
      parameters:
      - name: edgeId
        in: path
        description: A string value representing the edge id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      - name: deviceId
        in: path
        description: A string value representing the device id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
  /api/devices:
    get:
      tags:
      - device-controller
      summary: Get Devices by Ids (getDevicesByIds)
      description: "Requested devices must be owned by tenant or assigned to customer which user is performing the request. \n\nAvailable for users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority."
      operationId: getDevicesByIds
      parameters:
      - name: deviceIds
        in: query
        description: A list of devices ids, separated by comma ','
        required: true
        schema:
          type: array
          items:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Device'
    post:
      tags:
      - device-controller
      summary: Find Related Devices (findByQuery)
      description: 'Returns all devices that are related to the specific entity. The entity id, relation type, device types, depth of the search, and other query parameters defined using complex ''DeviceSearchQuery''
        object. See ''Model'' tab of the Parameters for more info.


        Available for users with ''TENANT_ADMIN'' or ''CUSTOMER_USER'' authority.'
      operationId: findByQuery_3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceSearchQuery'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Device'
  /api/device:
    post:
      tags:
      - device-controller
      summary: Create or Update Device (saveDevice)
      description: "Create or update the Device. When creating device, platform generates Device Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)).\
        \ Device credentials are also generated if not provided in the 'accessToken' request parameter. The newly created device id will be present in the response. Specify existing Device id to update\
        \ the device. Referencing non-existing device Id will cause 'Not Found' error.\n\nDevice name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the device names and non-unique\
        \ 'label' field for user-friendly visualization purposes.Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. \n\nAvailable for\
        \ users with 'TENANT_ADMIN' or 'CUSTOMER_USER' authority."
      operationId: saveDevice
      parameters:
      - name: accessToken
        in: query
        description: Optional value of the device credentials to be used during device creation. If omitted, access token will be auto-generated.
        required: false
        schema:
          type: string
      - name: nameConflictPolicy
        in: query
        description: 'Optional value of name conflict policy. Possible values: FAIL or UNIQUIFY.  If omitted, FAIL policy is applied. FAIL policy implies exception will be thrown if an entity with the same
          name already exists.  UNIQUIFY policy appends a suffix to the entity name, if a name conflict occurs.'
        required: false
        schema:
          type: string
          default: FAIL
          enum:
          - FAIL
          - UNIQUIFY
      - name: uniquifySeparator
        in: query
        description: Optional value of name suffix separator used by UNIQUIFY policy. By default, underscore separator is used. For example, strategy is UNIQUIFY, separator is '-'; if a name conflict occurs
          for entity name 'test-name', created entity will have name like 'test-name-7fsh4f'.
        required: false
        schema:
          type: string
          default: _
      - name: uniquifyStrategy
        in: query
        description: 'Optional value of uniquify strategy used by UNIQUIFY policy. Possible values: RANDOM or INCREMENTAL. By default, RANDOM strategy is used, which means random alphanumeric string will
          be added as a suffix to entity name. INCREMENTAL implies the first possible number starting from 1 will be added as a name suffix. For example, strategy is UNIQUIFY, uniquify strategy is INCREMENTAL;
          if a name conflict occurs for entity name ''test-name'', created entity will have name like ''test-name-1.'
        required: false
        schema:
          type: string
          default: RANDOM
          enum:
          - RANDOM
          - INCREMENTAL
      requestBody:
        description: A JSON value representing the device.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Device'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
  /api/deviceProfile:
    post:
      tags:
      - device-profile-controller
      summary: Create or Update Device Profile (saveDeviceProfile)
      description: "Create or update the Device Profile. When creating device profile, platform generates device profile id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)).\
        \ The newly created device profile id will be present in the response. Specify existing device profile id to update the device profile. Referencing non-existing device profile Id will cause 'Not\
        \ Found' error. \n\nDevice profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant.\n\n# Device profile data definition\n\nDevice profile data\
        \ object contains alarm rules configuration, device provision strategy and transport type configuration for device connectivity. Let's review some examples. First one is the default device profile\
        \ data configuration and second one - the custom one. \n\n```json\n{\n   \"alarms\":[\n   ],\n   \"configuration\":{\n      \"type\":\"DEFAULT\"\n   },\n   \"provisionConfiguration\":{\n      \"\
        type\":\"DISABLED\",\n      \"provisionDeviceSecret\":null\n   },\n   \"transportConfiguration\":{\n      \"type\":\"DEFAULT\"\n   }\n}\n```\n\n```json\n{\n   \"alarms\":[\n      {\n         \"\
        id\":\"2492b935-1226-59e9-8615-17d8978a4f93\",\n         \"alarmType\":\"Temperature Alarm\",\n         \"clearRule\":{\n            \"schedule\":null,\n            \"condition\":{\n           \
        \    \"spec\":{\n                  \"type\":\"SIMPLE\"\n               },\n               \"condition\":[\n                  {\n                     \"key\":{\n                        \"key\":\"\
        temperature\",\n                        \"type\":\"TIME_SERIES\"\n                     },\n                     \"value\":null,\n                     \"predicate\":{\n                        \"\
        type\":\"NUMERIC\",\n                        \"value\":{\n                           \"userValue\":null,\n                           \"defaultValue\":30.0,\n                           \"dynamicValue\"\
        :null\n                        },\n                        \"operation\":\"LESS\"\n                     },\n                     \"valueType\":\"NUMERIC\"\n                  }\n               ]\n\
        \            },\n            \"dashboardId\":null,\n            \"alarmDetails\":null\n         },\n         \"propagate\":false,\n         \"createRules\":{\n            \"MAJOR\":{\n         \
        \      \"schedule\":{\n                  \"type\":\"SPECIFIC_TIME\",\n                  \"endsOn\":64800000,\n                  \"startsOn\":43200000,\n                  \"timezone\":\"Europe/Kiev\"\
        ,\n                  \"daysOfWeek\":[\n                     1,\n                     3,\n                     5\n                  ]\n               },\n               \"condition\":{\n        \
        \          \"spec\":{\n                     \"type\":\"DURATION\",\n                     \"unit\":\"MINUTES\",\n                     \"predicate\":{\n                        \"userValue\":null,\n\
        \                        \"defaultValue\":30,\n                        \"dynamicValue\":null\n                     }\n                  },\n                  \"condition\":[\n                  \
        \   {\n                        \"key\":{\n                           \"key\":\"temperature\",\n                           \"type\":\"TIME_SERIES\"\n                        },\n                 \
        \       \"value\":null,\n                        \"predicate\":{\n                           \"type\":\"COMPLEX\",\n                           \"operation\":\"OR\",\n                           \"\
        predicates\":[\n                              {\n                                 \"type\":\"NUMERIC\",\n                                 \"value\":{\n                                    \"userValue\"\
        :null,\n                                    \"defaultValue\":50.0,\n                                    \"dynamicValue\":null\n                                 },\n                             \
        \    \"operation\":\"LESS_OR_EQUAL\"\n                              },\n                              {\n                                 \"type\":\"NUMERIC\",\n                                \
        \ \"value\":{\n                                    \"userValue\":null,\n                                    \"defaultValue\":30.0,\n                                    \"dynamicValue\":null\n  \
        \                               },\n                                 \"operation\":\"GREATER\"\n                              }\n                           ]\n                        },\n      \
        \                  \"valueType\":\"NUMERIC\"\n                     }\n                  ]\n               },\n               \"dashboardId\":null,\n               \"alarmDetails\":null\n       \
        \     },\n            \"WARNING\":{\n               \"schedule\":{\n                  \"type\":\"CUSTOM\",\n                  \"items\":[\n                     {\n                        \"endsOn\"\
        :0,\n                        \"enabled\":false,\n                        \"startsOn\":0,\n                        \"dayOfWeek\":1\n                     },\n                     {\n             \
        \           \"endsOn\":64800000,\n                        \"enabled\":true,\n                        \"startsOn\":43200000,\n                        \"dayOfWeek\":2\n                     },\n  \
        \                   {\n                        \"endsOn\":0,\n                        \"enabled\":false,\n                        \"startsOn\":0,\n                        \"dayOfWeek\":3\n     \
        \                },\n                     {\n                        \"endsOn\":57600000,\n                        \"enabled\":true,\n                        \"startsOn\":36000000,\n           \
        \             \"dayOfWeek\":4\n                     },\n                     {\n                        \"endsOn\":0,\n                        \"enabled\":false,\n                        \"startsOn\"\
        :0,\n                        \"dayOfWeek\":5\n                     },\n                     {\n                        \"endsOn\":0,\n                        \"enabled\":false,\n               \
        \         \"startsOn\":0,\n                        \"dayOfWeek\":6\n                     },\n                     {\n                        \"endsOn\":0,\n                        \"enabled\":false,\n\
        \                        \"startsOn\":0,\n                        \"dayOfWeek\":7\n                     }\n                  ],\n                  \"timezone\":\"Europe/Kiev\"\n               },\n\
        \               \"condition\":{\n                  \"spec\":{\n                     \"type\":\"REPEATING\",\n                     \"predicate\":{\n                        \"userValue\":null,\n \
        \                       \"defaultValue\":5,\n                        \"dynamicValue\":null\n                     }\n                  },\n                  \"condition\":[\n                    \
        \ {\n                        \"key\":{\n                           \"key\":\"tempConstant\",\n                           \"type\":\"CONSTANT\"\n                        },\n                     \
        \   \"value\":30,\n                        \"predicate\":{\n                           \"type\":\"NUMERIC\",\n                           \"value\":{\n                              \"userValue\"\
        :null,\n                              \"defaultValue\":0.0,\n                              \"dynamicValue\":{\n                                 \"inherit\":false,\n                             \
        \    \"sourceType\":\"CURRENT_DEVICE\",\n                                 \"sourceAttribute\":\"tempThreshold\"\n                              }\n                           },\n                \
        \           \"operation\":\"EQUAL\"\n                        },\n                        \"valueType\":\"NUMERIC\"\n                     }\n                  ]\n               },\n             \
        \  \"dashboardId\":null,\n               \"alarmDetails\":null\n            },\n            \"CRITICAL\":{\n               \"schedule\":null,\n               \"condition\":{\n                  \"\
        spec\":{\n                     \"type\":\"SIMPLE\"\n                  },\n                  \"condition\":[\n                     {\n                        \"key\":{\n                         \
        \  \"key\":\"temperature\",\n                           \"type\":\"TIME_SERIES\"\n                        },\n                        \"value\":null,\n                        \"predicate\":{\n \
        \                          \"type\":\"NUMERIC\",\n                           \"value\":{\n                              \"userValue\":null,\n                              \"defaultValue\":50.0,\n\
        \                              \"dynamicValue\":null\n                           },\n                           \"operation\":\"GREATER\"\n                        },\n                        \"\
        valueType\":\"NUMERIC\"\n                     }\n                  ]\n               },\n               \"dashboardId\":null,\n               \"alarmDetails\":null\n            }\n         },\n\
        \         \"propagateRelationTypes\":null\n      }\n   ],\n   \"configuration\":{\n      \"type\":\"DEFAULT\"\n   },\n   \"provisionConfiguration\":{\n      \"type\":\"ALLOW_CREATE_NEW_DEVICES\"\
        ,\n      \"provisionDeviceSecret\":\"vaxb9hzqdbz3oqukvomg\"\n   },\n   \"transportConfiguration\":{\n      \"type\":\"MQTT\",\n      \"deviceTelemetryTopic\":\"v1/devices/me/telemetry\",\n     \
        \ \"deviceAttributesTopic\":\"v1/devices/me/attributes\",\n      \"transportPayloadTypeConfiguration\":{\n         \"transportPayloadType\":\"PROTOBUF\",\n         \"deviceTelemetryProtoSchema\"\
        :\"syntax =\\\"proto3\\\";\\npackage telemetry;\\n\\nmessage SensorDataReading {\\n\\n  optional double temperature = 1;\\n  optional double humidity = 2;\\n  InnerObject innerObject = 3;\\n\\n\
        \  message InnerObject {\\n    optional string key1 = 1;\\n    optional bool key2 = 2;\\n    optional double key3 = 3;\\n    optional int32 key4 = 4;\\n    optional string key5 = 5;\\n  }\\n}\"\
        ,\n         \"deviceAttributesProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage attributes;\\n\\nmessage SensorConfiguration {\\n  optional string firmwareVersion = 1;\\n  optional string serialNumber\
        \ = 2;\\n}\",\n         \"deviceRpcRequestProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcRequestMsg {\\n  optional string method = 1;\\n  optional int32 requestId = 2;\\\
        n  optional string params = 3;\\n}\",\n         \"deviceRpcResponseProtoSchema\":\"syntax =\\\"proto3\\\";\\npackage rpc;\\n\\nmessage RpcResponseMsg {\\n  optional string payload = 1;\\n}\"\n \
        \     }\n   }\n}\n```\n\nLet's review some specific objects examples related to the device profile configuration:\n\n# Alarm Schedule\n\nAlarm Schedule JSON object represents the time interval during\
        \ which the alarm rule is active. Note, \n\n```json\n\"schedule\": null\n```\n\nmeans alarm rule is active all the time. **'daysOfWeek'** field represents Monday as 1, Tuesday as 2 and so on. **'startsOn'**\
        \ and **'endsOn'** fields represent hours in millis (e.g. 64800000 = 18:00 or 6pm). **'enabled'** flag specifies if item in a custom rule is active for specific day of the week:\n\n## Specific Time\
        \ Schedule\n\n```json\n{\n   \"schedule\":{\n      \"type\":\"SPECIFIC_TIME\",\n      \"endsOn\":64800000,\n      \"startsOn\":43200000,\n      \"timezone\":\"Europe/Kiev\",\n      \"daysOfWeek\"\
        :[\n         1,\n         3,\n         5\n      ]\n   }\n}\n```\n\n## Custom Schedule\n\n```json\n{\n   \"schedule\":{\n      \"type\":\"CUSTOM\",\n      \"items\":[\n         {\n            \"\
        endsOn\":0,\n            \"enabled\":false,\n            \"startsOn\":0,\n            \"dayOfWeek\":1\n         },\n         {\n            \"endsOn\":64800000,\n            \"enabled\":true,\n\
        \            \"startsOn\":43200000,\n            \"dayOfWeek\":2\n         },\n         {\n            \"endsOn\":0,\n            \"enabled\":false,\n            \"startsOn\":0,\n            \"\
        dayOfWeek\":3\n         },\n         {\n            \"endsOn\":57600000,\n            \"enabled\":true,\n            \"startsOn\":36000000,\n            \"dayOfWeek\":4\n         },\n         {\n\
        \            \"endsOn\":0,\n            \"enabled\":false,\n            \"startsOn\":0,\n            \"dayOfWeek\":5\n         },\n         {\n            \"endsOn\":0,\n            \"enabled\"\
        :false,\n            \"startsOn\":0,\n            \"dayOfWeek\":6\n         },\n         {\n            \"endsOn\":0,\n            \"enabled\":false,\n            \"startsOn\":0,\n            \"\
        dayOfWeek\":7\n         }\n      ],\n      \"timezone\":\"Europe/Kiev\"\n   }\n}\n```\n\n# Alarm condition type (**'spec'**)\n\nAlarm condition type can be either simple, duration, or repeating.\
        \ For example, 5 times in a row or during 5 minutes.\n\nNote, **'userValue'** field is not used and reserved for future usage, **'dynamicValue'** is used for condition appliance by using the value\
        \ of the **'sourceAttribute'** or else **'defaultValue'** is used (if **'sourceAttribute'** is absent).\n\n**'sourceType'** of the **'sourceAttribute'** can be: \n * 'CURRENT_DEVICE';\n * 'CURRENT_CUSTOMER';\n\
        \ * 'CURRENT_TENANT'.\n\n**'sourceAttribute'** can be inherited from the owner if **'inherit'** is set to true (for CURRENT_DEVICE and CURRENT_CUSTOMER).\n\n## Repeating alarm condition\n\n```json\n\
        {\n   \"spec\":{\n      \"type\":\"REPEATING\",\n      \"predicate\":{\n         \"userValue\":null,\n         \"defaultValue\":5,\n         \"dynamicValue\":{\n            \"inherit\":true,\n \
        \           \"sourceType\":\"CURRENT_DEVICE\",\n            \"sourceAttribute\":\"tempAttr\"\n         }\n      }\n   }\n}\n```\n\n## Duration alarm condition\n\n```json\n{\n   \"spec\":{\n    \
        \  \"type\":\"DURATION\",\n      \"unit\":\"MINUTES\",\n      \"predicate\":{\n         \"userValue\":null,\n         \"defaultValue\":30,\n         \"dynamicValue\":null\n      }\n   }\n}\n```\n\
        \n**'unit'** can be: \n * 'SECONDS';\n * 'MINUTES';\n * 'HOURS';\n * 'DAYS'.\n\n# Key Filters\n\nKey filter objects are created under the **'condition'** array. They allow you to define complex\
        \ logical expressions over entity field, attribute, latest time series value or constant. The filter is defined using 'key', 'valueType', 'value' (refers to the value of the 'CONSTANT' alarm filter\
        \ key type) and 'predicate' objects. Let's review each object:\n\n## Alarm Filter Key\n\nFilter Key defines either entity field, attribute, telemetry or constant. It is a JSON object that consists\
        \ the key name and type. The following filter key types are supported:\n * 'ATTRIBUTE' - used for attributes values;\n * 'TIME_SERIES' - used for time series values;\n * 'ENTITY_FIELD' - used for\
        \ accessing entity fields like 'name', 'label', etc. The list of available fields depends on the entity type;\n * 'CONSTANT' - constant value specified.\n\nLet's review the example:\n\n```json\n\
        {\n  \"type\": \"TIME_SERIES\",\n  \"key\": \"temperature\"\n}\n```\n\n## Value Type and Operations\n\nProvides a hint about the data type of the entity field that is defined in the filter key.\
        \ The value type impacts the list of possible operations that you may use in the corresponding predicate. For example, you may use 'STARTS_WITH' or 'END_WITH', but you can't use 'GREATER_OR_EQUAL'\
        \ for string values.The following filter value types and corresponding predicate operations are supported: \n\n * 'STRING' - used to filter any 'String' or 'JSON' values. Operations: EQUAL, NOT_EQUAL,\
        \ STARTS_WITH, ENDS_WITH, CONTAINS, NOT_CONTAINS; \n * 'NUMERIC' - used for 'Long' and 'Double' values. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL; \n * 'BOOLEAN'\
        \ - used for boolean values. Operations: EQUAL, NOT_EQUAL;\n * 'DATE_TIME' - similar to numeric, transforms value to milliseconds since epoch. Operations: EQUAL, NOT_EQUAL, GREATER, LESS, GREATER_OR_EQUAL,\
        \ LESS_OR_EQUAL; \n\n\n\n\n## Filter Predicate\n\nFilter Predicate defines the logical expression to evaluate. The list of available operations depends on the filter value type, see above. Platform\
        \ supports 4 predicate types: 'STRING', 'NUMERIC', 'BOOLEAN' and 'COMPLEX'. The last one allows to combine multiple operations over one filter key.\n\nSimple predicate example to check 'value <\
        \ 100': \n\n```json\n{\n  \"operation\": \"LESS\",\n  \"value\": {\n    \"userValue\": null,\n    \"defaultValue\": 100,\n    \"dynamicValue\": null\n  },\n  \"type\": \"NUMERIC\"\n}\n```\n\nComplex\
        \ predicate example, to check 'value < 10 or value > 20': \n\n```json\n{\n  \"type\": \"COMPLEX\",\n  \"operation\": \"OR\",\n  \"predicates\": [\n    {\n      \"operation\": \"LESS\",\n      \"\
        value\": {\n        \"userValue\": null,\n        \"defaultValue\": 10,\n        \"dynamicValue\": null\n      },\n      \"type\": \"NUMERIC\"\n    },\n    {\n      \"operation\": \"GREATER\",\n\
        \      \"value\": {\n        \"userValue\": null,\n        \"defaultValue\": 20,\n        \"dynamicValue\": null\n      },\n      \"type\": \"NUMERIC\"\n    }\n  ]\n}\n```\n\nMore complex predicate\
        \ example, to check 'value < 10 or (value > 50 && value < 60)': \n\n```json\n{\n  \"type\": \"COMPLEX\",\n  \"operation\": \"OR\",\n  \"predicates\": [\n    {\n      \"operation\": \"LESS\",\n \
        \     \"value\": {\n        \"userValue\": null,\n        \"defaultValue\": 10,\n        \"dynamicValue\": null\n      },\n      \"type\": \"NUMERIC\"\n    },\n    {\n      \"type\": \"COMPLEX\"\
        ,\n      \"operation\": \"AND\",\n      \"predicates\": [\n        {\n          \"operation\": \"GREATER\",\n          \"value\": {\n            \"userValue\": null,\n    

# --- truncated at 32 KB (179 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/thingsboard/refs/heads/main/openapi/thingsboard-devices-openapi.yml