If you’ve tried to build anything that depends on accurate solar irradiance — a PV output estimator, an agricultural evapotranspiration model, a glare-risk flag for autonomous vehicles — you’ve probably noticed that WeatherAPI’s solar-related fields don’t all live in the same place, don’t have the same update cadence, and don’t mean quite the same thing. The field names suggest they’re interchangeable. They aren’t.
Here’s what each field actually represents, where the gaps are, and how we stitch them together into something more useful than any single field gives you on its own.
What You Actually Get and Where
The forecast endpoint (/v1/forecast.json) includes uv_index at the hourly level and a daily summary with fields like totalprecip_mm and avgvis_km. The hourly block also carries cloud (percentage cover, 0–100) and sometimes visibility. What you won’t find is a direct GHI (Global Horizontal Irradiance) value in W/m² — the unit that actually matters for most energy applications.
The current conditions endpoint gives you uv_index as a rounded integer. That’s it for solar, unless you’re on a plan that surfaces the air_quality block, which is adjacent but not the same problem.
uv_index is derived from the UV component of the solar spectrum — roughly 290–400 nm — weighted by the erythema action spectrum. It’s a biologically-weighted quantity. It correlates with GHI under clear-sky conditions, but cloud cover, aerosol loading, and solar angle all decouple them. A UV index of 7 at solar noon in July in Spain is not the same irradiance environment as UV index 7 at a low solar elevation in winter. Using UV index as a proxy for total irradiance will get you into trouble, quietly.
The Clear-Sky Irradiance Baseline
The most useful thing you can reconstruct without direct GHI readings is a clear-sky irradiance estimate, then apply a cloud transmittance correction on top of it.
Clear-sky GHI depends primarily on solar zenith angle and atmospheric path length (air mass). The simplified Kasten-Young formula for air mass is:
AM = 1 / (cos(θ) + 0.50572 × (96.07995 - θ)^(-1.6364))
where θ is the solar zenith angle in degrees. Clear-sky GHI at sea level runs roughly 1000 × cos(θ) W/m² at solar noon under dry, clean-air conditions, and that number degrades by roughly 10–12% per unit of air mass above 1.
To get solar zenith angle for a given lat/lon and UTC timestamp, you need the sun’s declination and hour angle. The NOAA Solar Calculator algorithm is well-documented and accurate to within a fraction of a degree for most practical purposes. You’re computing this client-side — the API doesn’t return solar angle directly.
What the API does give you is local sunrise and sunset times through the astronomy endpoint (/v1/astronomy.json). That’s enough to bound the daylight window and sanity-check your zenith angle calculation. If your computed zenith says the sun is up but the astronomy endpoint says it’s past sunset, trust the astronomy endpoint and zero out your irradiance estimate.
Cloud Transmittance: Where the Hourly Block Actually Earns Its Keep
Cloud cover percentage (cloud from the hourly forecast) is a crude but functional proxy for transmittance. The relationship isn’t linear — scattered cumulus at 30% cover doesn’t block 30% of incoming radiation, because geometry and cloud optical depth both matter — but a simple empirical correction gets you close enough for most applications:
transmittance = 1 - (0.75 × (cloud / 100)^3.4)
This form appears in several published clear-sky decomposition models; Boland, Ridley, and Lauret have a well-cited version. It’s not physically rigorous — it doesn’t account for cloud type, optical thickness, or multiple scattering — but it’s considerably better than ignoring cloud cover entirely or assuming a linear relationship.
Applied GHI estimate then becomes:
GHI_estimated = GHI_clear_sky × transmittance
At the hourly resolution WeatherAPI provides, this gives you a usable irradiance series. Not BSRN-quality instrumented data, but accurate enough that it won’t embarrass you in a production PV output model.
Elevation Correction
At altitude, the atmosphere is thinner. Less path length means less scattering and absorption, so clear-sky irradiance is higher than at sea level for the same solar angle. A rough correction:
GHI_elevation = GHI_sea_level × (1 + 0.000012 × elevation_m)
That factor — approximately 1.2% per 1000m — is consistent with what you’d calculate from standard atmosphere pressure profiles. For a mountain site at 2000m, you’re looking at roughly 2.4% higher irradiance than the sea-level estimate. Not huge, but meaningful if you’re doing a yield estimate for a solar installation.
WeatherAPI returns elevation when you resolve a location, so this correction is straightforward to apply without an extra data source.
The Gaps Worth Being Honest About
This reconstruction approach has real limits. It doesn’t account for aerosol optical depth — in regions with significant dust, smoke, or industrial pollution loading, your clear-sky GHI will be optimistic by anywhere from a few percent to over 30% during heavy haze events. The air quality block gives you PM2.5 and ozone, which are partial proxies, but converting those to aerosol optical depth correctly requires more than a simple lookup.
Diffuse vs. direct beam decomposition is also lost. For bifacial PV panels, tracking systems, or anything where angle of incidence matters, you need GHI split into DNI (Direct Normal Irradiance) and DHI (Diffuse Horizontal Irradiance) separately. The Erbs decomposition model does this from GHI and clearness index, but that requires knowing GHI first — which we’re estimating — so the error compounds.
For a simple fixed-tilt panel output estimator, the compounding error is probably acceptable. For a commercial energy yield model that feeds a financing decision, it isn’t. Know which problem you’re solving before you decide the reconstruction is good enough.
Putting It Together: A Minimal Request Pattern
To get everything you need in as few API calls as possible:
- One call to
/v1/forecast.jsonwithdays=3gives you hourlycloud,uv_index, andtemp_cfor the next 72 hours. - One call to
/v1/astronomy.jsonper day gives you accurate sunrise/sunset for bounding your daylight window. - Elevation comes from the
locationblock in any forecast response — no extra call needed.
Client-side, you compute solar zenith angle per hour, clear-sky GHI, then apply the cloud transmittance correction and elevation factor. If you’re caching forecast responses — and you should be, since hourly forecast data doesn’t meaningfully change faster than the underlying model run cycle (every 6 hours for GFS, every hour for HRRR) — you’re running this reconstruction logic against cached data, not making live calls per irradiance estimate.
One implementation note: cloud in the hourly block is an integer percentage from the NWP model, not a measured value. Near sunrise and sunset it can be noisier than mid-day values. Zero out any irradiance estimate where your computed solar zenith angle exceeds 90°, regardless of what the cloud field says — this avoids a class of edge-case bugs where low-sun-angle geometry produces slightly negative cosine values and your model starts reporting negative irradiance at dusk.
Where UV Index Is Actually Useful
It’s not useless — it’s just misapplied when treated as an irradiance proxy. For UV exposure alerts, skin damage risk modeling, or photodegradation estimates for materials applications, it’s the right quantity. It’s also a useful sanity check: if your reconstructed GHI is high but UV index is low, that’s a signal worth investigating. It usually means the cloud cover field is underreporting actual attenuation — which happens when the model has thin cirrus that reduces UV more than it reduces total broadband irradiance.
Build both into your pipeline and compare them. Disagreement between them is information, not noise.
If you’re running this across more than a handful of locations — say, a fleet of sites across different elevation bands and climates — log the ratio of UV-index-implied irradiance to your reconstructed GHI over time, per location. A persistent divergence at a specific site usually points to either a station-selection issue in the underlying data or a persistent aerosol effect the cloud cover field isn’t capturing. That ratio is cheap to compute and tends to surface problems before your end-users do.
