Skip to main content
Configuration entries are the primary way to configure integrations in Home Assistant. They represent a configured instance of an integration and handle the complete lifecycle from setup to removal.

ConfigEntry Class

The ConfigEntry class represents a single configuration entry for an integration.

Initialization

domain
str
required
The integration domain
title
str
required
User-friendly title for this config entry
data
Mapping[str, Any]
required
Configuration data
source
str
required
Source of the configuration (user, discovery, import, etc.)
options
Mapping[str, Any]
Optional configuration that can be modified by the user
unique_id
str
Unique identifier for this configuration entry
entry_id
str
Entry ID (auto-generated ULID if not provided)
version
int
default:"1"
Configuration version number
minor_version
int
default:"1"
Minor version number
from homeassistant.config_entries import ConfigEntry

entry = ConfigEntry(
    domain="my_integration",
    title="My Device",
    data={"host": "192.168.1.100"},
    source="user",
    unique_id="abc123"
)

Key Attributes

entry_id
str
Unique ID for this config entry (ULID format)
domain
str
Integration domain this entry belongs to
title
str
User-friendly title
data
MappingProxyType[str, Any]
Read-only configuration data. Use async_update_entry to modify.
options
MappingProxyType[str, Any]
Read-only options. Use async_update_entry to modify.
runtime_data
Any
Runtime data that can be set by the integration during setup. This data is not persisted.
state
ConfigEntryState
Current state of the config entry (LOADED, NOT_LOADED, SETUP_ERROR, etc.)
unique_id
str | None
Unique identifier for this entry
source
str
Source that created this entry (user, discovery, import, reauth, etc.)
version
int
Major version number
minor_version
int
Minor version number
disabled_by
ConfigEntryDisabler | None
Reason the entry is disabled, if any
supports_unload
bool | None
Whether the integration supports unloading
supports_remove_device
bool | None
Whether the integration supports device removal
supports_options
bool
Whether the integration supports options flow
supports_reconfigure
bool
Whether the integration supports reconfiguration

Lifecycle Methods

async_setup(hass, *, integration=None)

Set up the config entry.
hass
HomeAssistant
required
Home Assistant instance
integration
Integration
Integration object (loaded automatically if not provided)
await entry.async_setup(hass)

async_unload(hass, *, integration=None)

Unload the config entry.
hass
HomeAssistant
required
Home Assistant instance
integration
Integration
Integration object
return
bool
True if unload was successful
success = await entry.async_unload(hass)

async_remove(hass)

Invoke the remove callback on the component.
await entry.async_remove(hass)

Task Management

async_create_task(hass, target, name=None, eager_start=True)

Create a task tied to the config entry lifecycle.
hass
HomeAssistant
required
Home Assistant instance
target
Coroutine
required
Coroutine to execute
name
str
Task name
eager_start
bool
default:"True"
Whether to start eagerly
task = entry.async_create_task(
    hass,
    my_coroutine(),
    name="my_task"
)

async_create_background_task(hass, target, name, eager_start=True)

Create a background task that’s automatically cancelled when the entry is unloaded.
task = entry.async_create_background_task(
    hass,
    long_running_task(),
    name="background_worker"
)

Listeners

add_update_listener(listener)

Listen for when the entry is updated.
listener
UpdateListenerType
required
Async function called when entry is updated
return
CALLBACK_TYPE
Function to remove the listener
async def update_listener(hass, entry):
    # Handle update
    await hass.config_entries.async_reload(entry.entry_id)

remove = entry.add_update_listener(update_listener)

async_on_unload(func)

Add a function to call when config entry is unloaded.
@callback
def cleanup():
    # Cleanup resources
    pass

entry.async_on_unload(cleanup)

Reauth

async_start_reauth(hass, context=None, data=None)

Start a reauth flow for this entry.
hass
HomeAssistant
required
Home Assistant instance
context
ConfigFlowContext
Additional context for the flow
data
dict[str, Any]
Additional data for the flow
entry.async_start_reauth(hass)

ConfigEntryState Enum

States a config entry can be in.
LOADED
str
The config entry has been set up successfully
NOT_LOADED
str
The config entry has not been loaded
SETUP_ERROR
str
There was an error while trying to set up this config entry
SETUP_RETRY
str
The config entry was not ready to be set up yet, but might be later
SETUP_IN_PROGRESS
str
The config entry is currently setting up
MIGRATION_ERROR
str
There was an error while trying to migrate the config entry
FAILED_UNLOAD
str
An error occurred when trying to unload the entry
UNLOAD_IN_PROGRESS
str
The config entry is being unloaded

