Skip to content

Curl Examples

This page provides copy-paste-ready curl examples for every Smart Connect API endpoint, along with sample responses. For OData filtering, see the 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> with your actual region value, 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>.smartconnect.testo.com/v3/devices/properties

curl -X POST "https://data-api.<region>.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>.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>.smartconnect.testo.com/v3/devices/properties/{request_uuid}

curl -X GET "https://data-api.<region>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


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>.smartconnect.testo.com/v3/devices/status

curl -X POST "https://data-api.<region>.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>.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>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


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>.smartconnect.testo.com/v2/measurements

curl -X POST "https://data-api.<region>.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>.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>.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>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


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>.smartconnect.testo.com/v3/alarms

curl -X POST "https://data-api.<region>.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>.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>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


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>.smartconnect.testo.com/v1/locations

curl -X POST "https://data-api.<region>.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>.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>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


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>.smartconnect.testo.com/v1/measuring-objects

curl -X POST "https://data-api.<region>.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>.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>.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

See the API Reference for the full list of fields contained in the downloaded file (x-file-content on the 200 response of each GET endpoint).


Error Responses

401 Unauthorized

Returned when the API key is missing, invalid, or expired.

curl -X POST "https://data-api.<region>.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>.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.