SolarEdge Client (Monitoring API)
A Python client for the SolarEdge Monitoring API (V2), with synchronous and asynchronous interfaces and a method for every documented operation.
Upgrading from 2.x? SolarEdge retired Monitoring API V1 on November 3, 2026, and every request from 2.x now fails with HTTP 410. 3.0 talks to V2, which needs a new API key and has different endpoints and response shapes. See Migrating from 2.x.
Table of Contents
- Features
- Installation
- Credentials
- Quick Start
- Rate Limits
- Migrating from 2.x
- Development
- API Documentation
Features
- Complete V2 coverage: all 56 operations in SolarEdge's Basic Monitoring
(2.1.0) and Advanced Monitoring (2.0.1) APIs, plus
get()for anything added later - Sync & Async Support:
MonitoringClientandAsyncMonitoringClientshare one definition of every method, so they cannot drift apart - Typed: full annotations,
py.typed, andLiteraltypes for every enumerated parameter - Safe by default: arguments are validated before anything is sent, and the API key never appears in URLs or error messages
Installation
pip install solaredge
poetry add solaredge
uv add solaredge
Credentials
V1 API keys do not work with V2. Create an account on the
SolarEdge Developer Platform and generate
an API key there. This client sends it in the X-API-Key header, which
every V2 operation accepts.
V2 also supports OAuth 2.0 (Site Access), which lets an app act on behalf of a system owner. That isn't supported here yet. If you need it, please comment on #122.
Quick Start
All time windows take timezone-aware datetimes, which are sent as UTC. V2
rejects timestamps without an offset, so a naive datetime raises
SolarEdgeValidationError before any request is sent. Where start/end are
optional, leaving them out means "midnight today until now" in the site's
time zone.
Synchronous Usage
from datetime import datetime, timedelta, timezone
from solaredge import MonitoringClient
SITE_ID = 1234567
now = datetime.now(timezone.utc)
with MonitoringClient("YOUR_API_KEY") as client:
details = client.get_site_details(SITE_ID)
today = client.get_overview(SITE_ID)
daily = client.get_energy(
SITE_ID,
start=now - timedelta(days=30),
end=now,
resolution="DAY",
unit="KWH",
)
batteries = client.get_storage_telemetry(SITE_ID)
Asynchronous Usage
import asyncio
from datetime import datetime, timedelta, timezone
from solaredge import AsyncMonitoringClient
async def main():
now = datetime.now(timezone.utc)
async with AsyncMonitoringClient("YOUR_API_KEY") as client:
details, power = await asyncio.gather(
client.get_site_details(1234567),
client.get_power(1234567, start=now - timedelta(hours=2), end=now),
)
asyncio.run(main())
Methods
Every method returns the parsed JSON unchanged. Optional arguments left as
None are not sent, so the API's own defaults apply. The
API reference lists the paths, parameters and
per-resolution window limits.
| Area | Methods |
|---|---|
| Sites | get_sites, get_site_details, get_overview, get_performance, get_power, get_energy, get_environmental_benefits, get_lifetime_energy, get_external_production_energy |
| Alerts | get_alerts (all sites), get_site_alerts |
| Inventory | get_devices, get_device |
| Telemetry | get_inverters_telemetry, get_meters_telemetry, get_storage_telemetry |
| Status | get_inverters_status, get_storage_status |
| Lifetime counters | get_inverters_lifetime_energy, get_meters_lifetime_energy, get_storage_lifetime_energy |
| Inverter | get_inverter_power, _energy, _consumed_ac_power, _consumed_ac_energy, _voltage, _current, _frequency |
| Meter | get_meter_production_power / _energy, get_meter_consumption_*, get_meter_import_*, get_meter_export_* |
| Battery | get_battery_charge_power, _discharge_power, _charge_energy, _discharge_energy, _state_of_energy, _remaining_energy |
| Advanced Monitoring* | get_power_per_destination, get_energy_per_destination, get_current_power_flow, start_live_power_flow, get_weather_guard, get_backup_reserve |
| Anything else | get(path, params=None) |
* Business Pro and Enterprise plans only. Other plans get HTTP 403, raised as
SolarEdgeAuthError.
Telemetry, status and lifetime methods cover every device of that kind on the
site. Pass serial_numbers=[...] to limit them to specific devices. V2 reports
units in upper case ("WH", "KWH", "W"), so compare them
case-insensitively.
Error Handling
Every failure raises a SolarEdgeError subclass, so you never need to import
httpx to handle one. The originating httpx exception is preserved as
__cause__ if you want the transport-level detail.
from solaredge import (
MonitoringClient,
SolarEdgeAuthError,
SolarEdgeRateLimitError,
SolarEdgeError,
)
with MonitoringClient("YOUR_API_KEY") as client:
try:
flow = client.get_current_power_flow(1234567)
except SolarEdgeAuthError:
... # bad key, or an operation your plan does not include
except SolarEdgeRateLimitError as exc:
... # exc.retry_after, exc.limits
except SolarEdgeError:
... # anything else this library raises
The hierarchy:
| Exception | Raised when |
|---|---|
SolarEdgeError |
Base class for everything below |
SolarEdgeValidationError |
Arguments rejected locally, before any request. Also a ValueError |
SolarEdgeAPIError |
The API returned an error status, e.g. 400 for a window that is too long |
SolarEdgeAuthError |
401 / 403: key missing or invalid, or the operation is not in your plan |
SolarEdgeNotFoundError |
404: no such site, device or operation |
SolarEdgeRateLimitError |
429: per-minute or monthly quota exceeded. Carries retry_after and limits (the x-ratelimit-* headers) |
SolarEdgeServerError |
5xx: the API failed to handle a valid request |
SolarEdgeResponseError |
Success status, but the body could not be parsed |
SolarEdgeAPIError and its subclasses carry status_code, response_body and
url.
Rate Limits
Every call costs one credit. Plans set a monthly credit quota and a calls-per-minute limit; the Free tier allows 2,000 credits a month and 10 calls a minute.
This client caps itself at 3 concurrent requests but does not retry or throttle for you. A client that polled several endpoints every 15 minutes under V1 will run through the Free tier's monthly quota. To stay within it:
- Prefer the bulk telemetry methods over per-device ones.
- Use coarser resolutions where you can.
- Poll less often.
Migrating from 2.x
| 2.x method | 3.0 replacement |
|---|---|
get_site_list(...) |
get_sites(page=..., sites_in_page=..., name=...) |
get_site_details(site_id) |
get_site_details(site_id) |
get_overview(site_ids) |
get_overview(site_id), one site per call |
get_energy(site_ids, start_date, end_date, time_unit) |
get_energy(site_id, start, end, resolution, unit) |
get_time_frame_energy(...) |
get_energy(..., resolution="TOTAL") |
get_power(site_id, start_time, end_time) |
get_power(site_id, start, end, resolution, unit) |
get_power_details(...), get_energy_details(...) |
get_meters_telemetry(...), or get_power_per_destination / get_energy_per_destination (Advanced) |
get_current_power_flow(site_id) |
get_current_power_flow(site_id) (Advanced) |
get_storage_data(...) |
get_storage_telemetry(...), get_storage_status(...) |
get_environmental_benefits(site_id, system_units) |
get_environmental_benefits(site_id, unit="METRIC" or "IMPERIAL") |
get_inventory(site_id), get_components_list(site_id) |
get_devices(site_id, types=[...]) |
get_inverter_technical_data(site_id, serial, ...) |
get_inverters_telemetry(...) and get_inverters_status(...) with serial_numbers=[serial] |
get_meters(...) |
get_meters_lifetime_energy(...), get_meters_telemetry(...) |
get_site_data(site_ids) |
No V2 equivalent |
Other changes:
- Credentials: pass a V2 API key; V1 keys are rejected.
- One site per call: V2 has no comma-separated bulk form for sites.
- Datetimes must be timezone-aware, and are sent as UTC
from/to. - Parameters renamed:
time_unitis nowresolution, andQUARTER_OF_AN_HOURis nowQUARTER_HOUR. Enum values are upper case, e.g.METRIC,PRODUCTION. - Response bodies differ, so code that reads fields needs updating.
- Data no longer available: optimizer-level telemetry (optimizers appear
only in
get_devices), and per-phase inverter values (V2 averages across phases).
Development
# Install development dependencies
uv sync
uv run prek install -t commit-msg
# Commiting changes
uv run cz c
API Documentation
Metadata
Release files for solaredge 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| solaredge-3.0.0.tar.gz | 17.4 kB | With provenance | Details for solaredge-3.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| solaredge-3.0.0-py3-none-any.whl | Python 3 | none | any | Details for solaredge-3.0.0-py3-none-any.whl |
Total release size: 35.9 kB
Release files / solaredge-3.0.0.tar.gz
| Download URL | solaredge-3.0.0.tar.gz |
|---|---|
| Size | 17.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1269aa58b00c0c7c575b7f5ab2ac214edc0adf9de017be9001a4677bba8a90b0
|
|
BLAKE2b-256 checksum How to use checksums |
90ac96cf0e3045430ed0382349289f29f554458a02e61a1784bfc2e3e845a319
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / solaredge-3.0.0-py3-none-any.whl
| Download URL | solaredge-3.0.0-py3-none-any.whl |
|---|---|
| Size | 18.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3823365fa76c1e8df33d0f3337a354b66fe79340f902af43fe57f97fc09fcc65
|
|
BLAKE2b-256 checksum How to use checksums |
3946b2703f6a2f8fba9606c335995eb57792b9a8dbb07747fde89e96992b0297
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for solaredge 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for solaredge-3.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.