# Reference Clients

Three small, dependency-free files that cover sign-up through session and schedule for the Hungry Machines API — copy them as a starting point.

Three small files under `/examples/`, each dependency-free, that cover the same loop as the [agent guide](/guides/build-with-an-agent/): log in, refresh on a 401, set preferences, register an appliance, push readings and a weather forecast, pull or recompute a schedule, and apply the current 30-minute slot's command. Copy one as a starting point, or read it alongside the [OpenAPI description](/api-reference/openapi/) to see the same calls typed out.
- [hm_client.py](/examples/hm_client.py): Python standard library only (urllib + zoneinfo).
- [hm-client.mjs](/examples/hm-client.mjs): Plain JavaScript (fetch), no dependencies, with JSDoc types.
- [simulate_readings.py](/examples/simulate_readings.py): A testing tool: pushes synthetic readings to a test account.
## What's in each file

Both `hm_client.py` and `hm-client.mjs` implement the same client surface:

- Sign up or log in (`POST /auth/signup`, `POST /auth/login`), handling both of signup's response shapes — a session, or a pending user when email confirmation is on
- Refresh once on a 401 (`POST /auth/refresh`) and keep retrying the original call, not the caller
- Get and set preferences (`GET`/`PUT /api/v1/preferences`)
- Register an appliance (`POST /api/v1/appliances`)
- Push HVAC readings (`POST /api/v1/readings`), leaving out the optional `client` block — its `kind` names Hungry Machines' own software, not yours
- Push the home's hourly weather forecast once a day (`POST /api/v1/weather`)
- Pull today's schedule (`GET /api/v1/schedules`) or force an immediate replan (`POST /api/v1/schedule/recompute`)
- A `slot_command` / `slotCommand` helper that reads the current 30-minute slot from a given local time and returns the HVAC target temperature — falling back to the comfort band's midpoint, `(high_temps[slot] + low_temps[slot]) / 2`, when `setpoint_temps` is absent or `null` — or, for EV chargers, batteries, robots and water heaters, the boolean on/off command from `intervals[slot]`

`simulate_readings.py` is a separate testing tool, not part of the client: it imports `hm_client.py` and pushes a stream of plausible synthetic indoor/outdoor readings to one HVAC appliance, 5 minutes apart, so you can exercise a client or watch an account leave `"defaults"` without wiring up real hardware. It reads `HM_EMAIL`, `HM_PASSWORD` and `HM_APPLIANCE_ID` from environment variables and never prints them — **run it against a test account only**.

Check an entry's `source` before you hand it to the helper. An appliance with no stored plan yet comes back from `GET /api/v1/schedules` as `"schedule": {}` with `source: "defaults"`: it has no setpoints and no band, so the helper has nothing to read and there is no command to send. Skip that entry until `source` is `"optimization"`. The files also pull the schedule once; a long-running client should poll `GET /api/v1/schedules/updated-at` and pull again when its value changes.

None of the three files cover non-HVAC readings (`POST /api/v1/appliances/{appliance_id}/readings`) or constraints (`POST /api/v1/appliances/{appliance_id}/constraints`) — see [Build your own client](/guides/build-your-own-client/) for the full appliance-type matrix.

## Next steps

- [Build With an AI Agent](/guides/build-with-an-agent/) — the calls these files make, explained in order
- [Build your own client](/guides/build-your-own-client/) — the same material written for a person, with the full per-appliance-type schedule shapes
- [OpenAPI Description](/api-reference/openapi/) — every route these files call, as one machine-readable file

Canonical page: https://docs.hungrymachines.io/guides/reference-clients/
