diff --git a/public/resources/docs/reference/gateway-api/mqtt-js-gateway-attributes-request.js b/public/resources/docs/reference/gateway-api/mqtt-js-gateway-attributes-request.js
new file mode 100644
index 0000000000..ff673bc3ed
--- /dev/null
+++ b/public/resources/docs/reference/gateway-api/mqtt-js-gateway-attributes-request.js
@@ -0,0 +1,19 @@
+var mqtt = require('mqtt');
+var client = mqtt.connect('mqtt://localhost', {
+ username: process.env.TOKEN
+});
+
+client.on('connect', function () {
+ console.log('connected');
+ client.subscribe('v1/gateway/attributes/response');
+ // clientKeys/sharedKeys are comma-separated strings. An empty value returns
+ // ALL keys in that scope, e.g. sharedKeys: "". Omit a field to exclude a scope.
+ var request = { id: 1, device: 'Device A', clientKeys: 'fw_version,battery', sharedKeys: 'targetFwVersion' };
+ client.publish('v1/gateway/attributes/request', JSON.stringify(request));
+});
+
+client.on('message', function (topic, message) {
+ console.log('response.topic: ' + topic);
+ console.log('response.body: ' + message.toString());
+ client.end();
+});
diff --git a/public/resources/docs/reference/mqtt-api/mqtt-js-attributes-request.js b/public/resources/docs/reference/mqtt-api/mqtt-js-attributes-request.js
new file mode 100644
index 0000000000..584f88e91f
--- /dev/null
+++ b/public/resources/docs/reference/mqtt-api/mqtt-js-attributes-request.js
@@ -0,0 +1,20 @@
+var mqtt = require('mqtt');
+var client = mqtt.connect('mqtt://localhost', {
+ username: process.env.TOKEN
+});
+var requestId = 1;
+
+client.on('connect', function () {
+ console.log('connected');
+ client.subscribe('v1/devices/me/attributes/response/+');
+ // Specify keys as comma-separated strings. An empty value returns ALL keys
+ // in that scope, e.g. sharedKeys: "". Omit a field to exclude that scope.
+ var request = { clientKeys: 'firmwareVersion,serialNumber', sharedKeys: 'targetTemperature,enabled' };
+ client.publish('v1/devices/me/attributes/request/' + requestId, JSON.stringify(request));
+});
+
+client.on('message', function (topic, message) {
+ console.log('response.topic: ' + topic);
+ console.log('response.body: ' + message.toString());
+ client.end();
+});
diff --git a/src/content/_includes/docs/edge/reference/apis-and-sdks/coap-api.mdx b/src/content/_includes/docs/edge/reference/apis-and-sdks/coap-api.mdx
index 67ff5dd58e..d9342350ea 100644
--- a/src/content/_includes/docs/edge/reference/apis-and-sdks/coap-api.mdx
+++ b/src/content/_includes/docs/edge/reference/apis-and-sdks/coap-api.mdx
@@ -29,7 +29,7 @@ Base URL: `coap://{EDGE_HOST}/api/v1/{accessToken}`
|-----------|--------|------|
| Publish telemetry | POST | `/telemetry` |
| Publish client-side attributes | POST | `/attributes` |
-| Get attributes | GET | `/attributes?clientKeys=…&sharedKeys=…` |
+| Get attributes | GET | `/attributes?clientKeys=…&sharedKeys=…` (or `allClientKeys=true` / `allSharedKeys=true`) |
| Subscribe to shared attribute updates | GET + Observe | `/attributes/updates` |
| Subscribe to server-side RPC | GET + Observe | `/rpc` |
| Respond to server-side RPC | POST | `/rpc/{requestId}` |
@@ -82,14 +82,23 @@ coap-client -m post \
-e '{"firmware_version": "1.2.0", "serial": "SN-001"}'
```
-Get client and shared attributes:
+Read client-side and/or shared attributes. The response groups results by scope: `{"client": {...}, "shared": {...}}`. Choose which attributes to return with these query parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| `clientKeys` | Comma-separated list of client-side attribute keys to return |
+| `sharedKeys` | Comma-separated list of shared attribute keys to return |
+| `allClientKeys` | Set to `true` to return all client-side attributes (overrides `clientKeys`) |
+| `allSharedKeys` | Set to `true` to return all shared attributes (overrides `sharedKeys`) |
+
+**Example:**
```bash
coap-client -m get \
"coap://$EDGE_HOST/api/v1/$ACCESS_TOKEN/attributes?clientKeys=serial&sharedKeys=firmware_version"
```
-Response example:
+**Response:**
```json
{"client": {"serial": "SN-001"}, "shared": {"firmware_version": "1.2.0"}}
diff --git a/src/content/_includes/docs/edge/reference/apis-and-sdks/gateway-mqtt-api.mdx b/src/content/_includes/docs/edge/reference/apis-and-sdks/gateway-mqtt-api.mdx
index 7d39fdc469..2c0dc4f841 100644
--- a/src/content/_includes/docs/edge/reference/apis-and-sdks/gateway-mqtt-api.mdx
+++ b/src/content/_includes/docs/edge/reference/apis-and-sdks/gateway-mqtt-api.mdx
@@ -153,27 +153,72 @@ mosquitto_pub -h "$EDGE_HOST" -t "v1/gateway/attributes" \
### Request attribute values
-Subscribe to the response topic first, then publish the request.
+Subscribe to the response topic first, then publish the request. Because subscribing and publishing must happen in the same MQTT session, this cannot be shown with `mosquitto_pub`/`mosquitto_sub` as two separate commands. Use a script instead.
**Subscribe topic:** `v1/gateway/attributes/response`
**Publish topic:** `v1/gateway/attributes/request`
-**Payload:**
+**Request payload:**
```json
{
"id": 1,
"device": "Device A",
- "client": ["key1", "key2"],
- "shared": ["key3", "key4"]
+ "clientKeys": "fw_version,battery",
+ "sharedKeys": "targetFwVersion"
}
```
-- **id** — required. Integer request identifier. The response includes the same `id`.
+- **id** — required. Integer request identifier. The response echoes the same `id`.
- **device** — required. The device name in ThingsBoard.
-- **client** — optional. Client-side attribute keys to retrieve.
-- **shared** — optional. Shared attribute keys to retrieve.
+- **clientKeys** — optional. Comma-separated client-side attribute keys. Set to `""` (empty string) to retrieve all client-side attributes. Omit to exclude client attributes from the response.
+- **sharedKeys** — optional. Comma-separated shared attribute keys. Set to `""` (empty string) to retrieve all shared attributes. Omit to exclude shared attributes from the response.
+
+
+
+Omitting **both** `clientKeys` and `sharedKeys` (sending only `id` and `device`) returns **all** client and **all** shared attributes in a single scope-separated response.
+
+**Response payload:**
+
+```json
+{
+ "id": 1,
+ "device": "Device A",
+ "client": {"fw_version": "1.0", "battery": 87},
+ "shared": {"targetFwVersion": "2.0"}
+}
+```
+
+The response is scope-separated: `client` contains client-side attributes, `shared` contains shared attributes. A scope key is omitted from the response if it was not requested.
+
+**Example (Node.js / mqtt.js):**
+
+```js
+const mqtt = require('mqtt');
+const client = mqtt.connect('mqtt://$EDGE_HOST', { username: '$ACCESS_TOKEN' });
+
+client.on('connect', () => {
+ client.subscribe('v1/gateway/attributes/response', () => {
+ client.publish(
+ 'v1/gateway/attributes/request',
+ JSON.stringify({
+ id: 1,
+ device: 'Device A',
+ clientKeys: 'fw_version,battery',
+ sharedKeys: 'targetFwVersion',
+ })
+ );
+ });
+});
+
+client.on('message', (_topic, message) => {
+ console.log(message.toString());
+ client.end();
+});
+```
### Subscribe to attribute updates
diff --git a/src/content/_includes/docs/edge/reference/apis-and-sdks/http-api.mdx b/src/content/_includes/docs/edge/reference/apis-and-sdks/http-api.mdx
index 732a24399e..e2e66a55d0 100644
--- a/src/content/_includes/docs/edge/reference/apis-and-sdks/http-api.mdx
+++ b/src/content/_includes/docs/edge/reference/apis-and-sdks/http-api.mdx
@@ -30,7 +30,7 @@ Base URL: `http://{EDGE_HOST}:8080/api/v1/{accessToken}`
|-----------|--------|------|
| Publish telemetry | POST | `/telemetry` |
| Publish client-side attributes | POST | `/attributes` |
-| Get attributes | GET | `/attributes?clientKeys=…&sharedKeys=…` |
+| Get attributes | GET | `/attributes?clientKeys=…&sharedKeys=…` (or `allClientKeys=true` / `allSharedKeys=true`) |
| Subscribe to shared attribute updates (long-poll) | GET | `/attributes/updates?timeout={ms}` |
| Subscribe to RPC commands (long-poll) | GET | `/rpc?timeout={ms}` |
| Respond to server-side RPC | POST | `/rpc/{requestId}` |
@@ -64,12 +64,23 @@ curl -v -X POST \
+Read client-side and/or shared attributes. The response groups results by scope: `{"client": {...}, "shared": {...}}`. Choose which attributes to return with these query parameters:
+
+| Parameter | Description |
+|-----------|-------------|
+| `clientKeys` | Comma-separated list of client-side attribute keys to return |
+| `sharedKeys` | Comma-separated list of shared attribute keys to return |
+| `allClientKeys` | Set to `true` to return all client-side attributes (overrides `clientKeys`) |
+| `allSharedKeys` | Set to `true` to return all shared attributes (overrides `sharedKeys`) |
+
+**Example:**
+
```bash
curl -v \
"http://$EDGE_HOST:8080/api/v1/$ACCESS_TOKEN/attributes?clientKeys=serial&sharedKeys=firmware_version"
```
-Response example:
+**Response:**
```json
{"client": {"serial": "SN-001"}, "shared": {"firmware_version": "1.2.0"}}
diff --git a/src/content/_includes/docs/edge/reference/apis-and-sdks/mqtt-api.mdx b/src/content/_includes/docs/edge/reference/apis-and-sdks/mqtt-api.mdx
index d8ed0b9f0d..2ffeaa77e2 100644
--- a/src/content/_includes/docs/edge/reference/apis-and-sdks/mqtt-api.mdx
+++ b/src/content/_includes/docs/edge/reference/apis-and-sdks/mqtt-api.mdx
@@ -130,6 +130,13 @@ Subscribe to `v1/devices/me/attributes/response/+`, then publish to `v1/devices/
{"clientKeys": "attribute1,attribute2", "sharedKeys": "shared1,shared2"}
```
+| Field | Description |
+|-------|-------------|
+| `clientKeys` | Comma-separated client-side attribute keys to return; `""` returns all client attributes; omit to exclude the client scope |
+| `sharedKeys` | Comma-separated shared attribute keys to return; `""` returns all shared attributes; omit to exclude the shared scope |
+
+An empty request body (`{}`) returns all client and all shared attributes.
+
The following example uses MQTT.js because subscribe and publish must happen in the same session:
```js
@@ -156,6 +163,32 @@ Response example:
{"client": {"attribute1": "value1", "attribute2": true}}
```
+To retrieve all shared attributes, pass an empty string for `sharedKeys`:
+
+```js
+var mqtt = require('mqtt');
+var client = mqtt.connect('mqtt://' + process.env.EDGE_HOST, {
+ username: process.env.ACCESS_TOKEN
+});
+
+client.on('connect', function () {
+ client.subscribe('v1/devices/me/attributes/response/+');
+ client.publish('v1/devices/me/attributes/request/1',
+ JSON.stringify({sharedKeys: ''}));
+});
+
+client.on('message', function (topic, message) {
+ console.log('Attributes:', message.toString());
+ client.end();
+});
+```
+
+Response example:
+
+```json
+{"shared": {"targetTemperature": 24, "enabled": true}}
+```
+
### Subscribe to shared attribute updates
Subscribe to `v1/devices/me/attributes` to receive shared attribute changes pushed by the server:
diff --git a/src/content/_includes/docs/reference/coap-api/attributes.mdx b/src/content/_includes/docs/reference/coap-api/attributes.mdx
index 3c47c2ffab..44f5aa1aab 100644
--- a/src/content/_includes/docs/reference/coap-api/attributes.mdx
+++ b/src/content/_includes/docs/reference/coap-api/attributes.mdx
@@ -30,22 +30,33 @@ Send a `POST` request to upload client-side attributes:
## Request Attribute Values
-Send a `GET` request with `clientKeys` and `sharedKeys` query parameters:
+Send a `GET` request to the attributes endpoint to read client-side and/or shared attribute values. The response groups results by scope: `{"client": {...}, "shared": {...}}`.
-| Credential type | URL |
-|-----------------|-----|
-| Access Token | |
-| X.509 Certificate | |
+**Endpoint:**
+
+| Credential type | Endpoint |
+|-----------------|----------|
+| Access Token | |
+| X.509 Certificate | |
+
+**Query parameters** — choose which attributes to return:
+
+| Parameter | Description |
+|-----------|-------------|
+| `clientKeys` | Comma-separated list of client-side attribute keys to return |
+| `sharedKeys` | Comma-separated list of shared attribute keys to return |
+| `allClientKeys` | Set to `true` to return all client-side attributes (overrides `clientKeys`) |
+| `allSharedKeys` | Set to `true` to return all shared attributes (overrides `sharedKeys`) |
-**Access Token:**
+**Example** (Access Token):
-Response:
+**Response:**
```json
{"client": {"attribute1": "value1", "attribute2": true}, "shared": {"shared1": "value2", "shared2": false}}
@@ -53,10 +64,6 @@ Response:
When the device profile payload type is set to Protobuf, the request and response use fixed schemas. See MQTT Attributes for the Protobuf schemas.
-
-
## Subscribe to Shared Attribute Updates
Use the CoAP **Observe** option to receive push notifications when shared attributes change. The connection stays open and ThingsBoard sends a response each time a shared attribute is updated.
diff --git a/src/content/_includes/docs/reference/gateway-api/attributes.mdx b/src/content/_includes/docs/reference/gateway-api/attributes.mdx
index e4cc24031e..4ca4fab1bd 100644
--- a/src/content/_includes/docs/reference/gateway-api/attributes.mdx
+++ b/src/content/_includes/docs/reference/gateway-api/attributes.mdx
@@ -1,5 +1,6 @@
import DocLink from '@components/DocLink.astro';
import HostCode from '~/components/HostCode.astro';
+import { Aside } from '@astrojs/starlight/components';
## Publish Client-Side Attributes
@@ -24,24 +25,74 @@ Subscribe to the response topic first, then publish the request.
**Publish:** `v1/gateway/attributes/request`
+**Request:**
+
```json
-{
- "id": 1,
- "device": "Device A",
- "client": ["fw_version", "battery"],
- "shared": ["targetFwVersion"]
-}
+{"id": 1, "device": "Device A", "clientKeys": "fw_version,battery", "sharedKeys": "targetFwVersion"}
```
| Field | Required | Description |
|-------|----------|-------------|
| `id` | Yes | Integer request identifier — echoed in the response |
-| `device` | Yes | Device name |
-| `client` | No | Client-side attribute keys to return |
-| `shared` | No | Shared attribute keys to return |
+| `device` | Yes | Name of a device connected through this gateway |
+| `clientKeys` | No | Comma-separated client attribute keys to return; use `""` (empty string) to return all client attributes; omit the field entirely to exclude the client scope |
+| `sharedKeys` | No | Comma-separated shared attribute keys to return; use `""` (empty string) to return all shared attributes; omit the field entirely to exclude the shared scope |
+
+
+
+Omitting **both** `clientKeys` and `sharedKeys` (sending only `id` and `device`) returns **all** client and **all** shared attributes in a single scope-separated response.
+
+**Response:**
+
+```json
+{"id": 1, "device": "Device A", "client": {"fw_version": "1.0", "battery": 87}, "shared": {"targetFwVersion": "2.0"}}
+```
+
+### Example
+
+The following example is written in JavaScript and is based on [mqtt.js](https://github.com/mqttjs/MQTT.js). A pure command-line example is not available because subscribe and publish must happen in the same MQTT session.
+
+1. Save the **mqtt-js-gateway-attributes-request.js** file to your PC.
+
+
+
+ The content of the **mqtt-js-gateway-attributes-request.js** file:
+
+ ```js download='mqtt-js-gateway-attributes-request.js' title="mqtt-js-gateway-attributes-request.js"
+ var mqtt = require('mqtt');
+ var client = mqtt.connect('mqtt://localhost', {
+ username: process.env.TOKEN
+ });
+
+ client.on('connect', function () {
+ console.log('connected');
+ client.subscribe('v1/gateway/attributes/response');
+ // clientKeys/sharedKeys are comma-separated strings. An empty value returns
+ // ALL keys in that scope, e.g. sharedKeys: "". Omit a field to exclude a scope.
+ var request = { id: 1, device: 'Device A', clientKeys: 'fw_version,battery', sharedKeys: 'targetFwVersion' };
+ client.publish('v1/gateway/attributes/request', JSON.stringify(request));
+ });
+
+ client.on('message', function (topic, message) {
+ console.log('response.topic: ' + topic);
+ console.log('response.body: ' + message.toString());
+ client.end();
+ });
+ ```
+
+2. Now, follow these steps:
+
+
-
+ ```bash
+ export TOKEN=$ACCESS_TOKEN
+ node mqtt-js-gateway-attributes-request.js
+ ```
## Subscribe to Shared Attribute Updates
diff --git a/src/content/_includes/docs/reference/http-api/attributes.mdx b/src/content/_includes/docs/reference/http-api/attributes.mdx
index 33314f0ff4..390870c831 100644
--- a/src/content/_includes/docs/reference/http-api/attributes.mdx
+++ b/src/content/_includes/docs/reference/http-api/attributes.mdx
@@ -1,6 +1,5 @@
import DocLink from '@components/DocLink.astro';
import HostCode from '~/components/HostCode.astro';
-import { Aside } from '@astrojs/starlight/components';
The HTTP Attributes API lets devices upload client-side attributes, request attribute values, and poll for shared attribute updates. For an explanation of attribute types, see Attributes.
@@ -20,27 +19,31 @@ Upload client-side attributes with a `POST` request:
## Request Attribute Values
-Request client-side and shared attribute values with a `GET` request:
+Send a `GET` request to the attributes endpoint to read client-side and/or shared attribute values. The response groups results by scope: `{"client": {...}, "shared": {...}}`.
-
+**Endpoint:**
-| Query parameter | Description |
-|-----------------|-------------|
+
+
+**Query parameters** — choose which attributes to return:
+
+| Parameter | Description |
+|-----------|-------------|
| `clientKeys` | Comma-separated list of client-side attribute keys to return |
| `sharedKeys` | Comma-separated list of shared attribute keys to return |
+| `allClientKeys` | Set to `true` to return all client-side attributes (overrides `clientKeys`) |
+| `allSharedKeys` | Set to `true` to return all shared attributes (overrides `sharedKeys`) |
+
+**Example:**
-Response:
+**Response:**
```json
{"client": {"attribute1": "value1", "attribute2": true}, "shared": {"shared1": "value2", "shared2": false}}
```
-
-
## Subscribe to Shared Attribute Updates
Poll for shared attribute changes with a long-lived `GET` request:
diff --git a/src/content/_includes/docs/reference/mqtt-api/attributes.mdx b/src/content/_includes/docs/reference/mqtt-api/attributes.mdx
index 3577f88393..56e4ea76c5 100644
--- a/src/content/_includes/docs/reference/mqtt-api/attributes.mdx
+++ b/src/content/_includes/docs/reference/mqtt-api/attributes.mdx
@@ -43,6 +43,13 @@ Ask ThingsBoard for the current values of client-side or shared attributes. Usef
{"clientKeys": "firmwareVersion,serialNumber", "sharedKeys": "targetTemperature,enabled"}
```
+| Field | Description |
+|-------|-------------|
+| `clientKeys` | Comma-separated client-side attribute keys to return; `""` returns all client attributes; omit to exclude the client scope |
+| `sharedKeys` | Comma-separated shared attribute keys to return; `""` returns all shared attributes; omit to exclude the shared scope |
+
+An empty request body (`{}`) returns all client and all shared attributes.
+
**Response:**
```json
@@ -52,6 +59,53 @@ Ask ThingsBoard for the current values of client-side or shared attributes. Usef
}
```
+**Example**
+
+The following example is written in JavaScript and is based on [mqtt.js](https://github.com/mqttjs/MQTT.js). Pure command-line examples are not available because subscribe and publish need to happen in the same MQTT session.
+
+1. Save the **mqtt-js-attributes-request.js** file to your PC.
+
+
+
+ The content of the **mqtt-js-attributes-request.js** file:
+
+ ```js download='mqtt-js-attributes-request.js' title="mqtt-js-attributes-request.js"
+ var mqtt = require('mqtt');
+ var client = mqtt.connect('mqtt://localhost', {
+ username: process.env.TOKEN
+ });
+ var requestId = 1;
+
+ client.on('connect', function () {
+ console.log('connected');
+ client.subscribe('v1/devices/me/attributes/response/+');
+ // Specify keys as comma-separated strings. An empty value returns ALL keys
+ // in that scope, e.g. sharedKeys: "". Omit a field to exclude that scope.
+ var request = { clientKeys: 'firmwareVersion,serialNumber', sharedKeys: 'targetTemperature,enabled' };
+ client.publish('v1/devices/me/attributes/request/' + requestId, JSON.stringify(request));
+ });
+
+ client.on('message', function (topic, message) {
+ console.log('response.topic: ' + topic);
+ console.log('response.body: ' + message.toString());
+ client.end();
+ });
+ ```
+
+2. Now, follow these steps:
+
+
+
+ ```bash
+ export TOKEN=$ACCESS_TOKEN
+ node mqtt-js-attributes-request.js
+ ```
+