Skip to main content

The integration manifest

Every integration must contain a manifest.json. This page documents every key and its allowed values exactly as enforced by the validator (python -m script.apexfest) and, for custom integrations, by the runtime loader.

Key ordering

The validator enforces a canonical key order: domain, name, then all remaining keys in alphabetical order. Running the validator with --action generate re-sorts the file for you.

Required keys

domain

The integration's unique identifier. Must be a string and must match the directory name of the integration, or validation fails with "Domain does not match dir name".

name

The human-readable name of the integration.

documentation

A URL to the integration's documentation.

  • Built-in integrations: must begin with https://www.apexinfosys.in/integrations (in practice https://www.apexinfosys.in/integrations/<domain>).
  • Custom integrations: must be an https URL and must not point at the core documentation base — it should point at the custom integration's own docs.

codeowners

A list of GitHub handles (e.g. ["@developer"]) responsible for the integration. The key is required (an empty list is accepted at schema level), but an integration with a quality_scale of silver or higher must have at least one code owner.

Optional keys

integration_type

Defaults to "hub" when omitted. Allowed values:

ValueMeaning
deviceProvides a single device
entityAn entity base platform
hardwareA hardware integration
helperA helper that operates on existing data/entities
hubConnects to a hub that exposes multiple devices
serviceA single service
systemSystem-level integration
virtualA pointer entry with no code of its own (special schema, below)

config_flow

Boolean. Set to true if the integration is set up from the UI via a config flow.

dependencies / after_dependencies

Lists of other integration domains. dependencies are set up before your integration; after_dependencies are only ordered before yours if they are going to be set up anyway.

requirements

A list of PyPI requirement strings. Pin versions with == (the scaffolder enforces this for the initial requirement).

iot_class

How the integration gathers data. Allowed values:

  • assumed_state
  • calculated
  • cloud_polling
  • cloud_push
  • local_polling
  • local_push

The IoT class is required for regular integrations ("Domain is missing an IoT Class") and forbidden for entity platforms and a fixed list of system domains such as api, auth, automation, config, frontend, hardware, onboarding, raspberry_pi, recovery_mode, repairs, zone, etc. ("Domain should not have an IoT Class"). Virtual integrations never carry one.

quality_scale

One of the scaled tiers or the non-scaled markers:

  • Scaled: bronze, silver, gold, platinum
  • Non-scaled: custom, no_score, internal, legacy

silver and above require a non-empty codeowners list. Scaled integrations also carry a quality_scale.yaml rules file (see the quality checklist).

single_config_entry

Boolean. If true, only one config entry of this integration may exist (used by e.g. the sun integration).

loggers

List of logger names used by the integration's requirements, so log levels can be managed together with the integration.

disabled

A string; when present, explains why the integration is disabled.

preview_features

A mapping of feature slugs to an object with optional feedback_url, learn_more_url, and report_issue_url (all URLs).

Discovery keys

zeroconf

A list where each item is either a service type string or a matcher object:

"zeroconf": [
"_mytype._tcp.local.",
{ "type": "_mytype._tcp.local.", "name": "myname*", "properties": { "key": "value" } }
]
  • type (required in object form)
  • name, properties values — must be lowercase
  • macaddress, model, manufacturerdeprecated in zeroconf (use the properties matcher); macaddress must be uppercase and contain a * wildcard, the others lowercase.

ssdp

A list of matcher dictionaries; each dictionary may contain arbitrary keys but must not be empty.

bluetooth

A list of matcher objects with the optional keys:

  • connectable (bool)
  • service_uuid (lowercase string)
  • service_data_uuid (lowercase string)
  • local_name (string)
  • manufacturer_id (int)
  • manufacturer_data_start (list of ints)

dhcp

A list of matcher objects:

  • macaddressuppercase, must contain a * wildcard
  • hostnamelowercase
  • registered_devices (bool)

usb

A list of matcher objects:

  • vid, piduppercase
  • serial_number, manufacturer, descriptionlowercase
  • known_devices — list of strings

mqtt

A list of MQTT topic strings to subscribe to for discovery.

homekit

An object with an optional models list (device model prefixes to discover).

Virtual integrations

When integration_type is "virtual", a different, minimal schema applies:

{
"domain": "example",
"name": "Example",
"integration_type": "virtual",
"supported_by": "other_domain"
}
  • domain, name, integration_type: "virtual" are required.
  • Exactly one of supported_by (another existing built-in domain — the validator checks it exists) or iot_standards (a list drawn from homekit, zigbee, zwave) may be present; they are mutually exclusive.

Custom-integration-only keys

Custom integrations use the same schema with these differences:

version

Required in practice. The schema marks it optional, but the validator emits "No 'version' key in the manifest file" and the runtime loader blocks the integration from loading if version is missing or invalid. The version must parse under one of these strategies: CalVer, SemVer, SimpleVer, BuildVer, or PEP 440.

issue_tracker

URL of the custom integration's issue tracker.

import_executor

Boolean; whether the integration's code is imported in an executor.

documentation

Must be https and must not start with https://www.apexinfosys.in/integrations — point it at your own documentation.

Additionally, the validator warns if a custom integration's domain collides with a built-in integration ("Domain collides with built-in core integration").

Validating your manifest

# validate everything
python -m script.apexfest --requirements --action validate

# validate a single integration directory
python -m script.apexfest --integration-path apexos/components/<domain>