Curl Examples & OData Filtering Reference
This page provides copy-paste-ready curl examples for every Smart Connect API endpoint, along with sample responses and a comprehensive OData filtering reference. All endpoints follow the asynchronous pattern described in the Concepts chapter.
Before proceeding, make sure you have:
- A valid API key generated from the API Key Management — see Authentication & Security
curlinstalled on your system- Familiarity with the asynchronous request pattern — see Concepts
Info
In all examples below, replace <region> and <environment> with your actual region and environment values, and replace your-api-key-here with the API key you generated from the API Key Management.
Endpoint Overview
The Smart Connect API provides six endpoint pairs. Each pair consists of a POST endpoint to initiate data preparation and a GET endpoint to poll for results and retrieve download URLs.
| Endpoint | POST Path | GET Path | Date Range | OData |
|---|---|---|---|---|
| Device Properties | /v3/devices/properties |
/v3/devices/properties/{request_uuid} |
No | Yes |
| Device Status | /v3/devices/status |
/v3/devices/status/{request_uuid} |
No | Yes |
| Measurements | /v2/measurements |
/v2/measurements/{request_uuid} |
Yes | Yes |
| Alarms | /v3/alarms |
/v3/alarms/{request_uuid} |
Yes | Yes |
| Locations | /v1/locations |
/v1/locations/{request_uuid} |
No | Yes |
| Measuring Objects | /v1/measuring-objects |
/v1/measuring-objects/{request_uuid} |
No | Yes |
- Supported file formats: CSV (default), ORC, PARQUET, AVRO, JSON, TEXTFILE
Tip
If you need the same data multiple times, you can cache the download URL and download the file again without making a new API request. Download URLs are valid for approximately one hour.
Device Properties (v3)
Retrieve metadata about devices, sensors, and channels — including serial numbers, model codes, firmware versions, calibration status, and equipment relationships. This endpoint supports OData filtering.
Basic Request
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/properties
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/properties" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
}
}'
Sample response:
{
"status": "Submitted",
"request_uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
Request with OData Filtering
Scenario: Find all active loggers, returning only identifying and firmware fields.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/properties" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
},
"odata": {
"$filter": "device_category eq '\''LOGGER'\'' and device_is_active eq '\''true'\''",
"$select": "device_uuid,device_serial_no,device_model_code,device_firmware_version,sensor_uuid,sensor_serial_no",
"$orderby": "device_serial_no asc"
}
}'
Poll for Results
GET https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/properties/{request_uuid}
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/properties/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "x-custom-api-key: your-api-key-here"
While processing:
{
"status": "In Progress"
}
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/devices-properties/3fa85f64-5717-4562-b3fc-2c963f66afa6.csv?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/devices-properties/3fa85f64-5717-4562-b3fc-2c963f66afa6.csv.metadata?..."
}
Download Result
curl -o devices-properties.csv "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/devices-properties/3fa85f64-5717-4562-b3fc-2c963f66afa6.csv?..."
Note
Download URLs are pre-signed S3 URLs. They do not require the x-custom-api-key header and are valid for approximately one hour.
Response Fields
| Field | Type | Description |
|---|---|---|
tenant_uuid |
string | Unique identifier of the tenant account |
customer_site |
string | Identifier for the customer site |
device_uuid |
string | Unique identifier of the device |
device_category |
string | The category of the device such as LOGGER, GATEWAY, etc. |
device_serial_no |
string | Article number of the device |
device_model_code |
string | Device article number |
device_firmware_version |
string | Firmware version of the device |
device_supported_battery_types |
array | Supported battery types of the device |
device_display_name |
string | Name of the logger |
device_is_active |
string | Denotes that whether device is active or not |
device_communication_log_time |
integer | Interval of communication time (in milliseconds) |
device_measuring_cycle |
integer | Interval of device measuring cycle time (in milliseconds) |
device_measuring_cycle_effective |
integer | Interval of device effective measuring cycle time (in milliseconds) |
device_is_ethernetprobe |
string | Is the probe an ethernet probe |
device_is_powersuppliable |
string | Is the probe power-suppliable |
device_is_wirelessprobe |
string | Is the probe a radio probe |
device_last_modified |
date-time | Time point where the device was last modified in iso8601 format |
sensor_uuid |
uuid | Unique identifier of the sensor |
sensor_serial_no |
string | Serial number of the sensor |
sensor_model_code |
string | Article number of the sensor |
sensor_firmware_version |
string | Firmware version of the sensor |
sensor_display_name |
string | Name of the sensor |
sensor_is_wired |
string | Is the sensor wired |
sensor_is_radio |
string | Is the sensor wireless |
sensor_is_connected |
string | Is the sensor connected |
sensor_measuring_cycle |
integer | Interval of sensor measuring cycle time (in milliseconds) |
sensor_measuring_cycle_effective |
integer | Interval of sensor effective measuring cycle time (in milliseconds) |
sensor_last_modified |
date-time | Time point where the sensor was last modified in iso8601 format |
channel_id |
integer | Unique identifier of the channel |
channel_no |
integer | Number to identify a specific channel of a sensor if it has multiple ones |
channel_physical_unit |
string | The measurement unit (e.g., °C, %rF, g/m³) |
channel_physical_property_name |
string | Physical property name of channel (e.g., Temperature, Density, Door) |
channel_physical_extension |
string | Physical extension defines channel (e.g., Air Temperature, Absolute Humidity, Door Contact) |
channel_physical_unit_exponent |
integer | Exponent of the measurement - Number represents amount of decimal places |
channel_attenuation |
number | Product simulation attenuation (product simulation coefficient) |
channel_is_external |
string | Is the probe external |
channel_is_calibration_possible |
string | Is the probe calibratable |
equipment_uuid |
uuid | Unique equipment identifier which the device is assigned to |
equipment_parts_uuid |
uuid | Unique equipment identifier which the sensor is assigned to |
channel_last_modified |
date-time | Time point where the channel was last modified in iso8601 format |
Device Status (v3)
Retrieve the current status of devices — including connection type, battery level, radio signal strength, firmware version, and communication timestamps. This endpoint supports OData filtering.
Basic Request
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/status
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/status" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
}
}'
Sample response:
{
"status": "Submitted",
"request_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Request with OData Filtering
Scenario: Find all Wi-Fi connected devices with battery level below 20% to prioritize maintenance.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/status" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
},
"odata": {
"$filter": "connection_type eq '\''CT_WIFI'\'' and battery_level_percent lt 20",
"$select": "device_uuid,serial_no,connection_type,battery_level_percent,last_communication",
"$orderby": "battery_level_percent asc"
}
}'
Poll for Results
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/devices/status/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "x-custom-api-key: your-api-key-here"
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/devices-status/a1b2c3d4-e5f6-7890-abcd-ef1234567890.csv?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/devices-status/a1b2c3d4-e5f6-7890-abcd-ef1234567890.csv.metadata?..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
device_uuid |
uuid | Device identifier |
tenant_uuid |
uuid | Tenant identifier |
customer_site |
string | Customer site identifier |
serial_no |
string | Device serial number |
model_code |
string | Device model code |
connection_type |
string | Connection type: CT_UNKNOWN, CT_WIFI, CT_ETHERNET |
battery_level_percent |
integer | Battery level (0–100) |
radio_level_percent |
integer | Radio signal strength (0–100) |
fw_version |
string | Firmware version |
is_powersupply_on |
boolean | Whether external power supply is connected |
last_communication |
date-time | Last communication timestamp |
next_communication |
date-time | Next expected communication timestamp |
last_measurement_time |
date-time | Last measurement timestamp |
processed_at |
date-time | Processing timestamp |
Measurements (v2)
Retrieve measurement data for a specified time range — including measurement values, timestamps, physical properties, and device/sensor identifiers. This endpoint supports OData filtering.
Basic Request with Date Range
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-07T23:59:59Z",
"options": {
"result_file_format": "CSV"
}
}'
Note
If date_time_from is omitted, it defaults to 1 hour before the current time. If date_time_until is omitted, it defaults to 1 hour after date_time_from.
Sample response:
{
"status": "Submitted",
"request_uuid": "5f330649-9cf2-4d3d-8c96-9e4b2d960678"
}
Request with Parquet Format
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-07T23:59:59Z",
"options": {
"result_file_format": "PARQUET"
}
}'
Note
The number of result files may differ depending on the file format used. PARQUET format is recommended for data analysis workflows with tools like Pandas or Apache Spark.
Request with OData Filtering + Date Range
Scenario: Retrieve only temperature measurements from the past week, sorted by most recent first.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-07T23:59:59Z",
"options": {
"result_file_format": "CSV"
},
"odata": {
"$filter": "physical_property_name eq '\''Temperature'\''",
"$select": "uuid,sensor_uuid,serial_no,timestamp,measurement,physical_property_name,physical_unit",
"$orderby": "timestamp desc"
}
}'
Poll for Results
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements/5f330649-9cf2-4d3d-8c96-9e4b2d960678" \
-H "x-custom-api-key: your-api-key-here"
While processing:
{
"status": "In Progress"
}
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/measurements/5f330649-9cf2-4d3d-8c96-9e4b2d960678.csv?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/measurements/5f330649-9cf2-4d3d-8c96-9e4b2d960678.csv.metadata?..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid |
uuid | Measurement record identifier |
sensor_uuid |
uuid | Sensor identifier |
channel_no |
integer | Channel number of the sensor |
serial_no |
string | Serial number of the sensor |
model_code |
string | Model code of the sensor |
tenant_uuid |
uuid | Tenant identifier |
customer_site |
uuid | Customer site identifier |
timestamp |
date-time | Measurement timestamp (UTC) |
timestamp_local |
date-time | Measurement timestamp (local timezone) |
measurement |
number | The measured value |
physical_property_name |
string | Property name (e.g., Temperature, Humidity, Density) |
physical_unit |
string | Unit of measurement (e.g., CELSIUS, FAHRENHEIT) |
physical_extension |
string | Physical extension (e.g., Door Contact, Product Temperature) |
processed_at |
date-time | Processing timestamp |
Alarms (v3)
Retrieve alarm data for a specified time range — including alarm reason, severity, status, and the measured values that triggered the alarm. This endpoint supports OData filtering.
Basic Request with Date Range
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v3/alarms
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/alarms" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-15T23:59:59Z",
"options": {
"result_file_format": "CSV"
}
}'
Sample response:
{
"status": "Submitted",
"request_uuid": "fbf29fed-e3e2-46fb-a304-ee099e849044"
}
Request with OData Filtering + Date Range
Scenario: Retrieve only active alarms with Warning severity during a specific week, sorted by most recent first.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/alarms" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"date_time_from": "2025-04-07T00:00:00Z",
"date_time_until": "2025-04-14T23:59:59Z",
"options": {
"result_file_format": "CSV"
},
"odata": {
"$filter": "alarm_status eq '\''Alarm'\'' and alarm_severity eq '\''Warning'\''",
"$select": "uuid,alarm_reason,alarm_status,alarm_severity,alarm_time,alarm_value,physical_unit,serial_no",
"$orderby": "alarm_time desc"
}
}'
Poll for Results
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/alarms/fbf29fed-e3e2-46fb-a304-ee099e849044" \
-H "x-custom-api-key: your-api-key-here"
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/alarms/fbf29fed-e3e2-46fb-a304-ee099e849044.csv?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/alarms/fbf29fed-e3e2-46fb-a304-ee099e849044.csv.metadata?..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid |
uuid | Alarm record identifier |
alarm_reason |
string | Reason for the alarm |
alarm_status |
string | Current status: Alarm, Ok |
last_status_change_time |
date-time | When the alarm status last changed |
alarm_condition_type |
string | Condition type that triggered the alarm |
alarm_severity |
string | Severity level: Warning, Alarm |
alarm_time |
date-time | Alarm timestamp (UTC) |
alarm_time_local |
date-time | Alarm timestamp (local timezone) |
alarm_value |
number | The measured value that triggered the alarm |
physical_unit |
string | Unit of measurement (e.g., °C, %rF) |
physical_value |
string | Physical value (e.g., Temperature, Humidity, Door) |
physical_value_extension |
string | Physical value extension |
alarm_source_uuid |
uuid | Source device/sensor identifier |
serial_no |
string | Serial number of the alarm source |
tenant_uuid |
uuid | Tenant identifier |
customer_site_uuid |
uuid | Customer site identifier |
alarm_type |
string | Type: measurement_alarm, device system alarm, sensor system alarm |
source_alarm_event_uuid |
uuid | Source alarm event UUID (for back-to-normal alarms) |
processed_at |
date-time | Processing timestamp |
Locations (v1)
Retrieve information about registered locations — including customer sites, measurement sites, and their hierarchical relationships. This endpoint supports OData filtering.
Basic Request
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v1/locations
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/locations" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
}
}'
Sample response:
{
"status": "Submitted",
"request_uuid": "c8d7e6f5-a4b3-2c1d-0e9f-8a7b6c5d4e3f"
}
Request with OData Filtering
Scenario: Find all measurement site locations, sorted alphabetically by name.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/locations" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "CSV"
},
"odata": {
"$filter": "location_type eq '\''Measurement site'\''",
"$select": "location_uuid,name,location_type,location_subtype,parent_uuid",
"$orderby": "name asc"
}
}'
Poll for Results
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/locations/c8d7e6f5-a4b3-2c1d-0e9f-8a7b6c5d4e3f" \
-H "x-custom-api-key: your-api-key-here"
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/locations/c8d7e6f5-a4b3-2c1d-0e9f-8a7b6c5d4e3f.csv?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/locations/c8d7e6f5-a4b3-2c1d-0e9f-8a7b6c5d4e3f.csv.metadata?..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
tenant_uuid |
uuid | Tenant identifier |
location_uuid |
uuid | Location identifier |
parent_uuid |
uuid | Parent location identifier |
name |
string | Location name |
location_type |
string | Type of location (e.g., Customer, Measurement site) |
parent_location_type |
string | Type of the parent location |
location_subtype |
string | Subtype (e.g., Ventilation, Flue gas) |
valid_from |
date-time | Validity start date |
last_modified_at |
date-time | Last modification timestamp |
Measuring Objects (v1)
Retrieve detailed information about measuring objects — including product family, customer site, and configuration data such as alarm configurations, channel assignments, and measuring instructions. This endpoint supports OData filtering.
Basic Request
POST https://data-api.<region>.<environment>.smartconnect.testo.com/v1/measuring-objects
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/measuring-objects" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "JSON"
}
}'
Tip
JSON format may be more convenient for this endpoint, as the measurement_alarm_configuration, channel_assignments, and measuring_instructions fields contain JSON-encoded strings.
Sample response:
{
"status": "Submitted",
"request_uuid": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a"
}
Request with OData Filtering
Scenario: Retrieve all measuring objects for the "savr" product family.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/measuring-objects" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"options": {
"result_file_format": "JSON"
},
"odata": {
"$filter": "product_family_id eq '\''savr'\''",
"$select": "mo_uuid,customer_uuid,product_family_id,customer_site,measurement_alarm_configuration"
}
}'
Poll for Results
curl -X GET "https://data-api.<region>.<environment>.smartconnect.testo.com/v1/measuring-objects/d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a" \
-H "x-custom-api-key: your-api-key-here"
When completed:
{
"status": "Completed",
"data_urls": [
"https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/measuring-objects/d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a.json?..."
],
"metadata_url": "https://tds-eu-i-data-storage-query-results.s3.amazonaws.com/measuring-objects/d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a.json.metadata?..."
}
Response Fields
| Field | Type | Description |
|---|---|---|
customer_uuid |
uuid | Customer identifier |
mo_uuid |
uuid | Measuring object identifier |
product_family_id |
string | Product family (e.g., savr, sav3, data layer) |
customer_site |
string | Customer site identifier |
version_timestamp |
date-time | Version timestamp (UTC) |
measurement_alarm_configuration |
string | JSON-encoded alarm configuration |
channel_assignments |
string | JSON-encoded channel assignments |
measuring_instructions |
string | JSON-encoded measuring instructions |
valid_from |
date-time | Validity start date |
OData Query Reference
OData system query options allow you to filter, select, and sort data directly in your API request. This reduces the size of the result files and eliminates the need for post-processing.
Supported Endpoints
OData query options are available on all endpoints:
- Device Properties —
POST /v3/devices/properties - Device Status —
POST /v3/devices/status - Measurements —
POST /v2/measurements - Alarms —
POST /v3/alarms - Locations —
POST /v1/locations - Measuring Objects —
POST /v1/measuring-objects
$filter Operators
Use the $filter option to restrict results based on conditions. The following comparison and logical operators are supported:
| Operator | Description | Example |
|---|---|---|
eq |
Equal | connection_type eq 'CT_WIFI' |
ne |
Not equal | alarm_status ne 'Ok' |
gt |
Greater than | battery_level_percent gt 50 |
ge |
Greater than or equal | battery_level_percent ge 20 |
lt |
Less than | battery_level_percent lt 10 |
le |
Less than or equal | radio_level_percent le 30 |
and |
Logical AND | alarm_status eq 'Alarm' and alarm_severity eq 'Warning' |
or |
Logical OR | connection_type eq 'CT_WIFI' or connection_type eq 'CT_ETHERNET' |
not |
Logical NOT | not is_powersupply_on eq true |
$filter String Functions
The following string functions can be used within $filter expressions:
| Function | Description | Example |
|---|---|---|
contains(field, 'value') |
Substring match | contains(name, 'Cold Storage') |
startswith(field, 'value') |
Starts with prefix | startswith(serial_no, '556') |
endswith(field, 'value') |
Ends with suffix | endswith(fw_version, '.1') |
$select
Use $select to specify which columns to include in the result. This reduces file size and download time.
"$select": "device_uuid,serial_no,battery_level_percent,last_communication"
Tip
Using $select to request only the fields you need can significantly reduce download size and processing time, especially for endpoints with many fields like Device Properties.
$orderby
Use $orderby to sort results by one or more columns. Specify asc for ascending (default) or desc for descending order.
"$orderby": "alarm_time desc,alarm_severity asc"
You can sort by multiple columns by separating them with commas. The results will be sorted by the first column, then by the second column for rows with the same first column value, and so on.
Practical OData Scenarios
Below are practical scenarios demonstrating how to combine OData options for common use cases.
1. Low Battery Wi-Fi Devices (Device Status)
Find all Wi-Fi connected devices with battery below 20% to schedule maintenance:
{
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "connection_type eq 'CT_WIFI' and battery_level_percent lt 20",
"$select": "device_uuid,serial_no,battery_level_percent,last_communication",
"$orderby": "battery_level_percent asc"
}
}
2. Active Alarms Sorted by Time (Alarms)
Retrieve all currently active alarms, most recent first:
{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-30T23:59:59Z",
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "alarm_status eq 'Alarm'",
"$select": "uuid,alarm_reason,alarm_severity,alarm_time,alarm_value,physical_unit,serial_no",
"$orderby": "alarm_time desc"
}
}
3. Temperature Alarms in a Date Range (Alarms)
Retrieve only temperature-related alarms for a specific month:
{
"date_time_from": "2025-04-01T00:00:00Z",
"date_time_until": "2025-04-30T23:59:59Z",
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "physical_value eq 'Temperature'",
"$select": "uuid,alarm_reason,alarm_severity,alarm_time,alarm_value,physical_unit,serial_no,alarm_type",
"$orderby": "alarm_time desc"
}
}
4. Locations of a Specific Type (Locations)
Retrieve all measurement site locations with a specific subtype:
{
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "location_type eq 'Measurement site' and location_subtype eq 'Ventilation'",
"$select": "location_uuid,name,location_type,location_subtype,parent_uuid",
"$orderby": "name asc"
}
}
5. Devices Not Communicating Recently (Device Status)
Identify devices that have not communicated since a specific date:
{
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "last_communication lt '2025-04-01T00:00:00Z'",
"$select": "device_uuid,serial_no,connection_type,last_communication,fw_version",
"$orderby": "last_communication asc"
}
}
6. Measuring Objects for a Product Family (Measuring Objects)
Retrieve all measuring objects belonging to the "savr" product family:
{
"options": { "result_file_format": "JSON" },
"odata": {
"$filter": "product_family_id eq 'savr'",
"$select": "mo_uuid,customer_uuid,product_family_id,customer_site,measurement_alarm_configuration"
}
}
7. Locations Matching a Name Pattern (Locations)
Find all locations whose name contains "Cold Storage":
{
"options": { "result_file_format": "CSV" },
"odata": {
"$filter": "contains(name, 'Cold Storage')",
"$select": "location_uuid,name,location_type,location_subtype",
"$orderby": "name asc"
}
}
Error Responses
401 Unauthorized
Returned when the API key is missing, invalid, or expired.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v2/measurements" \
-H "Content-Type: application/json" \
-d '{
"options": { "result_file_format": "CSV" }
}'
{
"message": "Unauthorized"
}
400 Bad Request
Returned when the request body is malformed or contains invalid OData syntax.
curl -X POST "https://data-api.<region>.<environment>.smartconnect.testo.com/v3/alarms" \
-H "Content-Type: application/json" \
-H "x-custom-api-key: your-api-key-here" \
-d '{
"odata": {
"$filter": "invalid_field === true"
}
}'
{
"status": "Error",
"message": "Bad request: invalid filter expression"
}
500 Internal Server Error
Returned when an unexpected server-side error occurs.
{
"status": "Error",
"message": "An unexpected error occurred. Please try again later."
}
Tips and Best Practices
- Use
$selectto minimize download size: Request only the fields you need to reduce file size and download time. - Cache download URLs: If you need the same data multiple times, reuse the download URL instead of making a new API request. URLs are valid for approximately one hour.
- Use smaller date ranges: For measurements and alarms, requesting smaller time windows reduces processing time and result file sizes.
- Consider PARQUET format for analysis: If you are using data analysis tools like Pandas, Apache Spark, or similar frameworks, PARQUET format provides efficient compression and columnar storage.
- Implement exponential backoff for polling: Instead of polling at a fixed interval, start with a short interval (e.g., 5 seconds) and increase it progressively (10s, 20s, etc.) to avoid unnecessary requests.
- Deduplicate on
uuidfields: The Smart Connect API follows an at-least-once delivery policy. Duplicate records can occur, so plan to deduplicate results using theuuidfield.
What Next?
We recommend exploring the API Reference for the complete schema documentation, including all available fields and their detailed descriptions. If you are not yet familiar with the asynchronous request model, read the Concepts chapter.