Frigate MQTT integration is how the Frigate NVR tells the rest of your system that it saw a person, a car or a dog, and it is the cleanest way to build alerts and automations on top of local object detection. In this guide you will learn every topic Frigate publishes, what the event payload actually contains, and how to forward only the important detections from your local network to a cloud broker so you can receive them anywhere.
How Frigate Uses MQTT
Frigate runs object detection on your camera streams locally, usually with a Coral, Hailo, OpenVINO or GPU detector. Recording and clip review happen in its web UI, but everything event-driven goes out over MQTT. Frigate is an MQTT client: it connects to a broker you specify, publishes state and events, and subscribes to a handful of command topics so you can switch detection, recording or snapshots on and off remotely.
That design means Frigate does not care who consumes the data. Home Assistant, Node-RED, a Python script or a phone MQTT app can all subscribe to the same topics at once. If you are new to the pub/sub model, it helps to understand what an MQTT broker does before wiring things together.
Configuring the MQTT Section in Frigate
The mqtt block in Frigate's config.yml points it at a broker. Most installations run a local Mosquitto container next to Frigate:
mqtt:
enabled: true
host: mosquitto # container name or IP of the local broker
port: 1883
topic_prefix: frigate # every topic starts with this
client_id: frigate # must be unique on the broker
user: frigate
password: "{FRIGATE_MQTT_PASSWORD}"
stats_interval: 60 # seconds between frigate/stats messages
cameras:
driveway:
mqtt:
enabled: true # publish snapshots for this camera
timestamp: false
bounding_box: true
crop: true
height: 270
quality: 70
Two settings cause most support threads. First, client_id must be unique: if two Frigate instances share the default frigate ID on one broker, they will kick each other off in a loop. Second, if you change topic_prefix, every automation that listens on frigate/... must change too.
Frigate MQTT Topics Reference
These are the topics you will use most often, assuming the default frigate prefix:
| Topic | Payload | Use it for |
|---|---|---|
frigate/available |
online / offline |
NVR health; Frigate sets this as its Last Will |
frigate/events |
JSON with type, before, after |
Tracked object lifecycle: new, update, end |
frigate/reviews |
JSON review item | Grouped alerts and detections (newer versions) |
frigate/<camera>/<object> |
Integer count | How many of that object are in view right now |
frigate/<camera>/<object>/snapshot |
JPEG bytes | Best snapshot of the current object |
frigate/<camera>/motion |
ON / OFF |
Raw motion state |
frigate/<camera>/detect/set |
ON / OFF |
Command: enable or disable detection |
frigate/<camera>/detect/state |
ON / OFF |
Current detection state |
frigate/stats |
JSON | Detector inference speed, CPU, camera FPS |
Similar set/state pairs exist for recordings, snapshots and motion detection. Check the official Frigate MQTT documentation for your version, because newer releases add topics such as review items and tracked object updates.
Reading the frigate/events Payload
Every tracked object produces a sequence of messages on frigate/events: one new, several update messages as the object moves or the score improves, and one end when it leaves. Each message carries the full object state before and after the change. A trimmed example:
{
"type": "new",
"before": { "id": "1729076512.48-ab12cd", "label": "person", "top_score": 0.0 },
"after": {
"id": "1729076512.48-ab12cd",
"camera": "driveway",
"label": "person",
"score": 0.82,
"top_score": 0.84,
"false_positive": false,
"start_time": 1729076512.48,
"end_time": null,
"current_zones": ["front_path"],
"entered_zones": ["front_path"],
"has_snapshot": true,
"has_clip": false
}
}
The fields that matter for alerting:
after.idis stable for the lifetime of the object; use it to deduplicate.after.top_scoreis the best confidence seen so far, which is more reliable than the instantaneousscore.after.false_positivebecomesfalseonce Frigate is confident the object is real. Alerting before that point produces noise.after.entered_zoneslets you alert only when someone actually walks onto the path, not when they pass on the street.type: endwithend_timeset closes the event and is the right moment to fetch the clip through Frigate's HTTP API.
A common mistake is triggering on every update. A person walking across a frame can generate many updates, so a naive automation sends a burst of notifications for one visit.
Why Forward Frigate Events to a Cloud Broker
The local broker is perfect inside the house or site, but it is not reachable from your phone on mobile data without opening ports, and exposing Mosquitto to the internet is a security problem. The safer pattern is outbound only: a small forwarder on the same network subscribes to the local broker, filters events and publishes compact JSON to a cloud MQTT broker. Your phone, a remote dashboard or a second site subscribes there. Nothing listens on your home router.
Forwarding also lets you strip the payload down. Snapshots can be tens of kilobytes and the public test area accepts at most 64 KB per message, so the forwarder sends metadata only and leaves images on the local Frigate server.
You could point Frigate directly at a remote broker by changing host and port and setting client_id to the client ID issued with your credentials, because ConnectMQ binds client IDs to credentials. In practice a filter in between is better: Home Assistant keeps working locally if the internet drops, and only meaningful events leave the network.
Python Forwarder: Local Frigate to ConnectMQ
The script below uses paho-mqtt 2.x. It subscribes to the local broker, forwards one message when a person or car becomes a confident detection and one when it ends, mirrors Frigate's availability, and relays a remote detect on/off command back to Frigate.
pip install "paho-mqtt>=2.0"
import json
import os
import uuid
import paho.mqtt.client as mqtt
LOCAL_HOST = os.getenv("LOCAL_HOST", "localhost")
LOCAL_USER = os.getenv("LOCAL_USER")
LOCAL_PASS = os.getenv("LOCAL_PASS")
REMOTE_HOST = os.getenv("REMOTE_HOST", "broker.connectmq.com")
REMOTE_PORT = int(os.getenv("REMOTE_PORT", "1883"))
REMOTE_USER = os.getenv("REMOTE_USER") # unset for the public test area
REMOTE_PASS = os.getenv("REMOTE_PASS")
REMOTE_CLIENT_ID = os.getenv("REMOTE_CLIENT_ID", f"frigate-fwd-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("REMOTE_PREFIX", f"connectmq/demo/{uuid.uuid4().hex[:8]}/frigate")
LABELS = {"person", "car"}
MIN_SCORE = float(os.getenv("MIN_SCORE", "0.75"))
forwarded = set() # event ids already announced
# ---------- remote (cloud) client ----------
remote = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=REMOTE_CLIENT_ID)
if REMOTE_USER:
remote.username_pw_set(REMOTE_USER, REMOTE_PASS)
if REMOTE_PORT == 8883:
remote.tls_set()
remote.will_set(f"{PREFIX}/forwarder/status", "offline", qos=1, retain=True)
def on_remote_connect(client, userdata, flags, reason_code, properties):
print("remote connected:", reason_code)
client.publish(f"{PREFIX}/forwarder/status", "online", qos=1, retain=True)
client.subscribe(f"{PREFIX}/cmd/+/detect", qos=1)
def on_remote_message(client, userdata, msg):
camera = msg.topic.split("/")[-2]
value = msg.payload.decode().upper()
if value in ("ON", "OFF"):
local.publish(f"frigate/{camera}/detect/set", value)
print(f"relayed detect {value} to {camera}")
remote.on_connect = on_remote_connect
remote.on_message = on_remote_message
# ---------- local (Frigate) client ----------
local = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"frigate-fwd-local-{uuid.uuid4().hex[:6]}")
if LOCAL_USER:
local.username_pw_set(LOCAL_USER, LOCAL_PASS)
def on_local_connect(client, userdata, flags, reason_code, properties):
print("local connected:", reason_code)
client.subscribe([("frigate/events", 0), ("frigate/available", 0)])
def on_local_message(client, userdata, msg):
if msg.topic == "frigate/available":
remote.publish(f"{PREFIX}/nvr/status", msg.payload, qos=1, retain=True)
return
event = json.loads(msg.payload)
after = event["after"]
if after["label"] not in LABELS or after.get("false_positive", True):
return
event_id = after["id"]
if event["type"] in ("new", "update"):
if event_id in forwarded or after["top_score"] < MIN_SCORE:
return
forwarded.add(event_id)
state = "started"
elif event["type"] == "end":
if event_id not in forwarded:
return
forwarded.discard(event_id)
state = "ended"
else:
return
summary = {
"id": event_id,
"camera": after["camera"],
"label": after["label"],
"score": round(after["top_score"], 2),
"zones": after.get("entered_zones", []),
"state": state,
"start": after["start_time"],
"end": after.get("end_time"),
}
topic = f"{PREFIX}/{after['camera']}/{after['label']}/event"
remote.publish(topic, json.dumps(summary), qos=1)
print("forwarded", topic, summary["state"], summary["score"])
local.on_connect = on_local_connect
local.on_message = on_local_message
remote.connect(REMOTE_HOST, REMOTE_PORT, keepalive=60)
remote.loop_start()
local.connect(LOCAL_HOST, 1883, keepalive=60)
print("forwarding to", PREFIX)
local.loop_forever()
Run it on the Frigate host, then watch the remote side from any machine. Use the prefix the script printed:
mosquitto_sub -h broker.connectmq.com -p 1883 -i watcher-7f3a2c \
-t 'connectmq/demo/<your-id>/frigate/#' -v
Walk in front of a camera and you should see exactly two messages per visit: started and ended. To test the command path, publish OFF to connectmq/demo/<your-id>/frigate/cmd/driveway/detect.
The public test area is readable by anyone who guesses the topic, so treat it as a sandbox only. For a real home or site, create a private broker, set REMOTE_PORT=8883 and the REMOTE_USER, REMOTE_PASS and REMOTE_CLIENT_ID values from the portal. Do not run the command relay on a public topic.
Receiving Alerts on Your Phone
Because the cloud broker speaks plain MQTT, anything that can subscribe can alert you: an MQTT client app on your phone, a Node-RED flow that sends a push message through a notification service of your choice, or a remote Home Assistant instance. If you build a browser dashboard, connect over secure WebSocket on port 8084 with the /mqtt path. On the ConnectMQ portal, the live topic explorer shows the forwarded events arriving, which is handy while you tune MIN_SCORE and zones.
Troubleshooting Frigate MQTT
- Frigate logs "Unable to connect to MQTT server". Check that
hostresolves inside the Frigate container;localhostthere is the container itself, not the host machine. - Connection drops every few seconds. Two clients are using the same client ID. Give Frigate and every forwarder a distinct ID.
- No events, but the UI shows detections. The object may not be in the camera's
objects.tracklist, or arequired_zonessetting is filtering it. - Too many alerts. Alert on
top_scoreandentered_zones, ignoreupdateafter the first forward, and add per-camera cooldowns if needed. - Snapshots rejected on the remote broker. They exceed the message size limit; keep images local and send links or metadata.
For deeper detection pipelines, see how YOLO object detection over MQTT works or how to build person detection on an ESP32-CAM, and the AI and IoT guide for the bigger picture.
Get Remote Frigate Alerts with ConnectMQ
A private cloud broker is the missing piece between a local NVR and alerts you can trust away from home. ConnectMQ is a fully managed MQTT service with TLS on port 8883, generated credentials and a topic explorer for debugging. Start on the free Serverless plan at app.connectmq.com, no credit card required, then point the forwarder at your new broker.
Frequently Asked Questions
Does Frigate need an MQTT broker?
MQTT is optional for recording and the web UI, but the Home Assistant integration and all event-driven automations depend on it. Most users run Mosquitto on the same host.
What is the difference between frigate/events and frigate/reviews?
frigate/events describes individual tracked objects through their lifecycle. Review items group activity into alerts and detections that match what you see in the review UI, which is often better for notifications.
Can I send Frigate snapshots to a cloud broker?
Only if they fit the broker's message size limit, which is 64 KB on the public test area. Sending metadata and fetching images from Frigate's API on demand is usually cleaner and cheaper.
Is it safe to expose my local Mosquitto broker instead?
It is not recommended. An outbound forwarder to an authenticated TLS broker avoids opening ports on your router and keeps the local broker private.



