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

Sites


List all sites

GET
https://api.pvnode.com
/v2/sites/

Returns all sites belonging to the authenticated user, including those pending deletion.

List all sites › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

List all sites › Responses

200

Successful Response

​SiteResponse[]
SiteResponse
id
​string · required
​required
latitude
​number · required
longitude
​number · required
timezone
​string · required

IANA timezone, e.g. 'Europe/Berlin'. Automatically determined from location.

status
​SiteStatus · enum · required
Enum values:
active
inactive
​SiteConfig · required

Effective site configuration — stored overrides merged with current defaults.

​PVString[] · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
​

Elevation above sea level in meters. Automatically determined from location.

​

Set when the site is pending deletion. The site will be permanently removed 30 days after this date.

GET/v2/sites/
import requests url = "https://api.pvnode.com/v2/sites" headers = {"Authorization": "Bearer YOUR_API_KEY"} response = requests.get(url, headers=headers) print(response.text)
Example Responses
[ { "id": "id", "name": "string", "latitude": 0, "longitude": 0, "elevation": 0, "timezone": "timezone", "status": "active", "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "deleted_at": "2024-08-25T15:00:00Z" } ]
json
application/json

Create a site

POST
https://api.pvnode.com
/v2/sites/

Creates a new site for the authenticated user.

A site represents a PV installation with a fixed location and configuration.

Create a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Create a site › Request Body

CreateSiteRequest
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
​

Human-readable label for the site, e.g. 'Rooftop South'.

​

Optional configuration overrides. Only explicitly set values are stored; omitted fields fall back to current defaults.

​

PV string definitions for this site. Defaults to a single string with system defaults if omitted.

is_ephemeral
​boolean

Marks the site as temporary/exploratory. Not counted against plan limits.

Default: false

Create a site › Responses

Successful Response

SiteResponse
id
​string · required
​required
latitude
​number · required
longitude
​number · required
timezone
​string · required

IANA timezone, e.g. 'Europe/Berlin'. Automatically determined from location.

status
​SiteStatus · enum · required
Enum values:
active
inactive
​SiteConfig · required

Effective site configuration — stored overrides merged with current defaults.

​PVString[] · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
​

Elevation above sea level in meters. Automatically determined from location.

​

Set when the site is pending deletion. The site will be permanently removed 30 days after this date.

POST/v2/sites/
import requests url = "https://api.pvnode.com/v2/sites" payload = { "name": "string", "latitude": 48.8566, "longitude": 2.3522, "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": True } ], "is_ephemeral": False } headers = { "Content-Type": "application/json", "Authorization": "Bearer YOUR_API_KEY" } response = requests.post(url, json=payload, headers=headers) print(response.text)
Example Request Body
{ "name": "string", "latitude": 48.8566, "longitude": 2.3522, "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "is_ephemeral": false }
json
Example Responses
{ "id": "id", "name": "string", "latitude": 0, "longitude": 0, "elevation": 0, "timezone": "timezone", "status": "active", "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "deleted_at": "2024-08-25T15:00:00Z" }
json
application/json

Get a site

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

Returns a single site by its ID. Also returned if the site is pending deletion.

Get a site › path Parameters

site_id
​string · required

Get a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Get a site › Responses

Successful Response

SiteResponse
id
​string · required
​required
latitude
​number · required
longitude
​number · required
timezone
​string · required

IANA timezone, e.g. 'Europe/Berlin'. Automatically determined from location.

status
​SiteStatus · enum · required
Enum values:
active
inactive
​SiteConfig · required

Effective site configuration — stored overrides merged with current defaults.

​PVString[] · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
​

Elevation above sea level in meters. Automatically determined from location.

​

Set when the site is pending deletion. The site will be permanently removed 30 days after this date.

GET/v2/sites/{site_id}
import requests url = "https://api.pvnode.com/v2/sites/:site_id" headers = {"Authorization": "Bearer YOUR_API_KEY"} response = requests.get(url, headers=headers) print(response.text)
Example Responses
{ "id": "id", "name": "string", "latitude": 0, "longitude": 0, "elevation": 0, "timezone": "timezone", "status": "active", "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "deleted_at": "2024-08-25T15:00:00Z" }
json
application/json

Delete a site

DELETE
https://api.pvnode.com
/v2/sites/{site_id}

Deletes a site. The site is soft-deleted and permanently removed after 30 days.

Delete a site › path Parameters

site_id
​string · required

Delete a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Delete a site › Responses

Successful Response

No data returned
DELETE/v2/sites/{site_id}
import requests url = "https://api.pvnode.com/v2/sites/:site_id" headers = {"Authorization": "Bearer YOUR_API_KEY"} response = requests.delete(url, headers=headers) print(response.text)
Example Responses
No example specified for this content type

Update a site

PATCH
https://api.pvnode.com
/v2/sites/{site_id}

Partially updates a site. Only the provided fields are changed.

Update a site › path Parameters

site_id
​string · required

Update a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Update a site › Request Body

UpdateSiteRequest
​

Human-readable label for the site.

​

Latitude in decimal degrees (WGS84).

​

Longitude in decimal degrees (WGS84).

​
​

Configuration overrides to merge into the stored config.

​

Replaces all PV strings on the site.

​

Set to false to make an ephemeral site permanent.

Update a site › Responses

Successful Response

SiteResponse
id
​string · required
​required
latitude
​number · required
longitude
​number · required
timezone
​string · required

IANA timezone, e.g. 'Europe/Berlin'. Automatically determined from location.

status
​SiteStatus · enum · required
Enum values:
active
inactive
​SiteConfig · required

Effective site configuration — stored overrides merged with current defaults.

​PVString[] · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
​

Elevation above sea level in meters. Automatically determined from location.

​

Set when the site is pending deletion. The site will be permanently removed 30 days after this date.

PATCH/v2/sites/{site_id}
import requests url = "https://api.pvnode.com/v2/sites/:site_id" payload = { "name": "string", "latitude": 0, "longitude": 0, "timezone": "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": True } ], "is_ephemeral": True } headers = { "Content-Type": "application/json", "Authorization": "Bearer YOUR_API_KEY" } response = requests.patch(url, json=payload, headers=headers) print(response.text)
Example Request Body
{ "name": "string", "latitude": 0, "longitude": 0, "timezone": "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "is_ephemeral": true }
json
Example Responses
{ "id": "id", "name": "string", "latitude": 0, "longitude": 0, "elevation": 0, "timezone": "timezone", "status": "active", "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "deleted_at": "2024-08-25T15:00:00Z" }
json
application/json

Restore a site

POST
https://api.pvnode.com
/v2/sites/{site_id}/restore

Cancels a pending deletion and restores the site to active status.

Restore a site › path Parameters

site_id
​string · required

Restore a site › Headers

Authorization
​string · required

Bearer token. Format: Bearer YOUR_API_KEY

Default: Bearer YOUR_API_KEY

Restore a site › Responses

Successful Response

SiteResponse
id
​string · required
​required
latitude
​number · required
longitude
​number · required
timezone
​string · required

IANA timezone, e.g. 'Europe/Berlin'. Automatically determined from location.

status
​SiteStatus · enum · required
Enum values:
active
inactive
​SiteConfig · required

Effective site configuration — stored overrides merged with current defaults.

​PVString[] · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
​

Elevation above sea level in meters. Automatically determined from location.

​

Set when the site is pending deletion. The site will be permanently removed 30 days after this date.

POST/v2/sites/{site_id}/restore
import requests url = "https://api.pvnode.com/v2/sites/:site_id/restore" headers = {"Authorization": "Bearer YOUR_API_KEY"} response = requests.post(url, headers=headers) print(response.text)
Example Responses
{ "id": "id", "name": "string", "latitude": 0, "longitude": 0, "elevation": 0, "timezone": "timezone", "status": "active", "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 } }, "strings": [ { "slope": 0, "orientation": 0, "power_kw": 0.1, "gcr": 0, "near_field_shading": "string", "id": "string", "calibration_active": true } ], "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "deleted_at": "2024-08-25T15:00:00Z" }
json
application/json

HistoricalV1 API (legacy)