Data transformation API
This API is based on the Device Configuration API framework. For guidance on how to use these APIs, please refer to Device Configuration APIs.
This API is in BETA stage and provided for testing purposes. It is subject to backward-incompatible changes, including modifications to its functionality, behavior and availability. The API should not be used in production environments.
Overview
The Data transformation API provides configuration and runtime status for transforming JSON data in Device Data Hub topics using JSON Query (JQ) expressions. It allows you to define a transform of an input topic to an output topic to extract or modify the data as needed.
New topics created from transforms are prefixed with com.axis.dt.. They can be consumed by other applications or transforms like any other Device Data Hub topic, for example by subscribing to them via MQTT.
With this API, you can:
- Extract only the required content or filter out messages that do not meet specific criteria to reduce bandwidth when sending data to external consumers.
- Change the data format, for example convert timestamps to a different representation to make the data easier for external consumers to use.
- Precompute data derived from other fields to reduce processing requirements for external consumers.
Transform settings
The required transformation settings are inputTopic, jqExpression, and outputTopic.
The optional settings are:
outputTopicDescription: Defaults to"JQ transformation of the topic {inputTopic} of version {inputVersion}".outputTopicVersion: Defaults to the version of the input topic. If the input topic does not exist when the transform is created, the version will display0.0.0as a placeholder. Once the input topic becomes available, the version will update automatically.
Authentication
For detailed information on how to authenticate requests to this API, please refer to Authentication.
Use Cases
Add a timestamp in a numbered format to 'com.axis.scene.frame.v1'.
Input:
{
"channel_id": 1,
"timestamp": "2026-02-25T09:35:28.205241Z"
}
JQ Transform:
"(.timestamp | rtrimstr(\"Z\") | split(\".\")) as $parts | .seconds = ($parts[0] | strptime(\"%Y-%m-%dT%H:%M:%S\") | mktime) | .microseconds = ($parts[1] | tonumber)"
The expression contains backslash-escaped double quotes (\") for use in the API. To run it in a terminal, replace \" with ".
Output:
{
"channel_id": 1,
"seconds": 1772012128,
"microseconds": 205241,
"timestamp": "2026-02-25T09:35:28.205241Z"
}
Get available input topics
Retrieve all topics that can be used as inputs. Use this request to probe the available topics. Note that other topics can appear at any time, which means that it is possible to set up transformations for non-existing input topics.
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/availableTopics/topics
GET /config/rest/data-transformation/v1beta/availableTopics/topics HTTP/1.1
HOST: my-device
Content-Type: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": {
"topics": [
{
"topicName": "com.axis.some.topic",
"description": "Topic description",
"version": "1.0.0",
"keys": [
"channel_id"
]
}
]
}
}
Add a new transform
Add a transformation. Required fields are inputTopic, jqExpression, and outputTopic.
The output topic needs to have the prefix com.axis.dt. to be accepted.
- curl
- HTTP
curl --request POST \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/transforms \
--data '{
"data": {
"inputTopic": "com.axis.scene.frame.v1",
"jqExpression": ".track_events",
"outputTopic": "com.axis.dt.output.topic"
}
}'
POST /config/rest/data-transformation/v1beta/transforms HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"inputTopic": "com.axis.scene.frame.v1",
"jqExpression": ".track_events",
"outputTopic": "com.axis.dt.output.topic"
}
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"status": "success"
}
Get existing transforms
Retrieve the configured transformations.
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/transforms
GET /config/rest/data-transformation/v1beta/transforms HTTP/1.1
HOST: my-device
Content-Type: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": [
{
"inputTopic": "com.axis.input.topic",
"outputTopic": "com.axis.dt.output.topic",
"jqExpression": ".track_events",
"outputTopicDescription": "Only the object track events",
"outputTopicVersion": "1.0.0"
}
]
}
Update an existing transform
Update optional fields for an existing transformation.
- curl
- HTTP
curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic \
--data '{
"data": {
"outputTopic": "com.axis.dt.output.topic.v2"
}
}'
PATCH /config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"outputTopic": "com.axis.dt.output.topic.v2"
}
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Remove a transform
Remove a transformation.
- curl
- HTTP
curl --request DELETE \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic
DELETE /config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic HTTP/1.1
HOST: my-device
Content-Type: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Get transform statistics
Retrieve the runtime statistics for a transformation.
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic/statistics
GET /config/rest/data-transformation/v1beta/transforms/com/axis/dt/output/topic/statistics HTTP/1.1
HOST: my-device
Content-Type: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": {
"msgInCount": 1200,
"msgOutCount": 1195,
"byteInCount": 845000,
"byteOutCount": 812000,
"avgMsgProcessingTimeNs": 4000,
"avgMsgsPerSec": 25.5,
"msgDroppedCount": 3,
"jqTransformationErrCount": 2,
"publishErrCount": 0,
"lastErrMsg": "2026-02-09T09:15:33.123456Z Transform: error message"
}
}
API definition
Structure
data-transformation.v1 (Root Entity)
├── availableTopics (Entity)
├── topics (Property)
├── transforms (Entity Collection)
├── inputTopic (Property)
├── jqExpression (Property)
├── outputTopic (Property)
├── outputTopicDescription (Property)
├── outputTopicVersion (Property)
├── statistics (Property)
Entities
data-transformation.v1
- Description: Configuration root object.
- Type: Singleton
- Operations
- Get
- Attributes
- Dynamic Support: No
Properties
This entity has no properties.
Actions
This entity has no actions.
data-transformation.v1.availableTopics
- Description: Topics that can be used as an input.
- Type: Singleton
- Operations
- Get
- Attributes
- Dynamic Support: No
Properties
topics
- Description: Topics that can be used as an input.
- Datatype: TopicList
- Operations
- Get
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions
This entity has no actions.
data-transformation.v1.transforms
- Description: The set of all transformations configured by the system.
- Type: Collection (Key Property: outputTopic)
- Operations
- Get
- Set
- Properties: inputTopic, jqExpression, outputTopicDescription, outputTopicVersion
- Add
- Required properties: inputTopic, jqExpression, outputTopic
- Optional properties: outputTopicDescription, outputTopicVersion
- Remove
- Attributes
- Dynamic Support: No
Properties
inputTopic
- Description: The input topic.
- Datatype: Topic
- Operations
- Get
- Set
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
jqExpression
- Description: The jq program used to transform the input to another output format.
- Datatype: JqExpression
- Operations
- Get
- Set
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
outputTopic
- Description: The output topic.
- Datatype: Topic
- Operations
- Get
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
outputTopicDescription
- Description: Output topic description.
- Datatype: string
- Operations
- Get
- Set
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
outputTopicVersion
- Description: Output topic version.
- Datatype: Version
- Operations
- Get
- Set
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
statistics
- Description: Runtime statistics for the transform.
- Datatype: Statistics
- Operations
- Get (Permissions: admin, operator)
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions
This entity has no actions.
Data Types
JqExpression
- Description: The jq program used to transform the input to output format
- Type: string
- Minimum Length: 1
- Maximum Length: 20480
Statistics
- Description: Runtime statistics for a transform. Resets when the transform is modified or device is restarted.
- Type: complex
- Fields
- avgMsgProcessingTimeNs
- Description: Average processing time over the last 30 messages
- Type: integer
- Nullable: No / Gettable: Yes
- avgMsgsPerSec
- Description: Average number of input messages per second over the last 30 messages
- Type: number
- Nullable: No / Gettable: Yes
- byteInCount
- Description: Total number of bytes received
- Type: integer
- Nullable: No / Gettable: Yes
- byteOutCount
- Description: Total number of bytes sent after jq processing
- Type: integer
- Nullable: No / Gettable: Yes
- jqTransformationErrCount
- Description: Number of jq transformation errors
- Type: integer
- Nullable: No / Gettable: Yes
- lastErrMsg
- Description: Last error message when failing to transform or send a message
- Type: string
- Nullable: No / Gettable: Yes
- msgDroppedCount
- Description: Number of dropped messages
- Type: integer
- Nullable: No / Gettable: Yes
- msgInCount
- Description: Total number of input messages
- Type: integer
- Nullable: No / Gettable: Yes
- msgOutCount
- Description: Total number of output messages (errors don't count)
- Type: integer
- Nullable: No / Gettable: Yes
- publishErrCount
- Description: Number of failed Device Data Hub publications (for example, a missing key field)
- Type: integer
- Nullable: No / Gettable: Yes
- avgMsgProcessingTimeNs
Topic
- Description: Topic
- Type: string
- Minimum Length: 1
- Maximum Length: 128
- Pattern:
^([a-zA-Z0-9_-]+)(\.[a-zA-Z0-9_-]+)\*$
TopicInfo
- Description: Info about a Device Data Hub topic
- Type: complex
- Fields
- description
- Description: Topic description
- Type: string
- Nullable: No / Gettable: Yes
- keys
- Description: Topic keys
- Type: TopicKeys
- Nullable: No / Gettable: Yes
- topicName
- Description: Topic
- Type: Topic
- Nullable: No / Gettable: Yes
- version
- Description: Topic version
- Type: string
- Nullable: No / Gettable: Yes
- description
TopicKeys
- Description: Topic key paths
- Type: array
- Element type: string
- Null Value: No
TopicList
- Description: Information about topics
- Type: array
- Element type: TopicInfo
- Null Value: No
Version
- Description: Device Data Hub Topic Version
- Type: string
- Minimum Length: 1
- Maximum Length: 32
- Pattern:
^\d+\.\d+(\.\d+)?(\-(alpha|beta)\.\d+)?$