TL;DR
GET /v1/users/{userId}/home/automation-settings— read the home's household optimisation settings (smart price control, charge shifting, smart PV control, min SoC, eco offset, unknown battery)PUT /v1/users/{userId}/home/automation-settings— full replace of that object (all fields required); unchanged values are not re-applied- Every setting block always returns the stored value, plus
applicable(whether it currently affects optimisation) andinterventions[](blockers) - Drive partner UI from
applicable+interventions[].id— not fromenabledalone
The Automation Settings endpoints expose clever-PV's household optimisation configuration for a user's home: price-controlled battery charging, charge shifting, releasing battery power for household consumers, the minimum battery SoC reserved for PV control, the surplus / switch-on offset, and the "unknown battery" flag.
These are home-level settings (not device capabilities). Device-level control (e.g. manual battery operation-mode) remains on the device capability endpoints — and may be blocked while Smart Price Control is active (see smart-price-control-enabled).
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /v1/users/{userId}/home/automation-settings | Read the stored settings + applicability + interventions |
PUT | /v1/users/{userId}/home/automation-settings | Replace the settings (full object required) |
The home is resolved server-side from the authenticated end-user. The {userId} path segment is required for routing and auditing, but the home is not chosen by the caller.
Get the settings
GET /v1/users/{userId}/home/automation-settings
Code
200 OK
Code
Top-level fields
| Field | Type | Description |
|---|---|---|
smartPriceControl | object | Price-controlled battery charging. |
chargeShifting | object | Shifting battery charging to cheaper/greener periods. |
smartPvControl | object | Releasing battery power for household consumers, with a minimum charging power. |
minSocPvControl | object | Minimum battery state of charge reserved for PV control. |
ecoOffset | int | Surplus threshold / switch-on offset in watts. Always applicable. |
unknownBattery | object | Whether the home is flagged as having a battery clever-PV cannot yet identify. |
All six values are always present and reflect what is stored for the home — even when a setting currently has no effect on optimisation. Use applicable for that distinction.
Setting blocks
smartPriceControl / chargeShifting
| Field | Type | Description |
|---|---|---|
enabled | bool | Stored on/off value. |
applicable | bool | true when at least one electric meter of the home is from a manufacturer that supports smart battery control. When false, the stored enabled value is kept but has no effect until a supported meter/battery is present. |
interventions | array | Blockers that currently prevent this setting from taking effect. Empty when none apply. See Home automation interventions. |
unsupportedBatteries | array | Batteries whose manufacturer does not support smart battery control. The setting still applies to the remaining (supported) batteries; empty when all batteries are supported. Each entry is { "deviceId": "<electricMeterId>" }. |
smartPvControl
| Field | Type | Description |
|---|---|---|
enabled | bool | Whether battery power may be used for household consumers. |
minChargingPower | int | Minimum charging power reserved for the battery, in watts. |
applicable | bool | false when the home has no battery storage; stored values are kept but have no effect until a battery is onboarded. |
interventions | array | Blockers for this setting. |
minSocPvControl
| Field | Type | Description |
|---|---|---|
minSoc | int | Minimum state of charge, in percent (0–100). |
applicable | bool | false when the home has no battery storage. |
interventions | array | Blockers for this setting. |
unknownBattery
| Field | Type | Description |
|---|---|---|
hasUnknownBattery | bool | Whether the home is flagged as having an unidentified battery. |
applicable | bool | false when the home already has a known battery. The stored value is kept, but a PUT that changes it is silently ignored while a known battery is present. |
interventions | array | Blockers for this setting. |
Intervention object
| Field | Type | Description |
|---|---|---|
id | string | Stable, kebab-case intervention identifier (e.g. battery-capacity-required). Drive UI state from this. |
deviceId | string? | The device the intervention refers to, when the intervention is device-specific (e.g. a battery). null for home-wide interventions such as solar-forecast-setup-required. |
Update the settings
PUT /v1/users/{userId}/home/automation-settings
This is a full replace, not a partial update: the complete object is required. Settings whose value is unchanged from the stored state are not re-applied. Changed values are applied one at a time (not in a single transaction). If a later value fails to apply, part of the object may already be stored — retrying with the same object converges to the target state.
Code
Request body
| Field | Type | Rules |
|---|---|---|
smartPriceControl.enabled | bool | Required. |
chargeShifting.enabled | bool | Required. |
smartPvControl.enabled | bool | Required. |
smartPvControl.minChargingPower | int | Required. Must be >= 0 when the value actually changes. |
minSocPvControl.minSoc | int | Required. Must be 0–100 when the value actually changes. |
ecoOffset | int | Required. Must be >= 0 when the value actually changes. |
unknownBattery.hasUnknownBattery | bool | Required. Silently ignored while the home already has a known battery (request still succeeds; subsequent GET keeps the previous value). |
Range rules are only enforced for values that change. A home may carry a legacy value outside these ranges; sending that value back unchanged on every sync must not lock the home out of the API.
204 No Content
Successful replace. There is no response body — call GET again to read the resulting state (including updated applicable / interventions).
applicable vs enabled vs interventions
These three signals answer different questions:
| Signal | Meaning |
|---|---|
enabled / stored value | What is persisted for the home. Always returned so GET/PUT can round-trip. |
applicable | Whether the setting currently affects optimisation at all (hardware / battery presence prerequisites). When false, the stored value is inert. |
interventions[] | Soft blockers within an applicable setting (missing capacity, wrong operating mode, …). Empty when none apply — including when applicable is false. |
Example: smartPriceControl.enabled: true with applicable: false means the toggle is stored as on, but no supported meter/battery is present yet — optimisation is not running Smart Price Control.
Error responses
All errors follow RFC 7807 (application/problem+json) using the partner-friendly ConnectApiProblemDetails shape (type + errorCode + traceId + optional detail / issues).
| Status | errorCode | Meaning |
|---|---|---|
400 | validationError | PUT with out-of-range values that actually change (minSoc not in 0–100, ecoOffset / minChargingPower < 0), or a malformed body. |
401 | — | Missing or invalid bearer token. |
403 | — | Token lacks the connect_api scope. |
404 | missingHome | The authenticated user has no home. |
429 | — | Global IP rate limit (100 requests / 10 seconds). |
500 | internalError | Unhandled server error. |
Important notes
- Full replace: always send the complete object on
PUT. Omitting a field is a validation error, not a "leave unchanged". - Partial apply on failure: changed values commit individually. On a mid-flight failure, retry the same payload — unchanged fields are skipped, so the retry is idempotent.
applicable: falseis not an error: GET still returns200with the stored values; partners should hide or disable the control in UI until it becomes applicable.- Interventions live on the setting, not on devices: home-automation interventions appear under each setting's
interventions[]on this endpoint. The sameidstrings may also appear on device capabilities in other contexts — see Interventions. - Units:
ecoOffsetandminChargingPowerare in watts;minSocis a percent (0–100). - Cross-link: disabling Smart Price Control is what clears the device-level
smart-price-control-enabledintervention onoperation-mode.