Requests and responses
How the Platform API identifies sites, handles time, pages through results, formats responses, and reports errors.
Site IDs
Endpoints identify a site by its project ID, a UUID. To find your project IDs, call List projects:
[{ "id": "3235d25b-6008-452e-a453-62a5f2644ac1", "name": "Example Solar Farm" }]Most endpoints take a single project_id. Get performance data takes one or more project_ids, which must all belong to the same organization.
Query parameters
- To pass several values, repeat the parameter:
?project_ids=a&project_ids=b. - Boolean parameters accept
true,false,1, or0.
Time
Endpoints use two kinds of time, depending on what they return.
Performance and losses
Get performance data and List loss events work in the site's local time, so a day means the site's day.
dt_startanddt_endare dates, such as2026-05-25. The range includes both days in full.- Timestamps in the response, such as
ts, are the site's local time in the formYYYY-MM-DD HH:MM:SS, with no time zone.
Signals and alarms
The signals and alarms endpoints work in absolute time.
- Date-time parameters are ISO 8601 with a time zone offset, such as
2026-05-25T00:00:00Zor2026-05-25T00:00:00-05:00. - Timestamps in the response are UTC.
Intervals
Endpoints that aggregate over time take an interval: OneMinute, FiveMinutes, TenMinutes, FifteenMinutes, ThirtyMinutes, OneHour, OneDay, OneWeek, OneMonth, or OneYear. Get performance data also accepts Full, which returns one value for the whole range.
Pagination
Endpoints that can return many rows use limit and offset:
- Send your first request with
offset=0, or leave it out. - If the response has exactly
limitrows, more might exist. Increaseoffsetbylimit, and send the request again. - When a response has fewer than
limitrows, you've reached the last page.
Each endpoint's reference page lists its default and maximum limit.
Read only what changed
To keep a copy of alarms or signals up to date without reading everything again, use the endpoint's change parameters, such as updated_since for alarms or received_since for signals. Each reference page explains how to resume from the last row you read.
Response formats
Endpoints that return time series let you choose a format with the Accept header:
Accept | Format |
|---|---|
application/vnd.apache.arrow.stream | Apache Arrow IPC stream. This is the default. |
application/vnd.apache.parquet | Apache Parquet. |
application/json-seq | One JSON object per line. |
Arrow and Parquet are the most compact formats, and load directly into tools such as pandas, Polars, and DuckDB. Other endpoints return JSON.
Errors
Errors return a 4xx or 5xx status code. Most error bodies are JSON with a message:
{
"error": {
"message": "The project doesn't exist, or your token can't access it."
}
}A request with invalid parameters returns 400 Bad Request, with the problems listed under error.issues:
{
"error": {
"target": "query",
"issues": [{ "path": ["dt_start"], "message": "Invalid date" }]
}
}| Status | Meaning | What to do |
|---|---|---|
400 | A parameter is missing or invalid. | Fix the request, using error.issues. |
401 | The token is missing, invalid, or expired. | Check the Authorization header, or rotate the token. |
403 | The site doesn't exist, or your account can't access it. | Check the project ID, and your access in DUET. |
404 | The resource doesn't exist. | Check the ID. |
429 | You've sent too many requests. | Wait, and then retry. |
501 | The endpoint is planned and not available yet. | See Planned endpoints. |
5xx | Something went wrong on our side. | Retry with exponential backoff. If it continues, contact your account manager. |
Rate limits
- Platform API (
/platform/v1): 100 requests a minute for each user. - Inbound sync (
/integrations/v1): 300 requests a minute for each set of credentials.
When you exceed a limit, the API returns 429 Too Many Requests. To stay under it, request larger time ranges and pages rather than many small ones.

