Skip to content

The Native API and Home Assistant

Scope: the conversation a device has with its owner — ESPHome's native API, its encryption, how a client listens, and the pairing with Home Assistant that most readers are here for. The API half of this chapter was exercised for real, against the lab twin, with ESPHome's own client. The Home Assistant half is described from the projects' documentation: no Home Assistant was running in the lab, and the chapter does not pretend otherwise.

One protocol, two jobs

The api: section of chapter 3 opens a server on the device (TCP port 6053) that speaks ESPHome's native API — a binary protocol designed for exactly this: a controller connecting, learning what entities the device has, receiving their state changes as they happen, and sending commands back (turn the fan on; the file's switches and much else are controllable this way). It is also the channel esphome logs uses to stream a device's log — chapter 9 lives on it.

The greenhouse configuration's version of the section is two meaningful lines:

api:
  encryption:
    key: !secret api_key

That key turns on the protocol's encryption — the Noise protocol framework (the configuration dump calls the result "Noise encryption: YES"), with the base64 key from chapter 4 as the shared secret both sides must hold. A client without the key can connect and be told, in effect, no. The honest framing: this is good, modern encryption of the same family other local protocols use, and its strength is the key's custody — one key per device is the hygiene the projects recommend, because a shared key turns one lost file into every device's problem.

A client at work

The twin's boot dump advertises the service (transcript t04, trimmed):

[C][api:368]: Server:
  Address: greenhouse-sim.local:6053
  Noise encryption: YES

And this is esphome logs, ESPHome's own API client, connecting to it (t05):

$ esphome logs greenhouse-sim.yaml --device 127.0.0.1
INFO Starting log output from 127.0.0.1 using esphome API
INFO Successfully connected to greenhouse-sim @ 127.0.0.1 in 0.005s
INFO Successful handshake with greenhouse-sim @ 127.0.0.1 in 0.479s

(The lab addressed the twin by IP because the sandbox's name service was not asked to play; on a home network the mDNS name from chapter 3 is the usual address.) Handshake done — encrypted, key accepted — the device first replays its configuration dump, then streams every state change as it happens, which is where chapter 5's fan proof came from. The device's own log of the same arrival is one dry line (t07):

[D][api.connection:2816]: ESPHome Logs 2026.10.0 (127.0.0.1): connected

Two details in the client transcript deserve a beginner's attention. The handshake time is printed — about half a second here — because on real hardware it is the first number that tells you a network is struggling. And the client is identified to the device by name and version, because the API is a conversation between named parties, not a broadcast: the device serves a handful of clients at a time (the dump says 8, with a listen backlog of 4) and knows who each is.

Home Assistant, from here

Home Assistant is the API's most important client, and the pairing — described, not performed, in this guide — works like this. A correctly built device announces itself on the network by mDNS. Home Assistant, listening, discovers it and offers a notification: new device found. Accepting takes you to the ESPHome integration's setup, which asks for the device's address and, because the greenhouse configuration encrypts, its API encryption key — the same one in your secrets.yaml, which is the moment chapter 6's filing system pays rent. Key accepted, every entity in the configuration appears in Home Assistant with its name and device class already attached: Greenhouse Temperature as a temperature, the door as a door, the fan as a switch you can flip from a dashboard or an automation.

Three honest properties of that marriage:

  • It is local. No cloud account sits in the path; the conversation above is the whole architecture. Either side being down does not stop the device's own automations (chapter 5), which run on the chip regardless.
  • The configuration is the contract. Rename a sensor in the YAML and you have renamed it for Home Assistant at the next update; the entities are the file, projected. There is no second place where the device is defined, which is the blessing and, when a rename breaks someone's dashboard, the curse.
  • MQTT is the alternative, not a requirement. ESPHome can publish to an MQTT broker instead of (or as well as) the API, for owners whose controller is not Home Assistant. The specimen doesn't: one well-lit path, honestly walked, is this guide's way.