REST API
This article covers the device REST API for local network access. For remote access via the cloud, see the Cloud API. Client libraries are available for Python and Go.
Authentication
Connect directly to your SolarAssistant device on your local network using your device password. A password must be configured on the device before the API can be used. See the local password guide for instructions.
curl -u admin:<password> http://192.168.0.100/api/v1/metricsTo authenticate with a token instead of a password, pass it as a Bearer token in the Authorization header:
curl -H "Authorization: Bearer <token>" http://192.168.0.100/api/v1/metricsEndpoints
Examples below use 192.168.0.100 as the device IP. Find your device's IP address in the access overview.
GET/api/v1/metricsMetrics snapshot
Returns all current metric values. Filter by topic glob or retrieve a single value as plain text.
Query parameters
| topic | string | Topic glob filter, e.g. battery* or total/*. |
| value | integer | Set to 1 to return the value as plain text instead of JSON. |
Request
curl -u admin:<password> http://192.168.0.100/api/v1/metricsResponse
[
{"topic": "total/pv_power", "group": "Status", "name": "PV power", "value": 1240, "unit": "W"},
{"topic": "total/load_power", "group": "Status", "name": "Load power", "value": 940, "unit": "W"},
{"topic": "total/battery_state_of_charge", "group": "Status", "name": "Battery state of charge", "value": 80, "unit": "%"}
]GET/api/v1/historyMetric history
Returns one metric's recorded values, grouped into time buckets. A response holds up to 2000 buckets; when the range needs more, it includes a next time to pass as from for the following page. Battery metrics are not recorded in history.
Query parameters
| topic | string | Required. A single metric topic, e.g. total/pv_power or inverter_1/temperature. Globs are not accepted. |
| from | string | Start of the range as an RFC 3339 time. Defaults to one day before to. |
| to | string | End of the range as an RFC 3339 time. Defaults to now. |
| group_by | string | Bucket size as a number and unit (s, m, h or d), e.g. 1m or 1h. Minimum and default 10s. |
| agg | string | How values in a bucket are combined: mean (default), max, min, sum or last. |
Request
curl -u admin:<password> "http://192.168.0.100/api/v1/history?topic=total/pv_power&from=2026-09-16T12:00:00Z&to=2026-09-16T13:00:00Z&group_by=1m&agg=max"Response
{
"topic": "total/pv_power",
"device": "totals",
"group": "Status",
"name": "PV power",
"unit": "W",
"agg": "max",
"group_by": "1m",
"from": "2026-09-16T12:00:00Z",
"to": "2026-09-16T13:00:00Z",
"points": [
["2026-09-16T12:00:00Z", 1240],
["2026-09-16T12:01:00Z", 1302]
]
}Times are in UTC and buckets with no data are left out. An invalid parameter returns 400 and a topic that is unknown or not recorded returns 404, each with an error message in the body.
GET/api/v1/forecastMetric forecast
Returns one weather metric's forecast values, the counterpart of /api/v1/history for future times. It requires SolarAssistant Pro and the PV forecast to be enabled. Points are at the source's resolution of 15 minutes, and a response holds the whole range, so there is no paging.
The forecast topics are weather/pv_power_predicted (W), weather/outside_temperature (in the site's °C or °F setting), weather/weather_code (WMO code), weather/is_day, weather/cloud_cover (%), weather/wind_speed (km/h) and weather/global_tilted_irradiance (W/m²). For the PV power actually generated, use /api/v1/history with topic total/pv_power.
Query parameters
| topic | string | Required. A single forecast topic. Globs are not accepted. |
| from | string | Start of the range as an RFC 3339 time. Defaults to now. The device keeps about 48 hours of past forecast, and past points are from the latest model run, not what was forecast at the time. For the prediction as it stood at each moment, use /api/v1/history with topic weather/pv_power_predicted. |
| to | string | End of the range as an RFC 3339 time. Defaults to 4 days ahead, which covers the whole stored forecast of about 3 days. |
Request
curl -u admin:<password> "http://192.168.0.100/api/v1/forecast?topic=weather/pv_power_predicted"Response
{
"topic": "weather/pv_power_predicted",
"device": "weather",
"group": "Status",
"name": "PV power predicted",
"unit": "W",
"last_updated": "2026-07-02T06:00:00Z",
"from": "2026-07-02T08:00:00Z",
"to": "2026-07-02T08:15:00Z",
"points": [
["2026-07-02T08:00:00Z", 500.4],
["2026-07-02T08:15:00Z", 750.0]
]
}last_updated is when the forecast was last fetched. Times are in UTC. An invalid parameter returns 400. A topic that is unknown, has no forecast, is not enabled for forecast, or has no forecast fetched yet since the device started returns 404, each with an error message in the body.
GET/api/v1/gridGrid provider and prices
Returns the configured grid provider, with its day-ahead prices under pricing. Prices have the price multiplier and offset set on the device already applied. Slots follow the provider's resolution, which is 15 minutes, 30 minutes or an hour depending on the provider. When the provider publishes no prices, pricing is null, and before the first prices are fetched slots is an empty list.
Request
curl -u admin:<password> http://192.168.0.100/api/v1/gridResponse
{
"provider": "Europe - EPEX",
"schedule_type": "pricing",
"pricing": {
"currency": "EUR",
"unit": "€/kWh",
"slots": [
{"from": "2026-07-02T10:00:00Z", "to": "2026-07-02T11:00:00Z", "price": 0.12, "rank": 3, "premium": -0.02}
]
}
}Providers with separate import and export tariffs, such as Octopus, report a schedule_type of import_export_pricing. Each slot then carries import_price, import_rank, import_premium, export_price, export_rank and export_premium instead.
POST/api/v1/metricsWrite a setting
Sends a new value to the inverter. On failure a 422 is returned with an error message. Use the topic field from a GET response to know what topics are writable.
Body parameters
| topic | stringrequired | The metric topic to write, e.g. inverter_1/output_source_priority. |
| value | stringrequired | The new value to set. |
Request
curl -u admin:<password> -X POST http://192.168.0.100/api/v1/metrics \
-H "Content-Type: application/json" \
-d '{"topic": "inverter_1/output_source_priority", "value": "Utility first"}'Response
{"topic": "inverter_1/output_source_priority", "result": "ok"}WS/api/websocketStream metrics via WebSocket
Streams live metrics as they update using the SolarAssistant WebSocket API. Pass your password or token as a query parameter when connecting.
Query parameters
| password | string | Device password. |
| token | string | Bearer token, as an alternative to password. |
Request
ws://192.168.0.100/api/websocket?password=<password>After connecting, join the metrics channel. See the WebSocket API docs for channel events and topic format.
Topic structure
Topics follow the same structure as MQTT. Metrics are grouped under total/, inverter_1/, inverter_2/, battery_1/, etc. Some common topics:
| Topic | Description |
| total/pv_power | Combined PV power across all inverters (W) |
| total/load_power | Total load power (W) |
| total/grid_power | Grid power, negative = export (W) |
| total/battery_power | Battery power, negative = discharging (W) |
| total/battery_state_of_charge | Battery state of charge (%) |
| total/pv_energy | PV energy generated this period (kWh) |
| total/load_energy | Load energy consumed this period (kWh) |
| total/battery_energy_in | Energy charged into the battery this period (kWh) |
| total/battery_energy_out | Energy discharged from the battery this period (kWh) |
| total/grid_energy_in | Energy imported from the grid this period (kWh) |
| total/grid_energy_out | Energy exported to the grid this period (kWh) |
| inverter_1/device_mode | Current inverter mode |
| battery_1/voltage | Battery voltage (V) |
The kWh topics are period-to-date totals, not lifetime counters. Each one is the energy measured since the start of the current period in the device's local time, and it starts again from zero when the next period begins. Set the period under Configuration › System › Reset energy totals: Daily counts from midnight, Weekly from Monday midnight (the default) and Monthly from the 1st of the month.
If you derive energy deltas by subtracting consecutive readings, expect a large negative step at each reset and treat the first reading of a new period as the energy used since that period started.
To see all available topics for your specific inverter and battery model, call the metrics endpoint without a filter and inspect the topic fields in the response.