Documentation
Connect Zigbee2MQTT to ZigStream
A one-file extension forwards your Zigbee2MQTT messages to your ZigStream account. The whole setup takes about five minutes and requires no changes to your MQTT broker.
On this page
Requirements
- Zigbee2MQTT 1.36 or newer, running as a service or container.
- Write access to the Zigbee2MQTT
data/folder. - Outbound HTTPS on port 443. No inbound ports or port forwarding.
- A ZigStream account and one API key.
1. Generate an API key
Open your dashboard, go to Settings → API keys and create a key named after the host running Zigbee2MQTT.
Keys are shown once, are scoped to your account, and can be revoked at any time without touching your other integrations.
2. Install the forwarder
Download the extension into the Zigbee2MQTT extension folder.
# from your Zigbee2MQTT host
cd /opt/zigbee2mqtt/data
mkdir -p extension
curl -fsSL https://www.zigstream.app/downloads/http-forwarder.mjs \
-o extension/http-forwarder.mjs3. configuration.yaml reference
Add the following blocks todata/configuration.yaml.
advanced:
enable_external_js: true
http_forwarder:
endpoint: "https://ingest.zigstream.app/ingest"
token: "mk_live_xxxxxxxxxxxxxxxx"
# batching
batch_size: 50
flush_interval_ms: 5000
# forwarder reporting
heartbeat_interval_ms: 900000 # 15 minutes
inventory_interval_ms: 21600000 # 6 hours
# optional
debug: false
debug_payloads: false
exclude_topics:
- "zigbee2mqtt/bridge/logging"
- "zigbee2mqtt/bridge/request/#"
- "zigbee2mqtt/bridge/response/#"
- "zigbee2mqtt/+/availability"| Option | Type | Default | Description |
|---|---|---|---|
endpoint | string | — | Ingest URL. Use the regional endpoint shown in your dashboard. |
token | string | — | Scoped API key. Treat it as a secret and rotate it from Settings. |
batch_size | number | 50 | Maximum messages per request before an early flush. |
flush_interval_ms | number | 5000 | Time between pushes, in milliseconds. Lower means fresher data and more requests. |
heartbeat_interval_ms | number | 900000 | How often the forwarder reports its status and version to ZigStream (minimum 60000). |
inventory_interval_ms | number | 21600000 | How often the full device inventory is re-sent (minimum 300000). |
debug | boolean | false | Enable debug logging for the forwarder. |
debug_payloads | boolean | false | Include message payloads in debug logs (useful for troubleshooting, but verbose). |
exclude_topics | string[] | [] | Topic patterns to drop locally before anything leaves your network. Supports + (single level) and# (remaining levels) wildcards. |
The extension forwards all non-excluded MQTT publications to your ZigStream account. In addition, it sends two kinds of synthetic events through the same /ingest endpoint:
- Forwarder status events : These include the forwarder name, version, protocol version, and current configuration. Sent at startup and then every
heartbeat_interval_ms. - Device inventory snapshots : These contain the full list of devices known to Zigbee2MQTT. Sent at startup and then every
inventory_interval_ms.
You do not need to configure anything special on ZigStream to receive these; they are treated like any other ingested events and used to keep your bridge and device views up to date.
4. Restart & verify
Restart Zigbee2MQTT. Watch its log forhttp_forwarder: started.
Within one batch interval, your devices should appear under Devices in your dashboard.
Troubleshooting
- No devices appear: confirm
enable_external_js: trueis set. Zigbee2MQTT 2.11+ disables external extensions by default. - 401 errors in the log: the token was revoked or mistyped. Generate a fresh one from API keys.
- 429 errors: you are exceeding your plan’s ingest rate. Increase
flush_interval_msor reducebatch_size, or upgrade your plan. - Forwarder not reporting status: check that
heartbeat_interval_msis set and above 60000. Ensure your Zigbee2MQTT instance is not restarting more frequently than the heartbeat interval.