DUET PlatformDocs
API referenceRead APIPerformance

Get performance data

available
GET
/platform/v1/performance-v2

Authorization

Bearer
headerAuthorizationBearer <token>

Query Parameters

project_ids*array<string>

One or more DUET project IDs. Repeat the parameter for each ID, for example ?project_ids=a&project_ids=b. You must have access to every project, and all of them must belong to the same organization.

dt_start*string

The first date to include, in ISO 8601 format, for example 2026-05-25. DUET uses the start of that day.

dt_end*string

The last date to include, in ISO 8601 format, for example 2026-05-31. DUET uses the end of that day.

sentinel_tag?string

The deployment tag. Most projects have one deployment, default. A project with several data streams can name a specific deployment.

Default"default"
component*string

The component to query, for example meter, inverter, or met.

Value in"system""block""transformer""feeder""meter""met""inverter""combiner""mppt""tracker""tracker_controller""tracker_motor""bess""bess_section""bess_feeder""bess_block""bess_bus""bess_container""bess_dcc""bess_pcs""bess_rack""bess_meter""bess_ppc"
component_measure*string

The measure to query, for example active_power, energy, or poa_front.

Value in"ghi""temp""poa_front""poa_rear""poa_front_satellite""rh""windspeed""soiling""snow_depth""albedo""active_power""apparent_power""reactive_power""active_power_setpoint""active_power_setpoint_dc_pct""active_power_setpoint_ac_pct""dc_current""dc_voltage""dc_power""energy""energy_setpoint""tracker_motor_position""tracker_motor_setpoint""ghi_insolation""poa_front_insolation""poa_rear_insolation""ppa_revenue""internal_temp""reactive_power_setpoint""frequency""active_energy_delivered""active_energy_received""voltage""current""precipitation""module_temp_back""operating_status""dni""dhi""power_factor""stow_status""oil_temp""cabinet_temp""lv_power""lv_current""lv_frequency""lv_voltage""hv_power""hv_current""hv_frequency""hv_voltage""soc""full_pack_energy""charge_power_available""discharge_power_available""max_battery_temp""ac_current""ac_current_a""ac_current_b""ac_current_c""ac_voltage""ac_voltage_a""ac_voltage_b""ac_voltage_c""ac_voltage_an""ac_voltage_bn""ac_voltage_cn""energy_export""energy_import""full_battery_energy""remaining_battery_energy""dispatchable_charge_power""dispatchable_discharge_power""hw_capable_charge_power""active_power_command_feedback""nominal_charge_power""nominal_discharge_power""active_power_setpoint_local""active_power_setpoint_remote""reactive_power_setpoint_local""reactive_power_setpoint_remote""voltage_setpoint_local""voltage_setpoint_remote""power_factor_setpoint""ambient_temp""max_cell_voltage""min_cell_voltage""total_current""total_voltage""battery_voltage""bus_voltage""soh""min_temp""mean_temp""max_temp""mean_cell_voltage""min_rack_voltage""mean_rack_voltage""max_rack_voltage""ppa_price""apparent_energy""reactive_energy"
time_interval*string

The bucket size for the time series. Full returns the whole range as one bucket that starts at dt_start.

Value in"Full""OneMinute""FiveMinutes""TenMinutes""FifteenMinutes""ThirtyMinutes""OneHour""OneDay""OneWeek""OneMonth""OneYear"
hierarchy_ids?array<string>

Return only these hierarchy IDs, which identify sensors. Repeat the parameter for each ID. Omit it to return all sensors.

block_ids?array<string>

Return only these blocks. Repeat the parameter for each block ID. Omit it to return all blocks.

group_by?array<>

The dimensions to group by: any combination of project_id, block_id, and hierarchy_id. Repeat the parameter for each dimension. DUET rolls up each dimension that you leave out and returns it as null on every row. For example, omit hierarchy_id to get block-level rows. The default is all three, which returns one row for each sensor.

Items1 <= items
use_solar_bounds?boolean

Whether to place readings on a daylight time grid. When true, the default, every daylight bucket is present, even when the sensor reported nothing in it.

Defaulttrue

Header Parameters

Accept?string
Default"application/vnd.apache.arrow.stream"
Value in"application/vnd.apache.arrow.stream""application/vnd.apache.parquet""application/json-seq"

Response Body

A stream of performance time-series rows, one for each group_by key and bucket. The Accept header sets the format: an Arrow IPC stream (the default), Parquet, or JSON-seq, which is newline-delimited JSON objects.

Each row carries sensor_value (measured), model_value (expected), their setpoint-adjusted variants, and performance_index, which is sensor_value / model_value. Dimension columns that group_by leaves out are null.

  1. response
ts*string

The start of the bucket. Format: YYYY-MM-DD HH:MM:SS, in site-local time, with no time zone.

project_id*|

The project ID. Null when group_by doesn't include project_id.

duet_block_id*|

The block ID. Null when group_by doesn't include block_id.

hierarchy_id*|

The hierarchy ID, which identifies the sensor. Null when group_by doesn't include hierarchy_id.

sensor_tag*|

The SCADA sensor tag. Null when group_by doesn't include hierarchy_id.

sentinel_tag*string

The deployment tag that the row belongs to.

portfolio*|

The portfolio that the project belongs to. Null when the project isn't in a portfolio.

component*string

The component from the request.

component_measure*string

The measure from the request.

sensor_value*|

The measured value, aggregated over the bucket. Null when the bucket has no finite samples.

model_value*number

The expected value from the DUET model, aggregated over the bucket. 0 when no model covers the bucket.

sensor_value_setpoint*|

The measured value, adjusted for the active setpoint so that curtailment is accounted for. Null when the bucket has no finite samples.

model_value_setpoint*number

The modeled value, adjusted for the active setpoint. 0 when no model covers the bucket.

performance_index*|

The measured output relative to the expected output: sensor_value / model_value. Null when model_value is 0 or the measured value is missing.

performance_index_setpoint*|

The performance relative to the setpoint-adjusted expected output: sensor_value / model_value_setpoint. Curtailed periods don't count as underperformance.

forecast_value?|

Status: Planned.

The forecast value for the bucket, from the project's DUET model run on forecast weather. The site's grid injection limit is applied, but curtailment isn't. This value is separate from model_value, which is the expected value under measured weather. Null when no forecast covers the bucket.

forecast_issued_at?|

Status: Planned.

The time the forecast behind forecast_value was issued. DUET returns the latest forecast issued before the bucket starts.

Formatdate-time
forecast_lead_time_minutes?|

Status: Planned.

The number of minutes between forecast_issued_at and the start of the bucket.

Example Request
curl -X GET 'https://api.enurgen.com/platform/v1/performance-v2?project_ids=string&dt_start=string&dt_end=string&component=system&component_measure=ghi&time_interval=Full'
Example Response
{  "ts": "string",  "project_id": "string",  "duet_block_id": "string",  "hierarchy_id": "string",  "sensor_tag": "string",  "sentinel_tag": "string",  "portfolio": "string",  "component": "string",  "component_measure": "string",  "sensor_value": 0,  "model_value": 0,  "sensor_value_setpoint": 0,  "model_value_setpoint": 0,  "performance_index": 0,  "performance_index_setpoint": 0,  "forecast_value": 0,  "forecast_issued_at": "2019-08-24T14:15:22Z",  "forecast_lead_time_minutes": 0}