pvnodepvnode
  • pvnode.com
  • Studio
  • Pricing
  • Deutsch
  • English
  • API Reference
Product
  • Studio
  • API Documentation
  • API Reference
  • Pricing
Resources
  • Quickstart
  • Integrations
Legal
  • Imprint
  • Privacy
  • Terms
  • Licenses
pvnodepvnode

© 2026 pvnode. All rights reserved.

linkedin
Information
Forecast
    Get forecast for a sitegetGet forecast without a saved sitepost
Historical
    Get historical data for a sitegetGet historical data without a saved sitepost
Sites
    List all sitesgetCreate a sitepostGet a sitegetDelete a sitedeleteUpdate a sitepatchRestore a sitepost
V1 API (legacy)
    YieldgetSystemgetHistorygetForecastgetRecentget
Schemas
powered by Zudoku
pvnode API
pvnode API

Historical


Get historical data for a site

GET
https://api.pvnode.com
/v2/historical/{site_id}

Returns historical PV / weather / irradiance time series for a saved site.

Data is returned at 15-minute resolution using the site's stored location and configuration. Timestamps are in the site's local timezone by default (see timezone in the response); pass ?timezone=utc to receive UTC timestamps ending in Z. Each call consumes one request from your monthly quota and is recomputed fresh — there is no server-side caching.

Get historical data for a site › path Parameters

site_id
​string · required

Get historical data for a site › query Parameters

period
​