Source Constants

Common sources for config entries:
from homeassistant.config_entries import (
    SOURCE_USER,          # Created by user through UI
    SOURCE_DISCOVERY,     # Auto-discovered
    SOURCE_IMPORT,        # Imported from configuration.yaml
    SOURCE_BLUETOOTH,     # Discovered via Bluetooth
    SOURCE_DHCP,          # Discovered via DHCP
    SOURCE_ZEROCONF,      # Discovered via Zeroconf
    SOURCE_SSDP,          # Discovered via SSDP
    SOURCE_USB,           # Discovered via USB
    SOURCE_MQTT,          # Discovered via MQTT
    SOURCE_HOMEKIT,       # Discovered via HomeKit
    SOURCE_REAUTH,        # Re-authentication required
    SOURCE_RECONFIGURE,   # Reconfiguration flow
    SOURCE_IGNORE,        # Ignored entry
)

ConfigEntries Manager

The ConfigEntries manager (accessible via hass.config_entries) provides methods to manage all config entries.

async_get_entry(entry_id)

Get a config entry by ID.
entry = hass.config_entries.async_get_entry(entry_id)

async_entries(domain=None)

Get all config entries, optionally filtered by domain.
# Get all entries
all_entries = hass.config_entries.async_entries()

# Get entries for a specific domain
light_entries = hass.config_entries.async_entries("light")

async_reload(entry_id)

Reload a config entry.
await hass.config_entries.async_reload(entry_id)

async_update_entry(entry, *, data=None, options=None, title=None, unique_id=None)

Update a config entry.
entry
ConfigEntry
required
Config entry to update
data
Mapping[str, Any]
New data (replaces existing data)
options
Mapping[str, Any]
New options (replaces existing options)
title
str
New title
unique_id
str
New unique_id
hass.config_entries.async_update_entry(
    entry,
    data={"host": "192.168.1.200"},
    title="Updated Title"
)

Integration Setup

Integrations implement config entry support by providing specific functions in their __init__.py:

async_setup_entry(hass, entry)

Set up the integration from a config entry.
hass
HomeAssistant
required
Home Assistant instance
entry
ConfigEntry
required
Config entry to set up
return
bool
True if setup was successful
async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Set up from a config entry."""
    # Initialize the integration
    api = MyAPI(entry.data["host"])
    
    # Store runtime data
    entry.runtime_data = api
    
    # Forward to platforms
    await hass.config_entries.async_forward_entry_setups(
        entry, ["sensor", "switch"]
    )
    
    return True

async_unload_entry(hass, entry)

Unload a config entry.
async def async_unload_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Unload a config entry."""
    # Unload platforms
    unload_ok = await hass.config_entries.async_unload_platforms(
        entry, ["sensor", "switch"]
    )
    
    return unload_ok

async_migrate_entry(hass, entry)

Migrate an old config entry to a new version.
async def async_migrate_entry(
    hass: HomeAssistant,
    entry: ConfigEntry
) -> bool:
    """Migrate old entry."""
    if entry.version == 1:
        # Migrate from version 1 to 2
        new_data = {**entry.data, "new_field": "default_value"}
        
        hass.config_entries.async_update_entry(
            entry,
            data=new_data,
            version=2
        )
    
    return True

Best Practices

Store Runtime Data

Use entry.runtime_data to store runtime objects:
# During setup
entry.runtime_data = MyAPIClient(entry.data["host"])

# In platforms
api = entry.runtime_data

Use Update Listeners

Listen for option changes:
async def async_setup_entry(hass, entry):
    # ... setup code ...
    
    entry.async_on_unload(
        entry.add_update_listener(update_listener)
    )

async def update_listener(hass, entry):
    """Handle options update."""
    await hass.config_entries.async_reload(entry.entry_id)

Handle Cleanup

Register cleanup callbacks:
async def async_setup_entry(hass, entry):
    client = MyClient()
    
    async def cleanup():
        await client.disconnect()
    
    entry.async_on_unload(cleanup)

Build docs developers (and LLMs) love