Guide
Simple run for agents
A run from a location and a system size: the fields, their defaults, the losses, the weather and the answer
What it is
The simple request runs a PV system from its location and its size, for a caller without module, inverter or weather files. POST /v1/run/simple expands it into a full run request, runs it, and returns the answer with that request and every value it assumed. This page lists each field, its default and the default's source.
The smallest request
{"latitude": 39.8, "longitude": -89.85, "system_capacity_kw": 8}
curl -X POST https://pvperf.com/v1/run/simple -H "Authorization: Bearer pvp_live_…" -H "Content-Type: application/json" -d '{"latitude": 39.8, "longitude": -89.85, "system_capacity_kw": 8}'
These three fields are enough. Instead of system_capacity_kw you can send modules with module_power_w; three sizes must agree within 0.5 %. The MCP tool simulate_simple takes the same body.
Fields and defaults
| Field | Unit | If not given | Source |
|---|---|---|---|
latitude |
° north | required | — |
longitude |
° east | required | — |
system_capacity_kw |
kW DC at STC | modules × module_power_w |
— |
modules |
count | the capacity over the module power, rounded to whole modules | — |
module_power_w |
W at STC, at most 2,000 | the capacity over the modules; with the capacity alone, close to 500 W so that the modules are whole and the DC nameplate is exact | — |
module_type |
standard, premium, thin_film | standard | PVWatts version 8 |
module_efficiency |
fraction | 0.19 standard, 0.21 premium, 0.18 thin film | PVWatts version 8 (SSC cmod_pvwattsv8.cpp) |
temperature_coefficient |
1/°C | −0.0037 standard, −0.0035 premium, −0.0032 thin film | PVWatts version 8 (SSC cmod_pvwattsv8.cpp) |
bifaciality |
fraction | 0, a monofacial module | — |
racking |
fixed, rooftop, single_axis | fixed | — |
tilt_deg |
° | 20 for fixed and rooftop; 0 for a tracker axis | the array section's default |
azimuth_deg |
° clockwise from north | 180 on or north of the equator, 0 south of it; 180 for a tracker axis | the array section's default |
gcr |
fraction | 0.4 | the array section's default; PVWatts version 8 API |
dc_ac_ratio |
DC over AC | 1.2 | PVWatts version 8 API |
inverter_ac_kw |
kW AC; the DC kW over it above 0.5 and at most 3 | the DC kW over dc_ac_ratio |
— |
inverter_efficiency |
fraction | 0.96, that is 96 % | PVWatts version 8 API |
inverter_model |
flat, pvwatts | flat | — |
losses_percent |
% | 11.42 | PVWatts's default categories without shading, snow and age (Dobos 2014) |
weather |
inline, or {"id": "met_…"} |
the typical year at the coordinates, from weather_source |
NSRDB or PVGIS |
weather_source |
auto, nsrdb or pvgis | auto: the NSRDB GOES TMY in the Americas, else the PVGIS 5.3 TMY | — |
timezone |
h | the location's standard time (its IANA zone; round(longitude / 15) at sea) | the clock of the hourly answer |
elevation |
m | the typical year's elevation of the location; 0 with your own weather | NSRDB or PVGIS |
albedo |
fraction | 0.2 | the site section's default |
include_series |
true or false | false | — |
What the run assumes
- Module: the PVWatts DC model (page
step.module.pvwatts). The power is the nameplate power times the irradiance over 1,000 W/m², corrected by the temperature coefficient. It has no low-light loss and no current-voltage curve. - Size: whole modules in one inverter block. The stringing is recorded in the request; the PVWatts DC model does not read it.
- Inverter: one inverter of the AC nameplate. The efficiency is flat, 96 % unless given (page
step.inverter_efficiency.flat), or the PVWatts part-load curve withinverter_model: "pvwatts"(pagestep.inverter_efficiency.pvwatts). The output clips at the AC nameplate (pagestep.inverter_limits.ac_clip). - Racking:
fixedis rows with row-to-row shading at the GCR;rooftopis modules flush on a roof, with no row-to-row shading and a heat-loss factor of 20 W/m²K;single_axisis trackers with backtracking. - Every other step: the pvperf path (page
tree). The answer'srequestshows each choice.
Losses
| PVWatts category | Default | Request field |
|---|---|---|
| Soiling | 2 % | site.soiling_monthly |
| Mismatch | 2 % | dc_losses.module_mismatch_loss |
| Wiring and connections | 2 % and 0.5 %, 2.49 % together | dc_losses.dc_wiring_loss_at_stc, flat |
| Light-induced degradation | 1.5 % | dc_losses.lid_loss |
| Nameplate rating | 1 % | dc_losses.quality_loss |
| Availability | 3 % | ac_losses.unavailability_loss |
- The seven categories total 11.42 %. PVWatts's own default, 14.08 %, adds 3 % shading.
- pvperf computes the row-to-row shading from the racking, the snow (off by default) and the temperature. It does not take them from this total.
- With
losses_percent, each category is scaled by one factor so that they total that value: 14 % gives soiling 2.48 % and availability 3.72 %. - A PVWatts user's 14 % includes 3 % shading; 11.4 % here is the same assumption.
Weather
Without weather, the run uses a typical meteorological year at the coordinates rounded to 0.01°. weather_source picks it; the answer's defaults_applied entry for weather and the year's meta.source and meta.radiation_db name the one used.
auto(the default): in the Americas (the GOES satellites' coverage, latitude −60° to 61°, longitude −180° to −20°) the NSRDB GOES TMY v4, else the PVGIS 5.3 TMY. Where NSRDB has no year for the point or does not answer, the PVGIS year is used and the year'smeta.notessays why.nsrdb: the NSRDB GOES TMY v4 only. A point NSRDB refuses is a 422weather_location_unavailable.pvgis: the PVGIS 5.3 TMY only.
The two years:
- NSRDB GOES TMY v4 (National Laboratory of the Rockies, formerly NREL): satellite-derived irradiance from the GOES satellites (Physical Solar Model v4, 4 km), each month taken from the year that best represents it. pvperf keeps its own copy of the 2025 edition NSRDB publishes on AWS Open Data (2,018,267 sites) and uses the site nearest the point; a point farther than 0.1° from every site (at sea, outside the coverage) has no NSRDB year. NSRDB labels the rows in UTC at the half hour; pvperf rolls them onto the site's standard time and stores them at each hour's start, and the sun runs on that zone. No 29 February.
- PVGIS 5.3 TMY (European Commission, Joint Research Centre): built by ISO 15927-4 from PVGIS-SARAH3 radiation where SARAH3 covers (Europe, Africa, most of Asia) and PVGIS-ERA5 radiation elsewhere, with ERA5 temperature, humidity, wind and pressure. In the Americas its radiation is PVGIS-ERA5, a reanalysis, not satellite-derived data. PVGIS stamps its rows in UTC; pvperf stores the year labelled at each hour's start in UTC + round(longitude / 15) h, after PVGIS's irradiance time offset, and the sun runs on that zone.
For both:
- Each year is fetched once per location and source, and stored. Its id is in the answer's
request.weather;GET /v1/weather/tmy?latitude=…&longitude=…&source=…returns it with the hourly values (fields=metawithout them). - One address may fetch up to 30 new locations an hour, by either route. A location fetched before is not limited. The stored years are not listed by
GET /v1/components. - The answer is on
timezone's clock (by default the location's standard time, from its IANA zone). Where the year's zone differs, every hourly value moves by the difference and the summary says so. The year starts on 1 January. - The source's horizon is not applied. A full request takes a horizon profile from
GET /v1/geo/horizon. - A location neither source covers is a 422
weather_location_unavailable. A source not answering is a 503geo_unavailable. Neither is charged. Send your own weather in either case: for measured data or another year, upload the file toPOST /v1/parse-weatherand send its id asweather.
The answer
The answer is that of POST /v1/run with two more keys:
request: the full request the run used. Send it, edited, toPOST /v1/runto change any input or method. Its weather is the stored id, so it is small. The PVWatts DC model sits inmodule.modeland the inverter law ininverter.efficiency_interpolation, so a library or PAN module, or a library or OND inverter, sent by id in their place runs its own model.defaults_applied: each value the expansion chose that you did not send, as{"field", "value", "source"}. The field is the path inrequest. One entry is namedsystem_capacity_kw: when whole modules ofmodule_power_wcannot make the capacity within 0.5 %, its value is the DC kW the run uses.
summary.e_grid_kwh is the energy to the grid for the year, summary.specific_yield_kwh_per_kwp the yield and loss_diagram every loss row. With an API key the run is stored (links.run) and charged in units like POST /v1/run. A simple run on the hourly typical year is 1 unit. Fixed, rooftop and single-axis racking take the same units. The answer's billing block gives the units, their reasons and the price. GET /v1/pricing gives the rules.
Refusals and their fixes
| Answer | Cause | Fix |
|---|---|---|
422 validation_error, field system_capacity_kw |
no size, or three sizes that disagree | send system_capacity_kw, or modules with module_power_w |
422 validation_error, field modules |
the capacity over the modules is above 2,000 W a module | send more modules, or module_power_w |
422 validation_error, field bifaciality |
a bifacial module on rooftop racking |
use fixed or single_axis, or bifaciality 0 |
422 validation_error, field modules |
a module count above 100,000 with no factor of 100 or less | send a count with a small factor |
422 validation_error, field temperature_coefficient or module_efficiency |
a value in percent | send fractions: -0.0035 for -0.35 %/°C, 0.19 for 19 % |
422 validation_error, field inverter_ac_kw |
the DC kW over inverter_ac_kw is 0.5 or less, or above 3 |
send the AC nameplate in kW: 7.6 for a 7,600 W inverter |
422 weather_location_unavailable |
PVGIS has no data for the location | send weather |
503 geo_unavailable |
PVGIS did not answer | retry, or send weather |
429 rate_limited |
more than 30 new weather locations in an hour from one address | wait, use a location fetched before, or send weather |
| 401, 402 | as POST /v1/run |
an API key, free units or a wallet top-up |
References
- Dobos 2014, PVWatts Version 5 Manual, NREL/TP-6A20-62641
- NREL 2026, PVWatts V8 API documentation, developer.nlr.gov/docs/solar/pvwatts/v8/ (the defaults of dc_ac_ratio, gcr and inv_eff)
- NREL SAM Simulation Core (SSC) source code, release 2026.7.3, github.com/NatLabRockies/ssc: ssc/cmod_pvwattsv8.cpp, the temperature coefficient and the efficiency of each module type
- European Commission Joint Research Centre 2026, PVGIS 5.3 API non-interactive service and TMY generator, joint-research-centre.ec.europa.eu/photovoltaic-geographical-information-system-pvgis
- ISO 15927-4:2005, Hygrothermal performance of buildings — Calculation and presentation of climatic data — Part 4: Hourly data for assessing the annual energy use for heating and cooling
- Sengupta, Xie, Lopez, Habte, Maclaurin & Shelby 2018, The National Solar Radiation Data Base (NSRDB), Renewable and Sustainable Energy Reviews 89 51–60
- National Laboratory of the Rockies (formerly NREL), GOES TMY: PSM v4 Download API (developer.nlr.gov/docs/solar/nsrdb/nsrdb-GOES-tmy-v4-0-0-download)