Preferences
The preferences endpoints let you configure your comfort settings and optimization mode. These values control how aggressively the optimizer shifts energy usage.
These are account-level preferences. For a home with more than one HVAC, each unit also has its own per-HVAC preferences with the same shape; this account row seeds them and stays authoritative for account-scope fields.
See also Rates for the electricity rate curve the optimizer saves against.
GET /api/v1/preferences
Section titled “GET /api/v1/preferences”Auth: Required (Bearer JWT)
Example
Section titled “Example”curl https://api.hungrymachines.io/api/v1/preferences \ -H "Authorization: Bearer YOUR_TOKEN"Response (200)
Section titled “Response (200)”{ "base_temperature": 72.0, "savings_level": 1, "time_away": "08:00", "time_home": "17:00", "optimization_mode": "cool", "hourly_high_temps_f": null, "hourly_low_temps_f": null, "optimize_hvac_fan": false, "optimize_hvac_mode": false, "optimization_enabled": true, "newsletter_opt_in": true}If the user hasn’t set preferences yet, defaults are returned.
Fields
Section titled “Fields”| Field | Type | Default | Description |
|---|---|---|---|
base_temperature | float | 72.0 | Desired temperature (°F) |
savings_level | integer | 1 | How far the optimizer can deviate from base temp |
time_away | string | "08:00" | When you typically leave home (HH:MM) |
time_home | string | "17:00" | When you typically return home (HH:MM) |
optimization_mode | string | "cool" | "cool", "heat", "auto", or "off" |
hourly_high_temps_f | array[float] | null | null | Optional 24-element per-hour upper comfort bound (°F). When set, takes precedence over base_temperature + savings_level + time_away/time_home. |
hourly_low_temps_f | array[float] | null | null | Optional 24-element per-hour lower comfort bound (°F). When set, takes precedence over base_temperature + savings_level + time_away/time_home. |
optimize_hvac_fan | boolean | false | Opt-in: also emit a per-slot fan-speed schedule. |
optimize_hvac_mode | boolean | false | Opt-in: also emit a per-slot HVAC-mode schedule. |
optimization_enabled | boolean | true | Master pause switch. When false, clients must stop applying schedules entirely until re-enabled. Schedules are still computed, so re-enabling takes effect at the next half-hour boundary. |
newsletter_opt_in | boolean | true | Newsletter membership. Changing only this field does not trigger a schedule recompute. |
Savings levels
Section titled “Savings levels”| Level | Band | Behavior |
|---|---|---|
| 1 (tight) | ±2 °F | Conservative — minimal deviation from base temperature |
| 2 (moderate) | ±6 °F | Balanced — noticeable pre-cooling/pre-heating during away hours |
| 3 (aggressive) | ±12 °F | Maximum savings — wider temperature swings, especially when away |
Hourly comfort bands (advanced)
Section titled “Hourly comfort bands (advanced)”The default comfort band is symmetric around base_temperature, widened by savings_level during the time_away window. If you want explicit per-hour bounds — for example, a tighter band during occupied hours and a wider band overnight — submit hourly_high_temps_f and hourly_low_temps_f together.
- Both arrays must be set together, or both must be
nullto clear the override. - Each array is exactly 24 values, indexed
0(midnight) through23(11 PM local time). - Each value must be in
[50, 90]°F. - For every hour
i,hourly_low_temps_f[i] < hourly_high_temps_f[i]. - When the override is set,
time_away,time_home, andsavings_levelare ignored — the optimizer respects the explicit bounds at every hour.
Example: tighter [68, 74] band from 8 AM through 9 PM, wider [64, 78] band overnight.
{ "hourly_high_temps_f": [78, 78, 78, 78, 78, 78, 78, 78, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 78, 78], "hourly_low_temps_f": [64, 64, 64, 64, 64, 64, 64, 64, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 64, 64]}PUT /api/v1/preferences
Section titled “PUT /api/v1/preferences”Auth: Required (Bearer JWT)
Update one or more preference fields. All fields are optional — only the fields you include are changed; others keep their current values.
Example
Section titled “Example”curl -X PUT https://api.hungrymachines.io/api/v1/preferences \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "base_temperature": 73.0, "savings_level": 2, "optimization_mode": "auto" }'Request body
Section titled “Request body”All fields are optional — include only what you want to change.
{ "base_temperature": 73.0, "savings_level": 2, "time_away": "07:30", "time_home": "18:00", "optimization_mode": "auto"}Validation
Section titled “Validation”| Field | Constraints |
|---|---|
base_temperature | 60.0–85.0 °F |
savings_level | 1, 2, or 3 |
time_away | HH:MM format |
time_home | HH:MM format |
optimization_mode | "cool", "heat", "auto", "off" |
hourly_high_temps_f | Exactly 24 finite floats, each in [50, 90] °F |
hourly_low_temps_f | Exactly 24 finite floats, each in [50, 90] °F |
hourly_low_temps_f[i] < hourly_high_temps_f[i] | Per-hour lower bound must be strictly less than upper bound |
hourly_high_temps_f + hourly_low_temps_f | Both fields must be set together (or both null to clear) |
optimize_hvac_fan | true / false |
optimize_hvac_mode | true / false |
optimization_enabled | true / false |
newsletter_opt_in | true / false |
Response (200)
Section titled “Response (200)”Returns the full preferences object after the update (same shape as GET):
{ "base_temperature": 73.0, "savings_level": 2, "time_away": "07:30", "time_home": "18:00", "optimization_mode": "auto"}Errors
Section titled “Errors”| Status | Detail | Cause |
|---|---|---|
| 400 | "base_temperature must be between 60 and 85" | Validation failure |
| 400 | "hourly_high_temps_f and hourly_low_temps_f must be set together or both cleared" | Only one of the two arrays was provided as a non-null value |
| 400 | "hourly_high_temps_f and hourly_low_temps_f must each have exactly 24 values" | Wrong array length |
| 400 | "hourly bands at hour <i> must be between 50 and 90 F" | Value out of range at hour <i> |
| 400 | "hourly low must be less than high at hour <i>" | hourly_low_temps_f[i] >= hourly_high_temps_f[i] |
| 401 | "Not authenticated" | Missing or invalid token |