API Mode¶
This is the simplest mode, and easiest to get started with. It doesn't require any server side components, only a token. Since it uses the standard Home Assistant APIs, it doesn't offer the same security and footgun potential as live mode. Its also simple in-process Python, without the fancy blended operation of live mode.
Its aimed to be as code compatible with live, so you can use obj code in either, and switch to live mode if you need more direct entity access without having to learn new syntax, and being able to reuse your existing plugins.
Built-ins¶
The two special variables in api mode are:
obj- the Object Tree exposed as a dictionary object and common methods, with the source being the Home Assistant APIhass_api- the Home Assistant web socket / REST API exposed using the homeassistant-api library
The objects returned by obj are of class ApiEntity, and combines the Entity class from Home Assistant, with RegistryEntity since things of common use are split across both.
Example ApiEntity¶
>>> obj["sensor.sun_next_rising"]
ApiEntity(
entity_id='sensor.sun_next_rising',
platform='sun',
domain='sensor',
object_id='sun_next_rising',
state='2026-10-09T06:34:50+00:00',
name='Sun Next rising',
state_attributes={'device_class': 'timestamp'},
area_id=None,
labels=frozenset(),
registry_entry={
'area_id': None,
'categories': {},
'config_entry_id': 'dc912d263e164495aede7834731fa675',
'config_subentry_id': None,
'created_at': 0.0,
'device_id': 'd9df6cad924f2747eab95d2b414265f0',
'disabled_by': None,
'entity_category': 'diagnostic',
'entity_id': 'sensor.sun_next_rising',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': 'f1e460ed2f879b80cbf5e2cc6b8e3c5e',
'labels': [],
'modified_at': 1770236490.999007,
'name': None,
'next_name_part': 'device',
'options': {
'cloud.alexa': {'should_expose': False},
'cloud.google_assistant': {'should_expose': False},
'conversation': {'should_expose': False}
},
'original_name': 'Next rising',
'platform': 'sun',
'translation_key': 'next_rising',
'unique_id': 'dc912d263e164495aede7834731fa675-next_rising'
}
)
In live mode the entities returned are the actual Entity objects from Home Assistant, with their full set of methods and other attributes.
Code That Works in Both Modes¶
An ApiEntity uses the real Entity names wherever it has the data, so the same expression reads the same in api and live mode:
| Expression | In api mode it comes from |
|---|---|
entity_id, state, name, state_attributes |
The entity's state |
registry_entry.unique_id, registry_entry.options, and so on |
The entity registry. Also a dict, so registry_entry["unique_id"] works in api mode |
platform.platform_name, platform.domain |
The entity registry. platform is also the plain string, so platform == "mqtt" works in api mode |
unique_id, enabled, entity_category, has_entity_name, translation_key |
The entity registry |
device_class, unit_of_measurement, icon, entity_picture, supported_features, assumed_state, attribution |
The state's attributes |
available |
False when the state is unavailable, or there is none |
domain, object_id, area_id and labels are extras that a real Entity doesn't have. The spelling that works on both is platform.domain, registry_entry.area_id and registry_entry.labels.
Some differences remain:
- Values inside
registry_entryare as the API sends them:labelsis a list where the real one is a set, andcreated_atandmodified_atare numbers where the real ones are datetimes state_attributesholds everything the state publishes, includingdevice_classandunit_of_measurement, which a realEntitykeeps out of it- There is no
device_entry,device_info,extra_state_attributesorcapability_attributes, and no methods
Home Assistant API¶
The homeassistant-api project
has native Python objects that wrap around the JSON results from Home Assistant WebSockets and REST API calls.
These can be accessed via hass_api, and mixed with the results and calls of obj, and works identically in live and api mode.
The API access is read/write, so can be used for anything that the user who issued the token can do.
Since everything is plain Python, these can be combined together in procedural or one-liner comprehension type code, and use other libraries you've imported.