Two auth mechanisms — pick whichever fits the caller:
Session cookie — POST /login with password=<web-password>
returns a Set-Cookie you reuse. Browsers do this automatically.
Bearer token — Authorization: Bearer <token> header on
every request. Generate the token on Settings → Home Assistant →
API token ; only the hash is kept on the device.
Responses are JSON unless noted. Errors use a consistent shape:
{ "ok" : false , "error" : " human-readable reason " }
The on-device page /config/api is the live, hand-maintained
inventory — open it on your own HeatSync for the same list (54+
endpoints currently). This page mirrors it grouped by purpose.
Method Path Notes POST/loginForm-encoded password=…. Returns 302 + cookie. GET/logoutClears the session cookie. GET/api/auth/tokenStatus of the long-lived bearer token (created? when?). POST/api/auth/tokenGenerate a new bearer token; returns the plaintext (shown once, stored hashed). DELETE/api/auth/tokenRevoke the current token.
Method Path Description GET/api/statusTop-level health — WiFi, MQTT, bus stats, writes counter, BLE inject status. GET/api/livePer-device snapshot — every value HeatSync has decoded. Drives the dashboard and the HACS integration’s main poll. GET/api/systemChip info, uptime, reset reason, heap stats. GET/api/diagnoseBundle of /api/system + /api/status + sniffer head + events. Used by the “Copy snapshot” button and HA’s “Download diagnostics”. GET/api/eventsLast ~80 events from the in-RAM ring (boot, OTAs, faults, warnings). GET/api/events/persistedPersistent events that survive reboots (boot count, last error, etc.). GET/api/busList of NASA addresses seen on the bus. GET/api/sniffer/recentAll unique (source, msgNo) tuples with last/previous value + change count. Cap 256, chunked-streamed. POST/api/sniffer/resetZero the sniffer’s change counters. GET/api/ble/sensorsBLE thermometers seen + paired (empty when BLE compile-disabled). POST/api/ble/pairPair a sensor by MAC (form mac=…&name=…). POST/api/ble/unpairUnpair (form mac=…).
These power the home page widgets and the HACS integration’s daily
totals.
Method Path Description GET/api/cost/statusToday’s running totals — todayPence, peakKwh, offPeakKwh, per-mode kWh split, current rateNowPence + bucket (peak/offPeak). Reset at midnight. GET/api/energy/dailyPer-day historical totals (kwhElec, kwhThermal, cycles, outdoorAvg). One entry per past day; rolls forward at midnight. GET/api/carbon/statusCurrent gCO₂/kWh from carbonintensity.org.uk for the configured region, plus the 48-slot half-hour forecast. POST/api/carbon/configForm: enabled, postcode, or resolve=1 to derive postcode from saved weather lat/lon. GET/api/weatherCurrent weather state + 48 h hourly forecast (Open-Meteo). POST/api/weather/configSave lat/lon (and optional place label). GET/api/weather/geocode?q=<postcode-or-city>Resolve a place name to lat/lon. GET/api/octopus/statusStored Octopus credentials state + last lookup result (API key masked). POST/api/octopus/lookupFire the Octopus account + tariff lookup. Form: apiKey, account (both optional — falls back to persisted). POST/api/octopus/applyApply the most recent successful lookup’s windows to tariffWindows[].
Method Path Description GET/api/dhw-schedule/statusCurrent DHW schedule decision — mode (0–3), enabled, off-peak flag, status string, reheat-minutes estimate, computed Efficiency/Combo window epochs. GET/api/schedule/heatingWeekly heating schedule blocks. POST/api/schedule/heatingReplace the weekly heating schedule. GET/api/dhw-modelCylinder-learning state — volume estimate, standing loss, last-reheat duration, cycle count. GET/api/load-comp/statusLoad-compensation state — current offset, computed error and slope terms.
Method Path Description GET/api/configAll persisted settings (passwords, API keys never returned). POST/api/configForm-encoded; only the keys present are updated. Triggers MQTT re-setup when touched.
Notable fields: deviceName, zoneLabel, mqttHost, mqttPort,
mqttUser, mqttPass, mqttTopicPrefix, haDiscoveryPrefix,
haEnabled, writesEnabled, roomTempInject, glycolPercent,
dhwSchedEnabled, dhwSchedMode (0=Tariff, 1=Carbon, 2=Efficiency,
3=Combo), dhwSchedFullTarget, dhwSchedMidTarget,
dhwSchedHardLimit, dhwTankVolumeL, tariffWindows[],
tariffPeakPence, tariffOffPeakPence, loadComp*, heatNightOffset,
awayActive, awaySetbackC, boost*, preferredBssid.
All return { "ok": true } on success, or 400 { ok: false, error: ... }.
Method Path Body / query Description POST/api/control/dhw-targetvalue=<30..65>Set DHW setpoint °C. POST/api/control/dhw-power`on=1 0` POST/api/control/dhw-mode`mode=eco standard POST/api/control/dhw-boost(none) One-shot +5 °C for 1 h. POST/api/control/heating-mode`mode=off heat POST/api/control/heating-targetvalue=<float>Set room/zone target. POST/api/control/heating-boost(none) One-shot +1 °C for 1 h. POST/api/control/water-law-offsetvalue=<-5..+5>±5 °C heating-curve dial. POST/api/control/heating-curveForm: curveType, wl1FlowMax, wl1FlowMin, wl2FlowMax, wl2FlowMin, ambMax, ambMin Write the heating curve shape. POST/api/control/flow-targetvalue=<15..65>Direct flow-temp override (fixed-flow installs). POST/api/control/fan-mode`mode=auto low POST/api/control/quiet-mode`on=1 0` POST/api/control/legionellaForm: enabled, day, hour, targetC, durationMin Anti-legionella schedule. POST/api/control/away`on=1 0`
Method Path Description GET/api/wifi/scanScan visible WiFi APs (BSSID + RSSI + channel). POST/api/wifi/selectPin to a specific BSSID (form bssid=AA:BB:...). Empty = auto-pick strongest matching SSID. POST/api/wifi/roamForce-evaluate auto-roam now, bypassing the 5-min cool-down. GET/api/net/probeDNS + TCP + TLS connectivity probe with explicit mbedTLS error codes. Diagnostic.
Method Path Description GET/api/baselineBaseline-capture state — active, progress, computed delta. POST/api/baseline/startBegin a baseline capture (~10 min idle measurement). POST/api/baseline/cancelAbort an in-progress capture.
Method Path Description POST/api/fsv/pollKick off a polling cycle — sends a NASA Read request for each known FSV register in rotation, one every 250 ms. GET/api/fsv/status{ active, index, total, elapsedMs }.POST/api/fsv/probeOne-shot Read for a specific register with caller-spoofed source class (diagnostic). Query: target=<hex>, source=<hex>.
Method Path Description GET/api/heat-loss/stateSummary of the analyser’s current estimate. GET/api/heat-loss/binsPer-outdoor-temperature-bin samples. GET/api/heat-loss/eventsRecent cool-down events used as samples. POST/api/heat-loss/resetWipe the accumulated samples.
Method Path Description GET/api/update/statusCurrent version, latest release, install-in-progress flag. POST/api/update/checkFetch the manifest from GitHub Pages right now. POST/api/update/installBegin downloading + flashing the latest release. Device reboots when done. POST/api/update/configForm: autoCheck, autoCheckIntervalH. GET/update(Legacy upload page — used by ./build.sh ota-http.) POST/updateMultipart upload of samsung_controller.ino.bin. Cookie auth.
The first-boot onboarding wizard at /wizard.
Method Path Description POST/api/wizard/mqtt-testTry connecting to the entered MQTT broker. GET/api/wizard/ha-checkConfirm HA’s homeassistant/status was seen. POST/api/wizard/namesSave device + zone labels. POST/api/wizard/completeMark onboarding done, redirect to dashboard.
All authenticated; redirect to /login if no session — except ?demo=1
which serves the page with the demo JS shim for screenshots / docs.
/ (dashboard), /heating, /hot-water, /schedule, /diagnostics,
/sniffer, /faults, /insights, /wizard, /config,
/config/device, /config/energy, /config/home-assistant,
/config/data-sources, /config/api, /config/sensors,
/config/device-info, /config/firmware.
Path Purpose /loginLogin form. /style.cssShared stylesheet. /icons.svgLucide icon sprite. /heatsync.jsDemo-mode shim used by ?demo=1 for screenshots. /favicon.svg / /favicon.icoSVG mark.