> ## 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.

# Creating a New Integration

> Step-by-step guide to creating a new Home Assistant integration

This guide will walk you through creating a new integration for Home Assistant. We'll cover the essential files, structure, and best practices for building a high-quality integration.

## Prerequisites

Before you begin, ensure you have:

* A working Home Assistant development environment
* Python 3.12 or later installed
* Familiarity with async/await patterns in Python
* Understanding of the device or service you want to integrate

## Integration Structure

A basic integration consists of several key files:

```
homeassistant/components/your_integration/
├── __init__.py           # Main integration setup
├── manifest.json         # Integration metadata
├── config_flow.py        # Configuration UI flow
├── const.py             # Constants and configuration keys
├── sensor.py            # Entity platform (example)
└── strings.json         # Translations for UI
```

## Step 1: Create the Manifest

The `manifest.json` file defines your integration's metadata. This is required for Home Assistant to recognize your integration.

```json title="manifest.json" theme={null}
{
  "domain": "your_integration",
  "name": "Your Integration",
  "codeowners": ["@your-github-username"],
  "config_flow": true,
  "documentation": "https://www.home-assistant.io/integrations/your_integration",
  "iot_class": "cloud_polling",
  "requirements": ["your-library==1.0.0"],
  "version": "1.0.0"
}
```

### Key Manifest Fields

* **domain**: Unique identifier for your integration (lowercase, no spaces)
* **name**: Human-readable name displayed in the UI
* **config\_flow**: Set to `true` if your integration uses the UI configuration flow
* **iot\_class**: How the integration communicates (see IoT class documentation)
* **requirements**: Python packages required by your integration
* **codeowners**: GitHub usernames responsible for maintaining this integration

## Step 2: Define Constants

Create a `const.py` file to store configuration keys and constants:

```python title="const.py" theme={null}
"""Constants for the Your Integration integration."""

DOMAIN = "your_integration"

# Configuration keys
CONF_API_KEY = "api_key"
CONF_HOST = "host"

# Default values
DEFAULT_PORT = 8080
DEFAULT_SCAN_INTERVAL = 60
```

## Step 3: Implement the Main Integration

The `__init__.py` file contains the core integration setup logic:

```python title="__init__.py" theme={null}
"""The Your Integration integration."""
from __future__ import annotations

import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

# List of platforms to support
PLATFORMS: list[Platform] = [Platform.SENSOR]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Your Integration from a config entry."""
    # Store an API client or coordinator in hass.data
    hass.data.setdefault(DOMAIN, {})
    
    try:
        # Initialize your API client or data coordinator
        # Example: api_client = YourAPIClient(entry.data[CONF_API_KEY])
        # await api_client.async_connect()
        
        # Store the client for use by platforms
        hass.data[DOMAIN][entry.entry_id] = {
            "client": None,  # Your API client here
        }
    except Exception as err:
        raise ConfigEntryNotReady(f"Unable to connect: {err}") from err
    
    # Forward the setup to platforms
    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
    
    return True


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, PLATFORMS)
    
    if unload_ok:
        # Clean up stored data
        hass.data[DOMAIN].pop(entry.entry_id)
    
    return unload_ok
```

### Key Functions

#### async\_setup\_entry

This is the main entry point for modern integrations. It:

1. Initializes API clients or data coordinators
2. Stores shared data in `hass.data[DOMAIN]`
3. Forwards setup to entity platforms
4. Returns `True` on success or raises `ConfigEntryNotReady` on failure

#### async\_unload\_entry

Cleans up when the integration is removed:

1. Unloads all entity platforms
2. Cleans up stored data
3. Closes API connections if needed

## Step 4: Create a Config Flow

The config flow handles user configuration through the UI. See the [Config Entries guide](/guides/config-entries) for detailed information.

```python title="config_flow.py" theme={null}
"""Config flow for Your Integration."""
from __future__ import annotations

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.data_entry_flow import FlowResult

from .const import CONF_API_KEY, DOMAIN


class YourIntegrationConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
    """Handle a config flow for Your Integration."""
    
    VERSION = 1
    
    async def async_step_user(
        self, user_input: dict[str, Any] | None = None
    ) -> FlowResult:
        """Handle the initial step."""
        errors = {}
        
        if user_input is not None:
            # Validate the input
            try:
                # Test the connection with provided credentials
                # await validate_credentials(user_input[CONF_API_KEY])
                
                # Create the config entry
                return self.async_create_entry(
                    title="Your Integration",
                    data=user_input,
                )
            except Exception:
                errors["base"] = "cannot_connect"
        
        # Show the configuration form
        return self.async_show_form(
            step_id="user",
            data_schema=vol.Schema({
                vol.Required(CONF_API_KEY): str,
            }),
            errors=errors,
        )
```

