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

> Helpers for configuration validation using voluptuous schemas.

The `homeassistant.helpers.config_validation` module provides validators and schemas for configuration validation using the voluptuous library.

## Common Validators

### Basic Types

#### boolean

Validate and coerce a boolean value.

<ParamField path="value" type="Any" required>
  Value to validate (accepts bool, str, number)
</ParamField>

<ResponseField name="return" type="bool">
  Validated boolean value
</ResponseField>

```python theme={null}
import homeassistant.helpers.config_validation as cv

result = cv.boolean("yes")  # Returns: True
result = cv.boolean("0")    # Returns: False
result = cv.boolean(1)      # Returns: True
```

#### string

Coerce value to string, except for None.

<ParamField path="value" type="Any" required>
  Value to coerce
</ParamField>

<ResponseField name="return" type="str">
  String representation of value
</ResponseField>

```python theme={null}
result = cv.string("hello")  # Returns: "hello"
result = cv.string(123)      # Returns: "123"
# cv.string(None)  # Raises vol.Invalid
```

### Entity and Service Validators

#### entity\_id

Validate entity ID.

<ParamField path="value" type="Any" required>
  Value to validate
</ParamField>

<ResponseField name="return" type="str">
  Validated lowercase entity ID
</ResponseField>

```python theme={null}
result = cv.entity_id("Light.Living_Room")  # Returns: "light.living_room"
```

#### entity\_ids

Validate a list of entity IDs.

<ParamField path="value" type="str | list" required>
  Comma-separated string or list of entity IDs
</ParamField>

<ResponseField name="return" type="list[str]">
  List of validated entity IDs
</ResponseField>

```python theme={null}
result = cv.entity_ids("light.living_room, light.bedroom")
# Returns: ["light.living_room", "light.bedroom"]

result = cv.entity_ids(["light.living_room", "light.bedroom"])
# Returns: ["light.living_room", "light.bedroom"]
```

#### entity\_domain

Validate that entity belongs to specific domain.

<ParamField path="domain" type="str | list[str]" required>
  Domain(s) to validate against
</ParamField>

<ResponseField name="return" type="Callable[[Any], str]">
  Validator function
</ResponseField>

```python theme={null}
validate_light = cv.entity_domain("light")
result = validate_light("light.living_room")  # Returns: "light.living_room"
# validate_light("switch.outlet")  # Raises vol.Invalid
```

#### service

Validate service name format.

<ParamField path="value" type="Any" required>
  Value to validate
</ParamField>

<ResponseField name="return" type="str">
  Validated service name
</ResponseField>

```python theme={null}
result = cv.service("light.turn_on")  # Returns: "light.turn_on"
```

### Numeric Validators

#### positive\_int

Validate positive integer.

```python theme={null}
positive_int = vol.All(vol.Coerce(int), vol.Range(min=0))
```

#### positive\_float

Validate positive float.

```python theme={null}
positive_float = vol.All(vol.Coerce(float), vol.Range(min=0))
```

#### port

Validate port number (1-65535).

```python theme={null}
port = vol.All(vol.Coerce(int), vol.Range(min=1, max=65535))
```

#### byte

Validate byte value (0-255).

```python theme={null}
byte = vol.All(vol.Coerce(int), vol.Range(min=0, max=255))
```

### Geographic Validators

#### latitude

Validate latitude (-90 to 90).

```python theme={null}
latitude = vol.All(
    vol.Coerce(float),
    vol.Range(min=-90, max=90),
    msg="invalid latitude"
)
```

#### longitude

Validate longitude (-180 to 180).

```python theme={null}
longitude = vol.All(
    vol.Coerce(float),
    vol.Range(min=-180, max=180),
    msg="invalid longitude"
)
```

#### gps

Validate GPS coordinates.

```python theme={null}
gps = vol.ExactSequence([latitude, longitude])

result = cv.gps([51.5074, -0.1278])  # Valid
```

### Time and Date Validators

#### time

Validate and transform a time.

<ParamField path="value" type="Any" required>
  Time value to validate
</ParamField>

<ResponseField name="return" type="time">
  Validated time object
</ResponseField>

```python theme={null}
result = cv.time("14:30:00")  # Returns: time(14, 30, 0)
```

#### date

Validate and transform a date.

<ParamField path="value" type="Any" required>
  Date value to validate
</ParamField>

<ResponseField name="return" type="date">
  Validated date object
</ResponseField>

#### time\_period

Validate time period (timedelta).

```python theme={null}
result = cv.time_period("00:05:00")  # Returns: timedelta(minutes=5)
result = cv.time_period(300)         # Returns: timedelta(seconds=300)
result = cv.time_period({"minutes": 5})  # Returns: timedelta(minutes=5)
```

#### positive\_time\_period

Validate positive time period.

