Skip to content
it

EOS IoT Platform API

REST API to access IoT device data on the EOS platform. This documentation guides you through using the API to integrate device data into your applications.

📥 Download the OpenAPI specification and share it with your AI agent to get the full API context.

Download eos-openapi.json

Note: This is a new product (version 1.0.0). We welcome any feedback to help us improve the API. Don't hesitate to share your suggestions or report any issues you run into.

Authentication

All requests must include the x-api-key header with the API key provided at registration.

Example:

curl -H "x-api-key: YOUR_API_KEY" https://p2uyaymt8c.execute-api.eu-south-1.amazonaws.com/v1/integration/devices

Security:

  • ⚠️ Never share your API key
  • ⚠️ Don't put it in source code
  • ✅ Use environment variables to store it

Rate limiting

The API is rate-limited to keep the service stable. The specific limits depend on your usage plan:

Standard plan:

  • Rate: 0.5 requests per second
  • Burst: 5 concurrent requests
  • Quota: 100,000 requests per month

Custom plans: Other plans with different limits are available. Contact support for more information.

⚠️ Important: Be careful not to burn through your whole quota in the first three days of the month. Plan your API usage to spread requests evenly across the entire billing period and avoid running out of quota too early.

Multiple measurements

Some devices can have more than one sensor of the same type. For example, a device may have:

  • Two temperature sensors (one internal and one external)

In these cases:

  • The measure field will be the same (e.g. "temperature")
  • The sensor_type field will differ (e.g. "in100-q1-r-rc0i" vs "sht40-ad1b-r2")

Use the sensorType parameter to filter a specific sensor when needed.

Date format

All dates must be in ISO 8601 format with UTC timezone:

  • Format: YYYY-MM-DDTHH:mm:ssZ
  • Example: 2026-02-04T15:30:00Z

Historical data granularity

The /devices/{deviceId}/history endpoint supports several granularities:

  • raw: Raw data with no aggregation
  • 15m: Data aggregated every 15 minutes (average, min, max)
  • 1h: Data aggregated hourly (average, min, max)
  • 1d: Data aggregated daily (average, min, max)

Pagination

The /devices/{deviceId}/history endpoint supports pagination:

  • limit: Maximum number of results (default: 100, max: 100)
  • offset: Number of results to skip (default: 0)
  • The response includes pagination information in the pagination field

Data availability

Historical data availability depends on the granularity and on the sensor's installation date:

  • Data availability start date: Data is available from the sensor's installation date for each device
  • Raw data: Available for 30 days from the current date
  • High-frequency CSV data files: Available for 30 days from the current date (same retention as raw data)

Note: This feature is only available if you have high-frequency devices (e.g. motor sensors). If your tenant/site has no high-frequency devices, the API will return an error message.

  • 15-minute aggregated data (15m): Available for 90 days from the current date
  • Hourly aggregated data (1h): Available for 2 years from the current date
  • Daily aggregated data (1d): Available permanently (no expiry)

Recommendations:

  • Use raw for detailed recent analysis (last 30 days)
  • Use the high-frequency CSV files for bulk downloads of recent data (last 30 days)
  • Use 15m for medium-term trends (up to 90 days)
  • Use 1h for long-term analysis (up to 2 years)
  • Use 1d for historical analysis beyond 2 years

Support

For assistance or questions, contact technical support.

HTTP status codes

  • 200 OK: Request completed successfully
  • 400 Bad Request: Malformed request or missing parameters
  • 401 Unauthorized: Missing or invalid API key
  • 403 Forbidden: Access denied
  • 404 Not Found: Resource not found
  • 500 Internal Server Error: Internal server error

Devices

Operations to query the available IoT devices.

These endpoints let you:

  • Get the list of devices
  • Query the measurements available for each device

List devices

Returns the list of devices available for your API key.

Behavior:

  • Without parameters: returns all available devices
  • With includeMeasures=true: includes the measurements available for each device

Performance:

  • Without includeMeasures: fast query, ideal for long lists
  • With includeMeasures=true: slower query, use only when needed

