Skip to content

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:

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 PropertiesPOST /v3/devices/properties
  • Device StatusPOST /v3/devices/status
  • MeasurementsPOST /v2/measurements
  • AlarmsPOST /v3/alarms
  • LocationsPOST /v1/locations
  • Measuring ObjectsPOST /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 $select to 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 uuid fields: The Smart Connect API follows an at-least-once delivery policy. Duplicate records can occur, so plan to deduplicate results using the uuid field.

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.