```python theme={null}
positive_time_period = vol.All(time_period, positive_timedelta)
```

### Template Validators

#### template

Validate a jinja2 template.

<ParamField path="value" type="Any" required>
  Template string to validate
</ParamField>

<ResponseField name="return" type="Template">
  Validated Template object
</ResponseField>

```python theme={null}
result = cv.template("{{ states('sensor.temperature') }}")
```

#### dynamic\_template

Validate a dynamic (non-static) jinja2 template.

<ParamField path="value" type="Any" required>
  Template string to validate (must contain template syntax)
</ParamField>

<ResponseField name="return" type="Template">
  Validated Template object
</ResponseField>

```python theme={null}
result = cv.dynamic_template("{{ now() }}")
# cv.dynamic_template("static")  # Raises vol.Invalid
```

### URL Validators

#### url

Validate a URL.

<ParamField path="value" type="Any" required>
  URL to validate
</ParamField>

<ResponseField name="return" type="str">
  Validated URL
</ResponseField>

```python theme={null}
result = cv.url("https://example.com")  # Valid
result = cv.url("http://example.com")   # Valid
```

#### configuration\_url

Validate a URL that allows the homeassistant scheme.

```python theme={null}
result = cv.configuration_url("homeassistant://navigate/lovelace/dashboard")
result = cv.configuration_url("https://example.com")
```

### File System Validators

#### path

Validate it's a safe path.

<ParamField path="value" type="Any" required>
  Path to validate
</ParamField>

<ResponseField name="return" type="str">
  Validated path
</ResponseField>

```python theme={null}
result = cv.path("/config/custom_components")  # Valid path
```

#### isfile

Validate that the value is an existing file.

```python theme={null}
result = cv.isfile("/config/configuration.yaml")  # Valid if file exists
```

#### isdir

Validate that the value is an existing directory.

```python theme={null}
result = cv.isdir("/config")  # Valid if directory exists
```

## Schema Helpers

### has\_at\_least\_one\_key

Validate that at least one key exists.

```python theme={null}
schema = vol.Schema(
    vol.All(
        {
            vol.Optional("name"): str,
            vol.Optional("id"): int,
        },
        cv.has_at_least_one_key("name", "id")
    )
)
```

### has\_at\_most\_one\_key

Validate that zero keys exist or one key exists.

```python theme={null}
schema = vol.Schema(
    vol.All(
        {
            vol.Optional("action"): str,
            vol.Optional("service"): str,
        },
        cv.has_at_most_one_key("action", "service")
    )
)
```

### deprecated

Log key as deprecated and provide a replacement.

<ParamField path="key" type="str" required>
  Deprecated key name
</ParamField>

<ParamField path="replacement_key" type="str | None" default="None">
  Replacement key name
</ParamField>

<ParamField path="default" type="Any | None" default="None">
  Default value
</ParamField>

<ParamField path="raise_if_present" type="bool" default="False">
  Whether to raise exception if key is present
</ParamField>

```python theme={null}
schema = vol.Schema(
    vol.All(
        {
            vol.Optional("name"): str,
        },
        cv.deprecated("entity_namespace", replacement_key="name")
    )
)
```

### make\_entity\_service\_schema

Create an entity service schema.

<ParamField path="schema" type="dict | None" required>
  Service data schema
</ParamField>

<ParamField path="extra" type="int" default="vol.PREVENT_EXTRA">
  Extra keys handling (vol.PREVENT\_EXTRA or vol.ALLOW\_EXTRA)
</ParamField>

<ResponseField name="return" type="VolSchemaType">
  Entity service schema
</ResponseField>

```python theme={null}
SERVICE_TURN_ON_SCHEMA = cv.make_entity_service_schema(
    {
        vol.Optional("brightness"): vol.All(vol.Coerce(int), vol.Range(0, 255)),
        vol.Optional("color_temp"): vol.All(vol.Coerce(int), vol.Range(153, 500)),
    }
)
```

## Pre-built Schemas

### PLATFORM\_SCHEMA\_BASE

Base schema for platform configuration.

```python theme={null}
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA_BASE.extend({
    vol.Required("api_key"): cv.string,
    vol.Optional("scan_interval"): cv.positive_time_period,
})
```

### ENTITY\_SERVICE\_FIELDS

Fields for entity service schemas (entity\_id, device\_id, area\_id, floor\_id, label\_id).

### TARGET\_SERVICE\_FIELDS

Fields for target service schemas (supports entity registry IDs).

## Constants

* `CONF_PLATFORM` - "platform" key
* `CONF_ENTITY_ID` - "entity\_id" key
* `CONF_DEVICE_ID` - "device\_id" key
* `CONF_AREA_ID` - "area\_id" key
* `CONF_NAME` - "name" key
* `CONF_SCAN_INTERVAL` - "scan\_interval" key