Usage examples:

  • Simple list: GET /devices
  • With measurements: GET /devices?includeMeasures=true

Authorization: ApiKeyAuth

Query parameters

includeMeasures boolean · Default: false · Example: includeMeasures=true

If true, includes the measurements available for each device in the available_measures field.

When to use it:

  • When you need to know which measurements are available before making data calls
  • When you want to show users the available options

When NOT to use it:

  • When you only want the device list (faster)
  • When you already have information about the available measurements

Responses

  • 200 · Device list returned successfully
  • 400 · Invalid request. Common causes: missing or malformed parameters, out-of-range values, invalid date format, empty or oversized array
  • 401 · Unauthorized, authentication failed. Causes: API key missing from the x-api-key header, invalid or expired API key, API key not linked to a valid Usage Plan
  • 403 · Access denied, insufficient permissions
  • 500 · Internal server error. Retry the request after a few seconds; if the problem persists, contact support and include the requestId if available in your logs

get /devices

Data

Operations to access device data.

These endpoints let you:

  • Get the latest available value for a device
  • Get the latest values from multiple devices in a single call
  • Query historical data at different granularities
  • Filter by measurement type and sensor

Latest device value

Returns the latest available value for a specific device.

Behavior by parameters:

  • Without parameters (GET /devices/{deviceId}/last): returns all measurements from the latest available timestamp. Format: object with device_id, timestamp and a data array. Useful when you want to see all simultaneous measurements
  • With measure (GET /devices/{deviceId}/last?measure=temperature): returns only that measurement. If multiple sensors share the same measure, all of them are returned. Format: single object or array (if multiple sensors)
  • With measure and sensorType (GET /devices/{deviceId}/last?measure=temperature&sensorType=in100-q1-r-rc0i): returns only that specific sensor. Format: single object

Usage examples:

  • All measurements: GET /devices/aa:bb:cc:dd:ee:ff/last
  • Temperature only: GET /devices/aa:bb:cc:dd:ee:ff/last?measure=temperature
  • Specific sensor: GET /devices/aa:bb:cc:dd:ee:ff/last?measure=temperature&sensorType=in100-q1-r-rc0i

Authorization: ApiKeyAuth

Path parameters

deviceId required string ^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$ · Example: aa:bb:cc:dd:ee:ff

Device ID (MAC address in XX:XX:XX:XX:XX:XX format). Separator: colon (:). Case insensitive.

Query parameters

  • measure string · Example: measure=temperature. Filters by measurement type. Accepted values: any measurement type returned by the sensors (e.g. temperature, humidity, pressure, co2, battery_percentage, battery_voltage, rssi, a_current, b_current, c_current, total_current, a_voltage, b_voltage, c_voltage, a_act_power, b_act_power, c_act_power, total_act_power, etc.) or "all" to return all measurements. The value must exactly match the measure field returned by the sensors (case-sensitive)
  • sensorType string · Example: sensorType=in100-q1-r-rc0i. Filters by sensor type. Examples: in100-q1-r-rc0i (internal temperature sensor), sht40-ad1b-r2 (external temperature sensor), dht22 (humidity/temperature sensor). Note: must be used together with measure to be effective

Responses

  • 200 · Latest value(s) returned successfully
  • 400 · Invalid request
  • 401 · Unauthorized, authentication failed
  • 403 · Access denied, insufficient permissions
  • 404 · Resource not found. Causes: nonexistent device ID, device not accessible with your API key, no data available for the requested device. Note: if the device exists but has no data, you will still get a 404
  • 500 · Internal server error

get /devices/{deviceId}/last

Example response (with measure and sensorType, single object):

{
  "timestamp": "2026-02-04T15:30:00Z",
  "device_id": "aa:bb:cc:dd:ee:ff",
  "sensor_type": "in100-q1-r-rc0i",
  "measure": "temperature",
  "unit": "C",
  "value": 22.5
}

Latest values from multiple devices

Returns the latest values from multiple devices in a single call.

