Manifest
Every field of manifest.json and what the registry validates.
{
"domain": "x_acme_thing",
"version": "1.0.0",
"name": "Acme Thing",
"brand": "Acme",
"description": "Controls Acme Things over the LAN.",
"author": "Jane Developer",
"homepage": "https://example.com/acme-thing",
"iotClass": "LocalPoll",
"singleton": false,
"platforms": ["switch", "sensor"],
"permissions": ["http", "timers"],
"exposedConfigFields": ["host"],
"configFlow": {
"pages": [{
"id": "connect",
"title": "Connect",
"inputs": [
{ "key": "host", "label": "Host or IP", "type": "string", "required": true, "scope": "data" },
{ "key": "pollSeconds", "label": "Poll every (s)", "type": "number", "default": 30, "scope": "options" }
]
}]
}
}| Field | Meaning |
|---|---|
domain | x_<vendor>_<name>: lowercase, digits, single underscores; at most 64 characters; unique across the registry |
version | semver 1.2.3; each (domain, version) is published once |
name, brand, description, author, homepage? | catalog copy shown in the Add integration picker |
iotClass | LocalPush, LocalPoll, CloudPoll or CloudPush: how the integration learns about changes |
singleton | one config entry per hub |
platforms | entity platforms you will create: sensor, binary_sensor, switch, light, cover, lock, select |
permissions | http (LAN / internet HTTP, never loopback), kv (persistent storage), timers (setTimeout / setInterval) |
exposedConfigFields | config keys safe to show unmasked (host, port). Everything else is masked in every UI |
configFlow | the install wizard: pages of inputs, each scoped data (identity, set once) or options (tunable later) |
optionsFlow? | a custom "edit options" form; defaults to every options-scoped input |
The registry validates with the same zod schema the hub uses (communityIntegrationManifestSchema,
exported by the SDK). The exact enumerations (platforms, permissions, form input types,
iotClass, the bundle size cap) are generated on the SDK API reference.
Permissions
Ask only for what you use: the picker shows them, and a call without the permission is refused at
run time. An integration without http can still publish entities fed by kv or timers (a
virtual device), but most real integrations need http.