Two useful integration patterns

  • MQTT: a local, asynchronous publish/subscribe bus. Great for device state and commands.
  • Webhook: an HTTP request pushed to a URL. Great for an event crossing systems such as a form submission, n8n workflow, or external API.

Neither is “better.” Use MQTT for continuous local state/event streams; use webhooks for explicit cross-system requests.

MQTT vocabulary

TermMeaning
BrokerServer that routes messages
TopicHierarchical address, e.g. home/coop/door/state
PublisherSends a message
SubscriberReceives matching messages
PayloadMessage body, often JSON
Retained messageBroker remembers last value for new subscribers
QoSDelivery assurance level
LWTLast Will and Testament availability message

Topic design

Use predictable nouns and state/action separation:

home/coop/door/state
home/coop/door/command
home/coop/door/availability
home/water-feature/pump/state

Avoid vague or versionless topics such as data or status2. Plan the schema so another system can understand it without reverse-engineering firmware.

Retained state and commands

Retain current state, not one-time commands. A retained .../command can cause a device to repeat an old action after reconnecting.

// state payload
{"state":"open","updated_at":"2026-07-16T10:00:00Z"}

Home Assistant MQTT discovery

HA can create entities from discovery messages. Use it when devices are genuinely dynamic or custom, but document the discovery prefix, unique IDs, and availability topics. For a small fixed integration, an explicit HA configuration can be easier to reason about.

Secure MQTT baseline

[ ] Authentication enabled; one credential per integration where practical
[ ] TLS for untrusted networks/remote paths
[ ] ACLs limit publish/subscribe scope
[ ] Broker not exposed directly to public internet
[ ] Availability/LWT configured for devices
[ ] Secrets stored outside source control

Webhook design

A webhook receiver must assume incoming data is malformed, duplicated, delayed, or malicious until proven otherwise.

Authenticate → validate schema → deduplicate event ID → process → record outcome → respond

Example payload shape

{
  "event_id": "evt_123",
  "event_type": "lead.created",
  "occurred_at": "2026-07-16T10:00:00Z",
  "data": {"source": "website"}
}

Use a stable event_id to make retries idempotent: processing the same event twice should not send two emails or create duplicate leads.

n8n + Home Assistant boundary

Use webhooks for n8n workflows that receive a defined event. Validate a secret/header and restrict the endpoint. Keep physical actions behind HA and give n8n a monitored, approval-gated role unless the automation is low-risk and well-tested.

Debugging checklist

MQTT:
[ ] Broker reachable and authenticated?
[ ] Correct topic spelling/case?
[ ] Publisher actually sending?
[ ] Subscriber has expected wildcard/filter?
[ ] Retained state appropriate?
[ ] JSON valid and schema expected?
[ ] LWT/availability correct?

Webhooks:
[ ] URL and method correct?
[ ] Auth/signature valid?
[ ] Payload valid and complete?
[ ] Event duplicate handled?
[ ] Receiver logs response/error safely?
[ ] Downstream action visible and reversible?

Design rule

Messages are contracts. Document topic/payload shapes and failure behaviour as carefully as you document an API. That is what keeps small automations from becoming an untraceable tangle.