Benefits:

  • Reduces the number of HTTP calls needed
  • More efficient when reading data from many devices
  • Keeps the same filtering logic as /devices/{deviceId}/last

Limitations:

  • Maximum 100 devices per request
  • Longer timeout for large lists

Behavior:

  • Without measure: returns all measurements for each device
  • With measure: returns only that measurement for each device
  • With measure and sensorType: returns only that sensor for each device

Usage examples:

  • All devices, all measurements: POST /devices/last/bulk with {"deviceIds": [...]}
  • All devices, temperature only: POST /devices/last/bulk with {"deviceIds": [...], "measure": "temperature"}
  • Specific sensor: POST /devices/last/bulk with {"deviceIds": [...], "measure": "temperature", "sensorType": "in100-q1-r-rc0i"}

Authorization: ApiKeyAuth

Request Body schema: application/json

  • deviceIds required Array of strings [ 1 .. 100 ] items · List of device IDs to query. Minimum: 1 device. Maximum: 100 devices. Format: array of strings (MAC address)
  • measure string · Filters by measurement type (optional). If omitted, returns all measurements for each device
  • sensorType string · Filters by sensor type (optional). Must be used together with measure to be effective

Responses

  • 200 · Latest values returned successfully
  • 400 · Invalid request
  • 401 · Unauthorized, authentication failed
  • 403 · Access denied, insufficient permissions
  • 500 · Internal server error

post /devices/last/bulk

Example request:

{
  "deviceIds": ["aa:bb:cc:dd:ee:ff", "11:22:33:44:55:66", "ff:ee:dd:cc:bb:aa"]
}

Example response:

{
  "results": [{}, {}],
  "count": 2,
  "requested": 2
}

Device historical data

Returns a device's historical data within a specified time range.

Available granularities:

  • raw (default): Raw data with no aggregation. Each row is a single measurement. Maximum time precision, more data returned
  • 15m: Data aggregated every 15 minutes. Each row contains average, minimum and maximum. Significantly reduces data volume
  • 1h: Hourly aggregated data. Each row contains average, minimum and maximum. Even more compact
  • 1d: Daily aggregated data. Each row contains the day's average, minimum and maximum. Minimum data volume

Pagination:

  • Use limit to control how many results you get (max 100)
  • Use offset to move between pages
  • The response includes pagination.hasMore to tell you whether more data exists

Filters:

  • measure: Filters by measurement type
  • sensorType: Filters by sensor type (must be used with measure)

Usage examples:

  • Full history: GET /devices/{id}/history?startDate=...&endDate=...
  • Temperature only: GET /devices/{id}/history?startDate=...&endDate=...&measure=temperature
  • Specific sensor: GET /devices/{id}/history?startDate=...&endDate=...&measure=temperature&sensorType=in100-q1-r-rc0i
  • Aggregated data: GET /devices/{id}/history?startDate=...&endDate=...&granularity=1d

Authorization: ApiKeyAuth

Path parameters

deviceId required string ^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$ · Example: aa:bb:cc:dd:ee:ff. Device ID (MAC address)

Query parameters

  • startDate required string <date-time> · Example: startDate=2026-02-04T00:00:00Z. Start date/time of the range (ISO 8601, UTC)
  • endDate required string <date-time> · Example: endDate=2026-02-04T23:59:59Z. End date/time of the range (ISO 8601, UTC). Note: must be later than startDate
  • granularity string · Default: "raw" · Enum: "raw" "15m" "1h" "1d". Granularity of the returned data
  • measure string · Example: measure=temperature. Filters by measurement type
  • sensorType string · Example: sensorType=in100-q1-r-rc0i. Filters by sensor type (must be used with measure)
  • limit integer [ 1 .. 100 ] · Default: 100 · Example: limit=100. Maximum number of results to return
  • offset integer >= 0 · Default: 0 · Example: offset=0. Number of results to skip (for pagination)

