EU PVGIS logo

Open data · Coming soon

Solar PV Yield Estimator with PVGIS

Estimate how much power a solar system makes at each site in your list. It uses the official EU PVGIS 5.3 model. Add your price per kWh to see a rough yearly value.

Built and tested. Prices will be shown after release.

Coming soon to the Apify StoreFollow us on Apify

What you get, for example

siteIndex0
siteNameMunich warehouse roof
latitude48.137

How it will work: 3 steps

  1. Follow us on ApifyThe tool is built and waits in the queue for the Apify Store. Apify is the cloud platform where our tools run.
  2. Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example: [{"name": "Munich warehouse roof", "lat": 48.137, "lon"… in Sites. Each start is one run.
  3. Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.

What it does

Solar PV Yield Estimator (PVGIS) estimates how much electricity a solar PV system will produce at each site in your list, using the official EU PVGIS 5.3 model from the European Commission's Joint Research Centre. For every site you get kWh per year, kWh per kWp, kWh per month, the optimal tilt and azimuth, a loss breakdown, year-to-year variability and an optional value estimate with your own tariff.

  • Yield per site. annualEnergyKwh, specificYieldKwhPerKwp, averageDailyEnergyKwh and 12 monthly values (monthlyEnergyKwh and monthly with irradiation and standard deviation).
  • Optimal angles. Leave out the tilt and azimuth and PVGIS finds the best values for the site. Give only the azimuth (for example a fixed roof direction) and PVGIS finds the best tilt.
  • Both azimuth conventions. Enter azimuths the PVGIS way (0 = south) or as a compass bearing (180 = south). Every row has both azimuthDeg and azimuthCompassDeg.
  • Quality figures. In-plane irradiation, performance ratio, angle-of-incidence, spectral and temperature losses, total loss and year-to-year variability.
  • Value estimate. Add your own price per kWh and each site gets estimatedAnnualValue.
  • Clear status. Each row is complete, not_found (sea or outside the radiation data) or error, with a reason. Invalid sites are reported and skipped; the rest of the list still runs.

Good for

  • Quick yield and kWh/kWp figures for a list of quotes or leads.
  • Comparing orientations or tilts on the same site (one row per variant).
  • Screening many locations for a solar portfolio.
  • Feeding monthly kWh into your own sizing, self-consumption or ROI sheet.

Not a good fit

  • Roof detection, panel layout or near shading from buildings and trees. PVGIS only uses the terrain horizon.
  • Trackers, off-grid systems with batteries, or hourly time series.
  • Tariffs, feed-in rules, taxes, degradation or payback. The value estimate is only kWh × your price.

Who uses it

Solar installers

Put a yield number into a customer quote fast.

Project developers

Screen and rank a long list of sites.

Home owners

Compare two roof directions before you buy.

Price

Prices will be shown after release.

Questions

Is it the same as the PVGIS website?

Yes, for the same inputs. The tool calls the PVGIS 5.3 API and keeps its values.

How exact are the numbers?

They are long-term averages. Real years vary, and shade, snow or dirt can lower output.

Can I use it outside Europe?

Yes. With the auto setting, sites outside the main data set use another database.

Do I need an API key?

No. PVGIS is free and open.

How accurate is this?

It is the same model as the PVGIS website, using long-term satellite or reanalysis data. The figures are averages: single years vary (see annualVariabilityPercent). Real systems also lose output to near shading, snow, soiling and equipment faults that PVGIS does not know about.

What should I use for lossPercent?

PVGIS suggests 14% for a typical system. Use more for long cable runs, old inverters or dusty sites.

Details

Step by step on Apify
  1. Open the Input tab.
  2. Keep the two example sites in sites, or replace them with yours: lat, lon and peakPowerKw for each.
  3. Keep Optimize missing angles on, or add angle and azimuth to a site.
  4. Click Start.
  5. Open the Output tab (Dataset) and check annualEnergyKwh and specificYieldKwhPerKwp.
Use cases
TaskInputKey fieldsNext step
Yield for a quote1 site with lat, lon, peakPowerKwannualEnergyKwh, monthlyEnergyKwhCopy into the offer
Compare roof directionsSame site twice, different azimuth and angleannualEnergyKwh, specificYieldKwhPerKwpPick the better layout
Screen a site listUp to 100 sites with namespecificYieldKwhPerKwp, statusRank or filter in a sheet
Rough revenueSites + tariffPerKwh + currencyestimatedAnnualValueYour own ROI model
Tips for better results
  • Leave tilt and azimuth empty and PVGIS finds the best angles.
  • Start with 14% system loss, as PVGIS suggests. Use more for old or dusty systems.
  • Use the source link in each row to repeat the same request on PVGIS.
Limits and good to know
  • 1 to 100 sites per run. For longer lists, use several runs
  • Sites are computed 3 at a time; 100 sites took about 47 seconds in tests. The internal time budget is 240 seconds; sites left after that get DEADLINE_REACHED and are not charged
  • Fixed (non-tracking), grid-connected systems only. Monthly and yearly averages only, no hourly series
  • PVGIS-SARAH3 covers Europe, Africa and parts of Asia and South America. auto falls back to PVGIS-ERA5 elsewhere (in tests: New York, Tokyo, Sydney). Choosing a database that does not cover a site gives not_found
  • The terrain horizon includes hills and mountains, not nearby buildings or trees
  • If PVGIS fails 3 times in a row (outage, rate limit or timeout), the Actor stops calling it and marks the rest as not computed, so a source outage does not use up your run time

Troubleshooting

SymptomCheckAction
not_found, LOCATION_OVER_SEAlatitude, longitudeCheck the coordinates are on land and lat/lon are not swapped.
not_found, OUTSIDE_DATABASE_COVERAGEradiationDatabase inputUse auto or PVGIS-ERA5.
error, INVALID_SITEstatusReasonFix the field named in the reason.
INVALID_INPUTRUN_SUMMARY.messageAdd at least one site, keep sites at 100 or fewer, check tariffPerKwh and currency.
CAPPEDRUN_SUMMARY.messageRaise the maximum cost per run, or run the remaining sites again.
ERROR or SOURCE_UNAVAILABLE rowsRUN_SUMMARY.http.failuresPVGIS was down or slow. Run the failed sites again later.
Yield looks too lowtiltDeg, azimuthCompassDeg, lossPercentCheck the azimuth convention: in pvgis, 0 is south; in compass, 0 is north.

For developers

Sample result

One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.

one result · JSON
{
  "siteIndex": 0,
  "siteName": "Munich warehouse roof",
  "status": "complete",
  "statusReason": null,
  "errorCode": null,
  "latitude": 48.137,
  "longitude": 11.575,
  "elevationM": 524,
  "peakPowerKw": 5,
  "systemLossPercent": 14,
  "mounting": "free-standing",
  "pvTechnology": "c-Si",
  "tiltDeg": 39,
  "tiltOptimized": true,
  "azimuthDeg": -1,
  "azimuthCompassDeg": 179,
  "azimuthOptimized": true,
  "annualEnergyKwh": 5694.23,
  "specificYieldKwhPerKwp": 1138.85,
  "averageDailyEnergyKwh": 15.6,
  "annualIrradiationKwhPerM2": 1432.61,
  "performanceRatioPercent": 79.5,
  "annualEnergyStdDevKwh": 312.43,
  "annualVariabilityPercent": 5.49,
  "angleOfIncidenceLossPercent": -2.87,
  "spectralLossPercent": 1.49,
  "temperatureIrradianceLossPercent": -6.23,
  "totalLossPercent": -20.51,
  "monthlyEnergyKwh": [257.21, 361.62, 520.03, 599.39, 600.6, 620.34, 641.43, 612.28, 532.09, 428.19, 274.69, 246.35],
  "monthly": [
    { "month": 1, "monthName": "January", "energyKwh": 257.21, "dailyEnergyKwh": 8.3, "irradiationKwhPerM2": 59.91, "dailyIrradiationKwhPerM2": 1.93, "energyStdDevKwh": 58.14 }
  ],
  "tariffPerKwh": null,
  "currency": null,
  "estimatedAnnualValue": null,
  "radiationDatabase": "PVGIS-SARAH3",
  "meteoDatabase": "ERA5",
  "dataYearsFrom": 2005,
  "dataYearsTo": 2023,
  "horizonUsed": true,
  "horizonDatabase": "DEM-calculated",
  "pvgisVersion": "v5_3",
  "sourceUrl": "https://re.jrc.ec.europa.eu/api/v5_3/PVcalc?lat=48.137&lon=11.575&peakpower=5&loss=14&mountingplace=free&pvtechchoice=crystSi&usehorizon=1&outputformat=json&optimalangles=1",
  "fetchedAt": "2026-10-12T13:28:33.393Z",
  "input": { "name": "Munich warehouse roof", "lat": 48.137, "lon": 11.575, "peakPowerKw": 5, "lossPercent": 14 }
}
Data fields (40)
FieldTypeMeaning
siteIndexintegerPosition of the site in your input list (0-based).
siteNamestringSite name from your input, or 'Site N' when not given.
statusstringcomplete = estimate returned; not_found = PVGIS has no data here (sea, outside the radiation database); error = invalid site, source failure or not computed (see errorCode).
statusReasonstringPlain-English reason for not_found or error rows; null when complete.
errorCodestringMachine code: INVALID_SITE, LOCATION_OVER_SEA, OUTSIDE_DATABASE_COVERAGE, SOURCE_BAD_REQUEST, SOURCE_UNAVAILABLE, RATE_LIMITED, CHARGE_LIMIT_REACHED, DEADLINE_REACHED, CANCELLED; null when complete.
latitudenumberLatitude used, decimal degrees.
longitudenumberLongitude used, decimal degrees.
elevationMnumberTerrain elevation reported by PVGIS, metres.
peakPowerKwnumberInstalled peak PV power, kWp.
systemLossPercentnumberSystem losses you entered (cables, inverter, soiling), %.
mountingstringfree-standing or building-integrated (as used by PVGIS).
pvTechnologystringPV module technology used by PVGIS, e.g. c-Si, CIS, CdTe.
tiltDegnumberModule tilt from horizontal, degrees (as used by PVGIS, including optimized values).
tiltOptimizedbooleanTrue when PVGIS chose the optimal tilt.
azimuthDegnumberOrientation in the PVGIS convention: 0 = south, -90 = east, 90 = west, ±180 = north.
azimuthCompassDegnumberSame orientation as a compass bearing: 0 = north, 90 = east, 180 = south, 270 = west.
azimuthOptimizedbooleanTrue when PVGIS chose the optimal azimuth.
annualEnergyKwhnumberAverage annual AC energy output of the system, kWh/year (PVGIS E_y).
specificYieldKwhPerKwpnumberAnnual energy per installed kWp, kWh/kWp/year (annualEnergyKwh / peakPowerKw).
averageDailyEnergyKwhnumberAverage daily energy output, kWh/day (PVGIS E_d).
annualIrradiationKwhPerM2numberAnnual global irradiation on the module plane, kWh/m²/year (PVGIS H(i)_y).
performanceRatioPercentnumberDerived performance ratio: specific yield / in-plane irradiation × 100.
annualEnergyStdDevKwhnumberYear-to-year standard deviation of annual output, kWh (PVGIS SD_y).
annualVariabilityPercentnumberYear-to-year variability: annualEnergyStdDevKwh / annualEnergyKwh × 100.
angleOfIncidenceLossPercentnumberAngle-of-incidence (reflection) loss, % (PVGIS l_aoi; negative = loss).
spectralLossPercentnumberSpectral effect, % (PVGIS l_spec; can be a gain or a loss); null when PVGIS does not report it.
temperatureIrradianceLossPercentnumberTemperature and low-irradiance loss, % (PVGIS l_tg).
totalLossPercentnumberTotal loss including your system loss, % (PVGIS l_total).
monthlyEnergyKwharray12 values: average energy output per month, January to December, kWh (PVGIS E_m). Empty when not complete.
monthlyarray12 objects (month, monthName, energyKwh, dailyEnergyKwh, irradiationKwhPerM2, dailyIrradiationKwhPerM2, energyStdDevKwh). Empty when not complete.
tariffPerKwhnumberYour price per kWh, if given.
currencystringCurrency code for the value estimate, if a tariff was given.
estimatedAnnualValuenumberannualEnergyKwh × tariffPerKwh. Simple model, not a financial forecast.
radiationDatabasestringSolar radiation database PVGIS used, e.g. PVGIS-SARAH3 or PVGIS-ERA5.
meteoDatabasestringDatabase for temperature and wind, e.g. ERA5.
dataYearsFromintegerFirst year of the radiation data averaged by PVGIS.
dataYearsTointegerLast year of the radiation data averaged by PVGIS.
horizonUsedbooleanTrue when terrain horizon shading was included.
horizonDatabasestringSource of horizon data, e.g. DEM-calculated.
pvgisVersionstringPVGIS API version, e.g. v5_3.
Input settings (8)

The main fields of the input form. With the API you send them as JSON.

SettingName in the APITypeExample value
Sites requiredsitesarray[{"name": "Munich warehouse roof", "lat": 48.137, "lon": 11.575, "peakPowerKw": 5, "los…
Optimize missing anglesoptimizeAnglesbooleantrue
Azimuth conventionazimuthConventionstring"pvgis"
Radiation databaseradiationDatabasestring"auto"
PV module technologypvTechnologystring"crystSi"
Include horizon shadinguseHorizonbooleantrue
Electricity value per kWh (optional)tariffPerKwhnumber
Currency codecurrencystring"EUR"

Start on Apify

Make a free Apify account: you get $5 of free usage every month. Missing a tool? Suggest it. We read every idea, but we do not promise to build it.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure