> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/home-assistant/core/llms.txt
> Use this file to discover all available pages before exploring further.

# Config Entries

> Configuration entry management in Home Assistant

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

<ParamField path="domain" type="str" required>
  The integration domain
</ParamField>

<ParamField path="title" type="str" required>
  User-friendly title for this config entry
</ParamField>

<ParamField path="data" type="Mapping[str, Any]" required>
  Configuration data
</ParamField>

<ParamField path="source" type="str" required>
  Source of the configuration (user, discovery, import, etc.)
</ParamField>

<ParamField path="options" type="Mapping[str, Any]">
  Optional configuration that can be modified by the user
</ParamField>

<ParamField path="unique_id" type="str">
  Unique identifier for this configuration entry
</ParamField>

<ParamField path="entry_id" type="str">
  Entry ID (auto-generated ULID if not provided)
</ParamField>

<ParamField path="version" type="int" default="1">
  Configuration version number
</ParamField>

<ParamField path="minor_version" type="int" default="1">
  Minor version number
</ParamField>

```python theme={null}
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

<ResponseField name="entry_id" type="str">
  Unique ID for this config entry (ULID format)
</ResponseField>

<ResponseField name="domain" type="str">
  Integration domain this entry belongs to
</ResponseField>

<ResponseField name="title" type="str">
  User-friendly title
</ResponseField>

<ResponseField name="data" type="MappingProxyType[str, Any]">
  Read-only configuration data. Use `async_update_entry` to modify.
</ResponseField>

<ResponseField name="options" type="MappingProxyType[str, Any]">
  Read-only options. Use `async_update_entry` to modify.
</ResponseField>

<ResponseField name="runtime_data" type="Any">
  Runtime data that can be set by the integration during setup. This data is not persisted.
</ResponseField>

<ResponseField name="state" type="ConfigEntryState">
  Current state of the config entry (LOADED, NOT\_LOADED, SETUP\_ERROR, etc.)
</ResponseField>

<ResponseField name="unique_id" type="str | None">
  Unique identifier for this entry
</ResponseField>

<ResponseField name="source" type="str">
  Source that created this entry (user, discovery, import, reauth, etc.)
</ResponseField>

<ResponseField name="version" type="int">
  Major version number
</ResponseField>

<ResponseField name="minor_version" type="int">
  Minor version number
</ResponseField>

<ResponseField name="disabled_by" type="ConfigEntryDisabler | None">
  Reason the entry is disabled, if any
</ResponseField>

<ResponseField name="supports_unload" type="bool | None">
  Whether the integration supports unloading
</ResponseField>

<ResponseField name="supports_remove_device" type="bool | None">
  Whether the integration supports device removal
</ResponseField>

<ResponseField name="supports_options" type="bool">
  Whether the integration supports options flow
</ResponseField>

<ResponseField name="supports_reconfigure" type="bool">
  Whether the integration supports reconfiguration
</ResponseField>

### Lifecycle Methods

#### async\_setup(hass, \*, integration=None)

Set up the config entry.

<ParamField path="hass" type="HomeAssistant" required>
  Home Assistant instance
</ParamField>

<ParamField path="integration" type="Integration">
  Integration object (loaded automatically if not provided)
</ParamField>

```python theme={null}
await entry.async_setup(hass)
```

#### async\_unload(hass, \*, integration=None)

Unload the config entry.

<ParamField path="hass" type="HomeAssistant" required>
  Home Assistant instance
</ParamField>

<ParamField path="integration" type="Integration">
  Integration object
</ParamField>

<ResponseField name="return" type="bool">
  True if unload was successful
</ResponseField>

```python theme={null}
success = await entry.async_unload(hass)
```

#### async\_remove(hass)

Invoke the remove callback on the component.

```python theme={null}
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.

<ParamField path="hass" type="HomeAssistant" required>
  Home Assistant instance
</ParamField>

<ParamField path="target" type="Coroutine" required>
  Coroutine to execute
</ParamField>

<ParamField path="name" type="str">
  Task name
</ParamField>

<ParamField path="eager_start" type="bool" default="True">
  Whether to start eagerly
</ParamField>

```python theme={null}
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.

```python theme={null}
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.

<ParamField path="listener" type="UpdateListenerType" required>
  Async function called when entry is updated
</ParamField>

<ResponseField name="return" type="CALLBACK_TYPE">
  Function to remove the listener
</ResponseField>

```python theme={null}
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.

```python theme={null}
@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.

<ParamField path="hass" type="HomeAssistant" required>
  Home Assistant instance
</ParamField>

<ParamField path="context" type="ConfigFlowContext">
  Additional context for the flow
</ParamField>

<ParamField path="data" type="dict[str, Any]">
  Additional data for the flow
</ParamField>

```python theme={null}
entry.async_start_reauth(hass)
```

## ConfigEntryState Enum

States a config entry can be in.

<ResponseField name="LOADED" type="str">
  The config entry has been set up successfully
</ResponseField>

<ResponseField name="NOT_LOADED" type="str">
  The config entry has not been loaded
</ResponseField>

<ResponseField name="SETUP_ERROR" type="str">
  There was an error while trying to set up this config entry
</ResponseField>

<ResponseField name="SETUP_RETRY" type="str">
  The config entry was not ready to be set up yet, but might be later
</ResponseField>

<ResponseField name="SETUP_IN_PROGRESS" type="str">
  The config entry is currently setting up
</ResponseField>

<ResponseField name="MIGRATION_ERROR" type="str">
  There was an error while trying to migrate the config entry
</ResponseField>

<ResponseField name="FAILED_UNLOAD" type="str">
  An error occurred when trying to unload the entry
</ResponseField>

<ResponseField name="UNLOAD_IN_PROGRESS" type="str">
  The config entry is being unloaded
</ResponseField>

## Source Constants

Common sources for config entries:

```python theme={null}
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.

```python theme={null}
entry = hass.config_entries.async_get_entry(entry_id)
```

### async\_entries(domain=None)

Get all config entries, optionally filtered by domain.

```python theme={null}
# 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.

```python theme={null}
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.

<ParamField path="entry" type="ConfigEntry" required>
  Config entry to update
</ParamField>

<ParamField path="data" type="Mapping[str, Any]">
  New data (replaces existing data)
</ParamField>

<ParamField path="options" type="Mapping[str, Any]">
  New options (replaces existing options)
</ParamField>

<ParamField path="title" type="str">
  New title
</ParamField>

<ParamField path="unique_id" type="str">
  New unique\_id
</ParamField>

```python theme={null}
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.

<ParamField path="hass" type="HomeAssistant" required>
  Home Assistant instance
</ParamField>

<ParamField path="entry" type="ConfigEntry" required>
  Config entry to set up
</ParamField>

<ResponseField name="return" type="bool">
  True if setup was successful
</ResponseField>

```python theme={null}
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.

```python theme={null}
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.

```python theme={null}
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:

```python theme={null}
# During setup
entry.runtime_data = MyAPIClient(entry.data["host"])

# In platforms
api = entry.runtime_data
```

### Use Update Listeners

Listen for option changes:

```python theme={null}
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:

```python theme={null}
async def async_setup_entry(hass, entry):
    client = MyClient()
    
    async def cleanup():
        await client.disconnect()
    
    entry.async_on_unload(cleanup)
```
