The Yield Simulation API allows you to run a photovoltaic yield simulation by submitting a structured JSON payload.
The payload describes:
This guide explains how to prepare the request payload for a standard monofacial PV yield simulation.
The current public version of the Yield Simulation API supports monofacial PV systems.
The current API supports:
The current public API does not expose:
The DC capacity and DC/AC ratio are computed automatically from the module power, number of modules per string, number of strings, and inverter nominal power.
POST /api/analytics-protocol/pv-yield/run
The request body must be a JSON object.
The payload has five main top-level sections:
{
"analysis": {},
"module_types": [],
"inverter_types": [],
"plane_of_arrays": [],
"inverters": []
}
| Section | Purpose |
|---|---|
analysis |
Site, weather period, models, and losses |
module_types |
PV module definitions |
inverter_types |
Inverter definitions |
plane_of_arrays |
Mounting geometry definitions |
inverters |
Electrical layout connecting modules, planes, and inverters |
The API uses a catalogue and reference structure.
First, you define reusable objects:
Then, inside the inverters section, you reference these objects by name.
Names are case-sensitive and must match exactly.
{
"analysis": {
"name": "Test_Lusim3D",
"location": {
"latitude": 50.8264,
"longitude": 4.4008,
"altitude": 88.04,
"timezone": "UTC",
"albedo": {
"albedo_avg": 0.2
}
},
"time_vectors": {
"start": "2020-01-01",
"end": "2020-12-31",
"simulation_freq": "H",
"meteo_file": {
"type": "LUC_TMY_P50",
"correct_timeshift": 0
}
},
"system": {
"phi": 0
},
"detailed_losses": {
"ac_wiring_loss": {
"nom_power_reference_ac_wiring_lss": "INV_DC_PWR",
"lss": 0.0
},
"dc_wiring_loss": {
"lss": 0.005
},
"auxiliaries_loss": 0.0,
"availability_grid_lss": 0.0,
"availability_pv_plant_loss": 0.0,
"eff_shading_factor_loss": 0.01,
"global_transformer_losses": 0.0,
"global_transformer_losses_components": {
"iron_losses": null,
"cupper_losses": null
},
"iam_loss": {
"lss": null
},
"lid_loss": 0.01,
"mismatch_bifacial_lss": null,
"mismatch_electric_tolerance_loss": 0.02,
"mutual_shading_lss": null,
"near_object_shading_lss": 0.02,
"power_line_loss": 0.0,
"snow_losses": 0.0,
"soiling_losses": 0.02,
"ShdDLss": null,
"ShdALss": null,
"spectral_lss": {
"lss": 0
}
},
"models": {
"iam_models": [
{
"model_name": "ashrae",
"status": true,
"b0_ashrae": 0.03
},
{
"model_name": "martin_ruiz",
"status": false
}
],
"model_diffuse": "erbs",
"model_inverter_efficiency": "generic_efficiency_curve",
"model_temp_cell": [
{
"model_name": "pvsyst",
"status": true,
"mounting_type": "insulated"
},
{
"model_name": "sapm",
"status": false,
"mounting_type": "close_mount_glass_glass"
},
{
"model_name": "ross",
"status": false
},
{
"model_name": "noct_lusim",
"status": false,
"mounting_type": null
}
],
"spectral_models": [
{
"model_name": "first_solar",
"status": true
},
{
"model_name": "sapm",
"module_fom_Sandia_db": "Aleo_S03_165__2007__E__",
"status": false
}
]
}
},
"module_types": [
{
"module_name": "ETSolar_M672BH_450TW",
"module_definition": {
"module_unit_power": 450,
"ETA_1000": 0.2070325,
"ETA_200": 0.2008215,
"GAMMA_TC": -0.00331,
"NOCT": 45,
"P_PEAK_TOL": 0,
"TRANSM": 1,
"Vmpp": 41.5,
"eta_m": 0.2070325,
"alpha_absorption": 0.9,
"bifaciality_factor": null
}
}
],
"inverter_types": [
{
"inverter_name": "Sungrow_125HX",
"inverter_definition": {
"INV_MOD": "Sungrow_125HX",
"INV_POW": 125,
"euro_eff": 0.982,
"PMaxOUT": 125
}
}
],
"plane_of_arrays": [
{
"axis_name": "axis_1",
"axis_height_ground": null,
"azimuth": 0,
"tilt": 45,
"tracker": true,
"max_angle": 60,
"pitch": 6.7,
"length_module": 2.094,
"gcr": null
}
],
"inverters": [
{
"inverter_type": "Sungrow_125HX",
"multiplier": 1,
"arrays": [
{
"array_name": "array_1",
"plane_of_array": "axis_1",
"module_type": "ETSolar_M672BH_450TW",
"modules_in_string": 27,
"number_of_strings": 11,
"ac_wiring_ohmic_losses_nom_power": {
"lss": null,
"nom_power_reference_ac_wiring_lss": null
},
"dc_wiring_ohmic_loss_nom_power": {
"lss": null
}
}
]
}
]
}
nullUse JSON null when a value is intentionally not provided.
Correct:
"bifaciality_factor": null
Avoid:
"bifaciality_factor": "None"
Do not use "None", empty strings, or placeholder values for missing numeric fields.
Loss values are expressed as fractions.
Examples:
| Value | Meaning |
|---|---|
0.00 |
0% |
0.005 |
0.5% |
0.01 |
1% |
0.02 |
2% |
Example:
"soiling_losses": 0.02
means a 2% soiling loss.
Do not use 2 when you mean 2%.
The payload uses references between sections.
These names must match exactly:
| Reference | Must match |
|---|---|
inverters[].inverter_type |
inverter_types[].inverter_name |
inverters[].arrays[].module_type |
module_types[].module_name |
inverters[].arrays[].plane_of_array |
plane_of_arrays[].axis_name |
Example:
"module_name": "ETSolar_M672BH_450TW"
must be referenced as:
"module_type": "ETSolar_M672BH_450TW"
analysisThe analysis section defines the study name, site, simulation period, weather source, system-level settings, losses, and models.
"analysis": {
"name": "Test_Lusim3D",
"location": {},
"time_vectors": {},
"system": {},
"detailed_losses": {},
"models": {}
}
Site information is defined in:
"analysis": {
"location": {}
}
Example:
"location": {
"latitude": 50.8264,
"longitude": 4.4008,
"altitude": 88.04,
"timezone": "UTC",
"albedo": {
"albedo_avg": 0.2
}
}
| Field | Type | Required | Description |
|---|---|---|---|
latitude |
number | Yes | Site latitude in decimal degrees |
longitude |
number | Yes | Site longitude in decimal degrees |
altitude |
number | Yes | Site altitude in metres above sea level |
timezone |
string | Yes | Use "UTC" unless instructed otherwise |
albedo.albedo_avg |
number | Yes | Average ground reflectance, from 0 to 1 |
Typical albedo values:
| Surface | Typical value |
|---|---|
| Dark ground | 0.10 to 0.15 |
| Grass or soil | 0.15 to 0.25 |
| Concrete | 0.20 to 0.35 |
| Bright surface | 0.30 to 0.50 |
For a standard first simulation, use:
"albedo_avg": 0.2
Simulation period and weather source are defined in:
"analysis": {
"time_vectors": {}
}
Example:
"time_vectors": {
"start": "2020-01-01",
"end": "2020-12-31",
"simulation_freq": "H",
"meteo_file": {
"type": "LUC_TMY_P50",
"correct_timeshift": 0
}
}
| Field | Type | Required | Description |
|---|---|---|---|
start |
string | Yes | Start date, format YYYY-MM-DD |
end |
string | Yes | End date, format YYYY-MM-DD |
simulation_freq |
string | Yes | Use "H" for hourly simulation |
meteo_file.type |
string | Yes | Weather source |
meteo_file.correct_timeshift |
number | Yes | Time correction in minutes. Use 0 by default |
| Value | Description | Recommended use |
|---|---|---|
"LUC_TMY_P50" |
LuData typical meteorological year, P50 | Recommended default |
"LUC_TMY_P90" |
LuData conservative TMY | Conservative sensitivity |
"LUC_TMY_P95" |
LuData TMY Percentile 95 | Highly conservative sensitivity |
For most first simulations, use:
"type": "LUC_TMY_P50"
System-level parameters are defined in:
"analysis": {
"system": {
"phi": 0
}
}
| Field | Type | Required | Description |
|---|---|---|---|
phi |
number | Yes | Power factor angle in degrees. Use 0 for standard active power simulations |
Recommended default:
"phi": 0
Losses are defined in:
"analysis": {
"detailed_losses": {}
}
The recommended starting configuration is:
"detailed_losses": {
"ac_wiring_loss": {
"nom_power_reference_ac_wiring_lss": "INV_DC_PWR",
"lss": 0.0
},
"dc_wiring_loss": {
"lss": 0.005
},
"auxiliaries_loss": 0.0,
"availability_grid_lss": 0.0,
"availability_pv_plant_loss": 0.0,
"eff_shading_factor_loss": 0.01,
"global_transformer_losses": 0.0,
"global_transformer_losses_components": {
"iron_losses": null,
"cupper_losses": null
},
"iam_loss": {
"lss": null
},
"lid_loss": 0.01,
"mismatch_bifacial_lss": null,
"mismatch_electric_tolerance_loss": 0.02,
"mutual_shading_lss": null,
"near_object_shading_lss": 0.02,
"power_line_loss": 0.0,
"snow_losses": 0.0,
"soiling_losses": 0.02,
"ShdDLss": null,
"ShdALss": null,
"spectral_lss": {
"lss": 0
}
}
| Field | Suggested value | Description |
|---|---|---|
soiling_losses |
0.02 |
Soiling loss |
lid_loss |
0.01 |
Light-induced degradation loss |
mismatch_electric_tolerance_loss |
0.02 |
Electrical mismatch loss |
near_object_shading_lss |
0.02 |
Loss from nearby objects or horizon effects |
eff_shading_factor_loss |
0.01 |
Simplified effective shading loss |
dc_wiring_loss.lss |
0.005 |
DC wiring loss |
ac_wiring_loss.lss |
0.0 |
AC wiring loss |
availability_pv_plant_loss |
0.0 |
PV plant unavailability |
availability_grid_lss |
0.0 |
Grid unavailability or curtailment |
power_line_loss |
0.0 |
Power line loss |
snow_losses |
0.0 |
Snow loss |
global_transformer_losses |
0.0 |
Transformer loss |
auxiliaries_loss |
0.0 |
Auxiliary consumption |
null in the current public APIKeep the following fields as null unless instructed otherwise:
"mismatch_bifacial_lss": null,
"mutual_shading_lss": null,
"ShdDLss": null,
"ShdALss": null
For monofacial simulations, mismatch_bifacial_lss must remain:
"mismatch_bifacial_lss": null
Physical models are defined in:
"analysis": {
"models": {}
}
Recommended model configuration:
"models": {
"iam_models": [
{
"model_name": "ashrae",
"status": true,
"b0_ashrae": 0.03
},
{
"model_name": "martin_ruiz",
"status": false
}
],
"model_diffuse": "erbs",
"model_inverter_efficiency": "generic_efficiency_curve",
"model_temp_cell": [
{
"model_name": "pvsyst",
"status": true,
"mounting_type": "insulated"
},
{
"model_name": "sapm",
"status": false,
"mounting_type": "close_mount_glass_glass"
},
{
"model_name": "ross",
"status": false
},
{
"model_name": "noct_lusim",
"status": false,
"mounting_type": null
}
],
"spectral_models": [
{
"model_name": "first_solar",
"status": true
},
{
"model_name": "sapm",
"module_fom_Sandia_db": "Aleo_S03_165__2007__E__",
"status": false
}
]
}
| Field | Recommended value | Description |
|---|---|---|
model_diffuse |
"erbs" |
Diffuse irradiance model |
model_inverter_efficiency |
"generic_efficiency_curve" |
Inverter efficiency model |
| IAM model | "ashrae" active |
Incidence angle modifier |
| Temperature model | "pvsyst" active |
Cell temperature model |
| Spectral model | "first_solar" active |
Spectral correction model |
Use exactly one active IAM model:
{
"model_name": "ashrae",
"status": true
}
and keep the other IAM models inactive:
{
"model_name": "martin_ruiz",
"status": false
}
Use exactly one active cell temperature model.
Use at most one active spectral model.
Modules are defined in:
"module_types": []
Example:
"module_types": [
{
"module_name": "ETSolar_M672BH_450TW",
"module_definition": {
"module_unit_power": 450,
"ETA_1000": 0.2070325,
"ETA_200": 0.2008215,
"GAMMA_TC": -0.00331,
"NOCT": 45,
"P_PEAK_TOL": 0,
"TRANSM": 1,
"Vmpp": 41.5,
"eta_m": 0.2070325,
"alpha_absorption": 0.9,
"bifaciality_factor": null
}
}
]
| Field | Type | Required | Description |
|---|---|---|---|
module_name |
string | Yes | Module identifier used in array definitions |
module_unit_power |
number | Yes | Module nominal power in Wp |
ETA_1000 |
number | Yes | Module efficiency at 1000 W/m2 |
ETA_200 |
number | Yes | Module efficiency at 200 W/m2 |
GAMMA_TC |
number | Yes | Temperature coefficient in 1/ degreesC |
NOCT |
number | Yes | Nominal operating cell temperature in degreesC |
P_PEAK_TOL |
number | Yes | Peak power tolerance |
TRANSM |
number | Yes | Module transmittance. Use 1 for standard opaque modules |
Vmpp |
number | Yes | Voltage at maximum power point |
eta_m |
number | Yes | Module efficiency used by the thermal model |
alpha_absorption |
number | Yes | Absorption coefficient, typically around 0.9 |
bifaciality_factor |
null | Yes | Must be null for current monofacial simulations |
The current public API supports monofacial simulations only.
Always set:
"bifaciality_factor": null
Do not use numeric bifaciality values in the current public API version.
Inverters are defined in:
"inverter_types": []
Example:
"inverter_types": [
{
"inverter_name": "Sungrow_125HX",
"inverter_definition": {
"INV_MOD": "Sungrow_125HX",
"INV_POW": 125,
"euro_eff": 0.982,
"PMaxOUT": 125
}
}
]
| Field | Type | Required | Description |
|---|---|---|---|
inverter_name |
string | Yes | Inverter identifier used in the layout |
INV_MOD |
string | Yes | Inverter model name |
INV_POW |
number | Yes | Nominal inverter AC power in kW |
euro_eff |
number | Yes | European weighted efficiency, from 0 to 1 |
PMaxOUT |
number | Yes | Maximum AC output power in kW |
Recommended inverter model:
"model_inverter_efficiency": "generic_efficiency_curve"
Mounting geometry is defined in:
"plane_of_arrays": []
Example:
"plane_of_arrays": [
{
"axis_name": "axis_1",
"axis_height_ground": null,
"azimuth": 0,
"tilt": 45,
"tracker": true,
"max_angle": 60,
"pitch": 6.7,
"length_module": 2.094,
"gcr": null
}
]
| Field | Type | Required | Description |
|---|---|---|---|
axis_name |
string | Yes | Geometry identifier used by arrays |
axis_height_ground |
number or null | No | Keep null unless instructed otherwise |
azimuth |
number | Yes | Plane azimuth in degrees |
tilt |
number | Yes | Plane tilt in degrees |
tracker |
boolean | Yes | true for tracker, false for fixed tilt |
max_angle |
number or null | Conditional | Tracker maximum rotation angle. Use null for fixed tilt |
pitch |
number or null | Conditional | Row pitch in metres |
length_module |
number or null | Conditional | Module length or row width in metres |
gcr |
number or null | Conditional | Ground coverage ratio |
{
"axis_name": "axis_1",
"axis_height_ground": null,
"azimuth": 0,
"tilt": 25,
"tracker": false,
"max_angle": null,
"pitch": null,
"length_module": null,
"gcr": 0.4
}
{
"axis_name": "axis_1",
"axis_height_ground": null,
"azimuth": 0,
"tilt": 45,
"tracker": true,
"max_angle": 60,
"pitch": 6.7,
"length_module": 2.094,
"gcr": null
}
If gcr is null, the API derives it from:
gcr = length_module / pitch
Example:
gcr = 2.094 / 6.7 = 0.3125
The electrical layout is defined in:
"inverters": []
Example:
"inverters": [
{
"inverter_type": "Sungrow_125HX",
"multiplier": 1,
"arrays": [
{
"array_name": "array_1",
"plane_of_array": "axis_1",
"module_type": "ETSolar_M672BH_450TW",
"modules_in_string": 27,
"number_of_strings": 11,
"ac_wiring_ohmic_losses_nom_power": {
"lss": null,
"nom_power_reference_ac_wiring_lss": null
},
"dc_wiring_ohmic_loss_nom_power": {
"lss": null
}
}
]
}
]
| Field | Type | Required | Description |
|---|---|---|---|
inverter_type |
string | Yes | Must match an inverter_name |
multiplier |
integer | Yes | Number of identical inverter units |
arrays |
array | Yes | DC arrays connected to this inverter type |
| Field | Type | Required | Description |
|---|---|---|---|
array_name |
string | Yes | Array name used for reporting |
plane_of_array |
string | Yes | Must match a plane_of_arrays[].axis_name |
module_type |
string | Yes | Must match a module_types[].module_name |
modules_in_string |
integer | Yes | Number of modules in series |
number_of_strings |
integer | Yes | Number of parallel strings |
ac_wiring_ohmic_losses_nom_power |
object | Yes | Keep values as null when using global AC wiring loss |
dc_wiring_ohmic_loss_nom_power |
object | Yes | Keep value as null when using global DC wiring loss |
You do not send DC capacity directly.
The API computes it from:
DC capacity [kWp] = modules_in_string x number_of_strings x module_unit_power / 1000
For the example payload:
DC capacity = 27 x 11 x 450 / 1000
DC capacity = 133.65 kWp
The DC/AC ratio is computed from:
DC/AC ratio = DC capacity / inverter nominal AC power
For the example payload:
DC/AC ratio = 133.65 / 125
DC/AC ratio = 1.07
For a first feasibility simulation, the following values are recommended:
| Category | Field | Recommended value |
|---|---|---|
| Weather | meteo_file.type |
"LUC_TMY_P50" |
| Frequency | simulation_freq |
"H" |
| Albedo | albedo_avg |
0.2 |
| IAM model | ashrae.status |
true |
| IAM coefficient | b0_ashrae |
0.03 |
| Diffuse model | model_diffuse |
"erbs" |
| Inverter model | model_inverter_efficiency |
"generic_efficiency_curve" |
| Temperature model | pvsyst.status |
true |
| Spectral model | first_solar.status |
true |
| Soiling | soiling_losses |
0.02 |
| LID | lid_loss |
0.01 |
| DC wiring | dc_wiring_loss.lss |
0.005 |
| AC wiring | ac_wiring_loss.lss |
0.0 |
| Electrical mismatch | mismatch_electric_tolerance_loss |
0.02 |
| Availability | availability_pv_plant_loss |
0.0 |
| Grid unavailability | availability_grid_lss |
0.0 |
These values are generic starting assumptions. For detailed engineering or financing studies, project-specific values should be used.
Before submitting the payload, check that:
analysis.name is defined.latitude, longitude, and altitude are correct.timezone is set to "UTC".start and end use the YYYY-MM-DD format.simulation_freq is set to "H".meteo_file.type is supported.null is used instead of "None".bifaciality_factor is null.mismatch_bifacial_lss is null."status": true."status": true."status": true.module_type matches an existing module_name.inverter_type matches an existing inverter_name.plane_of_array matches an existing axis_name.modules_in_string is a positive integer.number_of_strings is a positive integer.INV_POW and PMaxOUT are given in kW.module_unit_power is given in Wp.| Error | Likely cause | Fix |
|---|---|---|
| Unknown module type | module_type does not match module_name |
Check exact spelling |
| Unknown inverter type | inverter_type does not match inverter_name |
Check exact spelling |
| Unknown plane of array | plane_of_array does not match axis_name |
Check exact spelling |
| Invalid loss values | Loss entered as 2 instead of 0.02 |
Use fractions |
| Invalid null values | "None" used as text |
Use JSON null |
| Bifacial not supported | Numeric bifaciality_factor used |
Set bifaciality_factor to null |
| Missing tracker geometry | tracker is true but gcr, pitch, or length_module is incomplete |
Provide gcr or both pitch and length_module |
| Invalid model configuration | More than one model is active | Keep only one active model per model family |
| Very low or zero yield | Incorrect site, dates, losses, or geometry | Check coordinates, weather source, and loss values |
To create a new simulation payload:
analysis.name.modules_in_string and number_of_strings.The Yield Simulation API is designed for feasibility studies, preliminary design, comparison studies, and early-stage yield assessment.
Results depend on:
For contractual, financing, or bankability studies, assumptions should be reviewed and validated by qualified engineering teams.