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/metrics

To 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/metrics

Endpoints

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
topicstringTopic glob filter, e.g. battery* or total/*.
valueintegerSet to 1 to return the value as plain text instead of JSON.
Request
curl -u admin:<password> http://192.168.0.100/api/v1/metrics
Response
[
  {"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
topicstringRequired. A single metric topic, e.g. total/pv_power or inverter_1/temperature. Globs are not accepted.
fromstringStart of the range as an RFC 3339 time. Defaults to one day before to.
tostringEnd of the range as an RFC 3339 time. Defaults to now.
group_bystringBucket size as a number and unit (s, m, h or d), e.g. 1m or 1h. Minimum and default 10s.
aggstringHow 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
topicstringRequired. A single forecast topic. Globs are not accepted.
fromstringStart 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.
tostringEnd 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/grid
Response
{
  "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
topicstringrequiredThe metric topic to write, e.g. inverter_1/output_source_priority.
valuestringrequiredThe 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
passwordstringDevice password.
tokenstringBearer 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:

TopicDescription
total/pv_powerCombined PV power across all inverters (W)
total/load_powerTotal load power (W)
total/grid_powerGrid power, negative = export (W)
total/battery_powerBattery power, negative = discharging (W)
total/battery_state_of_chargeBattery state of charge (%)
total/pv_energyPV energy generated this period (kWh)
total/load_energyLoad energy consumed this period (kWh)
total/battery_energy_inEnergy charged into the battery this period (kWh)
total/battery_energy_outEnergy discharged from the battery this period (kWh)
total/grid_energy_inEnergy imported from the grid this period (kWh)
total/grid_energy_outEnergy exported to the grid this period (kWh)
inverter_1/device_modeCurrent inverter mode
battery_1/voltageBattery 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.