Responses

  • 200 · Historical data returned successfully
  • 400 · Invalid request
  • 401 · Unauthorized, authentication failed
  • 403 · Access denied, insufficient permissions
  • 404 · Resource not found
  • 500 · Internal server error

get /devices/{deviceId}/history

Example response (granularity=raw):

{
  "data": [{}, {}, {}],
  "pagination": {
    "limit": 100,
    "offset": 0,
    "total": 96,
    "hasMore": true,
    "returned": 96
  },
  "granularity": "raw"
}

High-frequency data

Operations to access the CSV files of high-frequency device data.

These endpoints let you:

  • List the available high-frequency CSV data files
  • Download the CSV files through pre-signed S3 URLs
  • Filter files by date, hour and device
  • Monitor daily download quotas

List high-frequency CSV files

Returns a list of the CSV files available for high-frequency device data, with pre-signed S3 URLs for download.

⚠️ Important: This endpoint is only available if you have high-frequency devices (e.g. motor sensors). If your tenant/site has no high-frequency devices, the API will return a NoHighFrequencyDevices error message.

High-frequency data system:

  • CSV files are created automatically every hour (at minute 10) for the previous hour
  • One file per device per hour (only if data exists)
  • Files are stored in S3 and organized by tenant, device, date and hour
  • Only devices flagged as highfrequency = true are included

Data retention: High-frequency CSV data files are available for 30 days (like raw data).

Download quotas:

  • Each tenant has a daily download limit (backup_hf_daily_download_limit)
  • The limit is shared across all API keys/users within the tenant
  • The quota resets at midnight UTC
  • Every pre-signed URL generation counts toward the daily limit

Default behavior (no deviceId and no hour):

  • Returns only the latest available file for each device (for the selected date, default: current UTC day)
  • Keeps responses small and is ideal for "daily sync" clients

Full-day mode:

  • To retrieve all of the day's files for all devices, use mode=day

Filters:

  • date: Filter by a specific date (YYYY-MM-DD). Default: current day
  • hour: Filter by a specific hour (0-23)
  • deviceId: Filter by a specific device (must belong to your tenant)
  • mode: latest (default) or day

Response format:

  • Files are grouped by device_id, then by hour
  • Each hour contains a pre-signed S3 URL (valid for 15 minutes)
  • Quota information shows the daily limit, usage and remaining downloads

Error cases:

  • If the tenant/site has no high-frequency devices: returns a "NoHighFrequencyDevices" error
  • If the daily quota is exceeded: returns 429 Too Many Requests
  • If the device does not belong to the tenant: returns 403 Forbidden

Authorization: ApiKeyAuth

Query parameters

  • date string ^\d{4}-\d{2}-\d{2}$ · Example: date=2026-02-19. Date to query the high-frequency data files for (YYYY-MM-DD format). Default: current day (UTC)
  • hour integer [ 0 .. 23 ] · Example: hour=15. Hour to filter files by (0-23). Example: 15 for 3:00 PM
  • deviceId string ^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$ · Example: deviceId=ad:6a:f5:ae:c9:b5. Device ID to filter files by (MAC address format). Note: the device must belong to your tenant
  • mode string · Default: "latest" · Enum: "latest" "day" · Example: mode=latest. Response mode: latest (default) returns only the latest available file for each device; day returns all files for the entire day (can be large)

Responses

  • 200 · High-frequency data file list returned successfully
  • 400 · Invalid request parameters
  • 401 · Unauthorized, authentication failed
  • 403 · Access denied, missing permission or device not belonging to the tenant
  • 404 · Device not found
  • 429 · Daily download quota exceeded
  • 500 · Internal server error

get /backup_files_highfrequency

Example response (success with files):

{
  "files": {
    "ad:6a:f5:ae:c9:b5": {}
  },
  "quota": {
    "dailyLimit": 100,
    "usedToday": 3,
    "remaining": 97,
    "resetAt": "2026-02-20T00:00:00.000Z"
  }
}

Request a free test

We reply within one working day. No commitment.

Loading the form…

Data sent through this form is processed as described in our privacy policy. The form is hosted by Tally.