## Step 5: Create Entity Platforms

Entity platforms provide the actual functionality. For example, a sensor platform:

```python title="sensor.py" theme={null}
"""Sensor platform for Your Integration."""
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN


async def async_setup_entry(
    hass: HomeAssistant,
    entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up sensor platform."""
    # Get the API client from hass.data
    client = hass.data[DOMAIN][entry.entry_id]["client"]
    
    # Create sensor entities
    async_add_entities([
        YourSensor(client, "temperature"),
        YourSensor(client, "humidity"),
    ])


class YourSensor(SensorEntity):
    """Representation of a Your Integration sensor."""
    
    def __init__(self, client, sensor_type):
        """Initialize the sensor."""
        self._client = client
        self._sensor_type = sensor_type
        self._attr_name = f"Your Integration {sensor_type}"
        self._attr_unique_id = f"{DOMAIN}_{sensor_type}"
    
    async def async_update(self) -> None:
        """Fetch new state data for the sensor."""
        # Update the sensor value
        # self._attr_native_value = await self._client.get_value(self._sensor_type)
        pass
```

See the [Entity Component guide](/guides/entity-component) for more details on creating entities.

## Step 6: Add Translations

Create a `strings.json` file for UI translations:

```json title="strings.json" theme={null}
{
  "config": {
    "step": {
      "user": {
        "title": "Connect to Your Integration",
        "description": "Enter your API credentials",
        "data": {
          "api_key": "API Key"
        }
      }
    },
    "error": {
      "cannot_connect": "Failed to connect, please check your API key"
    }
  }
}
```

## Testing Your Integration

Before submitting your integration:

1. **Run tests**: Ensure your integration has comprehensive test coverage
2. **Check code quality**: Run `pylint` and `mypy` on your code
3. **Test manually**: Install your integration in a development Home Assistant instance
4. **Review the checklist**: Follow the integration quality scale requirements

## Best Practices

### Use DataUpdateCoordinator

For integrations that poll data, use `DataUpdateCoordinator` to efficiently manage updates:

```python theme={null}
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

coordinator = DataUpdateCoordinator(
    hass,
    _LOGGER,
    name="your_integration",
    update_method=async_update_data,
    update_interval=timedelta(seconds=60),
)
```

### Handle Connection Errors

Always handle connection errors gracefully:

* Raise `ConfigEntryNotReady` during setup if the device is temporarily unavailable
* Raise `ConfigEntryAuthFailed` if authentication fails
* Set entity `available` property based on connection status

### Use Unique IDs

Always provide unique IDs for entities to enable customization:

```python theme={null}
self._attr_unique_id = f"{entry.entry_id}_{device_id}_{sensor_type}"
```

### Follow the Quality Scale

Aim for at least Silver quality scale:

* Use config flow (no YAML configuration)
* Implement proper entity naming
* Handle errors gracefully
* Provide translations
* Include tests

## Next Steps

* [Learn about Config Entries](/guides/config-entries)
* [Create Entity Components](/guides/entity-component)
* [Implement Device Automation](/guides/device-automation)
* Review existing integrations for examples
* Read the [Integration Quality Scale](https://developers.home-assistant.io/docs/integration_quality_scale_index/)

## Common Patterns

### Single Config Entry Integrations

For services that should only have one configuration:

```json title="manifest.json" theme={null}
{
  "single_config_entry": true
}
```

### Virtual Integrations

For integrations that re-use another integration's code:

```json title="manifest.json" theme={null}
{
  "integration_type": "virtual"
}
```

## Resources

* [Home Assistant Developer Documentation](https://developers.home-assistant.io/)
* [Integration Examples](https://github.com/home-assistant/core/tree/dev/homeassistant/components)
* [Discord Developer Channel](https://discord.gg/home-assistant)