Window length relative to yesterday, e.g. 14d, 3m, 1y. Units: d (days), m (30 days), y (365 days). Bare numbers like 30 are rejected — always specify a unit. Cannot be combined with start_date/end_date. Defaults to 14 days (clamped to your plan's maximum) when omitted.

Example: 14d
start_date
​

Inclusive start of the historical window (YYYY-MM-DD, site-local). Must be paired with end_date. Cannot be combined with period. Must be on or after your plan's earliest allowed date.

end_date
​

Inclusive end of the historical window (YYYY-MM-DD, site-local). Must be paired with start_date. Cannot be later than yesterday — historical data only covers up to yesterday.

include
​string[]

Field groups to include in the response. Combine freely (?include=weather&include=irradiance). default = pv_power. Omit default to receive only the requested groups. all returns every available field. strings adds a separate top-level strings array with per-string PV power + tilted irradiance (long format). Historical data has no clearsky reference.

Enum values:
default
all
weather
irradiance
strings
Default: ["default"]
timezone
​string · enum

Timezone of the returned values/strings timestamps. local (default) = naive site-local ISO 8601 (no offset); read the timezone field to interpret them. utc = RFC 3339 UTC ending in Z, and the response timezone field becomes UTC. The requested date window stays site-local. Use utc for clients without an IANA timezone database (e.g. jq-based integrations).

Enum values:
local
utc
Default: local

Get historical data for a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Get historical data for a site › Responses

Successful Response

HistoricalResponse
site_id
​string · required
timezone
​string · required

IANA timezone of the timestamps, e.g. 'Europe/Berlin'. Becomes 'UTC' when ?timezone=utc is requested.

start_date
​string · required

Inclusive start date of the returned window (YYYY-MM-DD, site-local).

end_date
​string · required

Inclusive end date of the returned window (YYYY-MM-DD, site-local).

included
​string[] · required

Groups included in this response.

​HistoricalValue[] · required
​

Per-string PV power and tilted irradiance (gti/gti_shaded) in long format (one row per timestep per string). Present only when include=strings (or all). Each row carries string_index (positional, always present) and, for saved sites, string_id (stable id — use it to correlate with a string's measurements). values is unaffected — total pv_power there is the sum across strings.

GET/v2/historical/{site_id}
import requests url = "https://api.pvnode.com/v2/historical/:site_id" headers = {"Authorization": "Bearer YOUR_API_KEY"} response = requests.get(url, headers=headers) print(response.text)
Example Responses
{ "site_id": "site_id", "timezone": "timezone", "start_date": "start_date", "end_date": "end_date", "included": [ "string" ], "values": [ { "timestamp": "timestamp", "pv_power": 0, "temp": 0, "weather_code": 0, "wind_speed": 0, "relative_humidity": 0, "precipitation_mm": 0, "snow_water_equivalent": 0, "ghi": 0, "dhi": 0, "bni": 0 } ], "strings": [ { "timestamp": "timestamp", "string_index": 0, "string_id": "string", "pv_power": 0, "gti": 0, "gti_shaded": 0 } ] }
json
application/json

Get historical data without a saved site

POST
https://api.pvnode.com
/v2/historical/inline

Returns historical PV / weather / irradiance time series without requiring a saved site.

Provide the location (latitude + longitude) and optionally strings and config inline. Computed fresh on every call and counts against your monthly historical quota.

Get historical data without a saved site › query Parameters

period
​

Window length relative to yesterday, e.g. 14d, 3m, 1y. Cannot be combined with start_date/end_date. See the saved-site endpoint for full rules.

Example: 14d
start_date
​

Inclusive start (YYYY-MM-DD, site-local). Must be paired with end_date; cannot be combined with period.

end_date
​

Inclusive end (YYYY-MM-DD, site-local). Must be paired with start_date; cannot be later than yesterday.

include
​string[]

Field groups to include. See the saved-site endpoint for details.

Enum values:
default
all
weather
irradiance
strings
Default: ["default"]
timezone
​string · enum

Timezone of the returned timestamps: local (default) or utc. See the saved-site endpoint for details.

Enum values:
local
utc
Default: local

Get historical data without a saved site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Get historical data without a saved site › Request Body

Historical request without a saved site. Minimum: latitude + longitude. The date window (`period` or `start_date`+`end_date`) and `include` are query params, matching the saved-site historical endpoint.
InlineHistoricalRequest
latitude
​number · min: -89.99 · max: 89.99 · required

Latitude of the site in decimal degrees (WGS84).

Example: 48.8566
longitude
​number · min: -179.99 · max: 179.99 · required

Longitude of the site in decimal degrees (WGS84).

Example: 2.3522
​

PV string definitions. Defaults to a single string (10 kWp, 180° orientation, 30° tilt) if omitted.

​

Site configuration overrides. Omitted fields fall back to current defaults.

Get historical data without a saved site › Responses

Successful Response

HistoricalResponse
site_id
​string · required
timezone
​string · required

IANA timezone of the timestamps, e.g. 'Europe/Berlin'. Becomes 'UTC' when ?timezone=utc is requested.

start_date
​string · required

Inclusive start date of the returned window (YYYY-MM-DD, site-local).

end_date
​string · required

Inclusive end date of the returned window (YYYY-MM-DD, site-local).

included
​string[] · required

Groups included in this response.

​HistoricalValue[] · required
​

Per-string PV power and tilted irradiance (gti/gti_shaded) in long format (one row per timestep per string). Present only when include=strings (or all). Each row carries string_index (positional, always present) and, for saved sites, string_id (stable id — use it to correlate with a string's measurements). values is unaffected — total pv_power there is the sum across strings.

POST/v2/historical/inline
import requests url = "https://api.pvnode.com/v2/historical/inline" payload = { "latitude": 48.8566, "longitude": 2.3522, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string" } ], "config": { "modules": { "technology": "perc", "temperature_coefficient": -0.35, "installation_year": 1980 }, "mounting": { "type": "open", "height_above_ground": 0 }, "inverter": { "clip_max_percent": 120, "clip_min_percent": 0.1 }, "losses": { "cable": 0.015, "conversion": 0.025, "albedo": 0.15, "snow_slide": 0.3, "diffuse_model": "perez" }, "shading": { "use_terrain_horizon": True, "sky_obstruction": "string" }, "tracking": { "type": "fixed", "axis_azimuth": 180, "axis_tilt": 0, "max_angle": 90, "backtracking": True } } } headers = { "Content-Type": "application/json", "Authorization": "Bearer YOUR_API_KEY" } response = requests.post(url, json=payload, headers=headers) print(response.text)
Example Request Body
{ "latitude": 48.8566, "longitude": 2.3522, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string" } ], "config": { "modules": { "technology": "perc", "temperature_coefficient": -0.35, "installation_year": 1980 }, "mounting": { "type": "open", "height_above_ground": 0 }, "inverter": { "clip_max_percent": 120, "clip_min_percent": 0.1 }, "losses": { "cable": 0.015, "conversion": 0.025, "albedo": 0.15, "snow_slide": 0.3, "diffuse_model": "perez" }, "shading": { "use_terrain_horizon": true, "sky_obstruction": "string" }, "tracking": { "type": "fixed", "axis_azimuth": 180, "axis_tilt": 0, "max_angle": 90, "backtracking": true } } }
json
Example Responses
{ "site_id": "site_id", "timezone": "timezone", "start_date": "start_date", "end_date": "end_date", "included": [ "string" ], "values": [ { "timestamp": "timestamp", "pv_power": 0, "temp": 0, "weather_code": 0, "wind_speed": 0, "relative_humidity": 0, "precipitation_mm": 0, "snow_water_equivalent": 0, "ghi": 0, "dhi": 0, "bni": 0 } ], "strings": [ { "timestamp": "timestamp", "string_index": 0, "string_id": "string", "pv_power": 0, "gti": 0, "gti_shaded": 0 } ] }
json
application/json

ForecastSites