Beacon documentation

Architecture

Beacon turns a self-hosted Frigate NVR into a real family security app. This page explains what the pieces are, how they fit together, and exactly where Beacon plugs into Frigate.

Beacon has two halves that evolve together: a small gateway service (written in Go) that you run next to Frigate, and native apps for iOS and Android. Frigate remains the source of truth for detection, recordings, snapshots, clips, and camera streams - the gateway never duplicates that. Instead it adds the things a thin, backend-less Frigate viewer structurally cannot:

The big picture

Cameras stream to Frigate. Frigate detects objects, records, and announces events over MQTT. The Beacon gateway subscribes to those events, decides who should be notified, and sends push. The apps talk only to the gateway - for sign-in, event history, snapshots, clips, and to set up live view.

Beacon architecture diagram Cameras send RTSP to a self-hosted Frigate instance, which runs object detection, go2rtc for restreaming and WebRTC, an MQTT broker, and stores recordings and snapshots. The Beacon gateway reads Frigate's MQTT events and HTTP API and is the only public surface the apps talk to. The gateway sends push through APNs and FCM, optionally via a hosted relay. Live video flows peer-to-peer between the phone and go2rtc, bypassing the gateway. push (APNs / FCM) control & API (HTTPS) live video · peer-to-peer Cameras RTSP feeds H.265 · H.264 Frigate self-hosted NVR Object detection Coral TPU go2rtc restream · WebRTC MQTT broker frigate/events Recordings · media snapshots · clips · API source of truth Beacon Gateway Go · the only public surface Auth - Apple / Google, JWT MQTT → APNs / FCM push Media proxy (HTTP Range) WebRTC (WHEP) signaling Users · roles · invites SQLite - users · events HLS fallback proxy Beacon Relay optional · hosted APNs · FCM push providers Family phones iOS · Android never touch Frigate RTSP events HTTP API HTTPS API push deliver live video · peer-to-peer (WebRTC) - bypasses the gateway

Everything left of the phones is self-hosted on your own network. The gateway is the only piece exposed to the internet - and it does its own authentication.

Private by architecture, not policy

Privacy is the reason Beacon is shaped the way it is. Three properties make it structural, not a promise you have to take on faith:

Your footage never leaves your hardware

Frigate records and stores everything on the host you run at home. Beacon never copies your video to Tarazel; the gateway only proxies a snapshot or clip on demand, straight from your Frigate to your own devices. There is no cloud that holds your recordings, and no subscription that can take them away.

The gateway is open source

The service that handles your accounts, camera access, and Frigate credentials is open source. You can read the exact code that touches your data, audit it, or run the whole thing yourself for free. Trust here is something you can verify, not something you have to be told.

Even the paid relay stays blind

Your gateway keeps all user data, camera scope, and mute logic, and holds the only credentials that reach Frigate. When it delivers push through the hosted relay, it forwards only a list of device tokens and an opaque wake-up; the relay stores no users, tokens, or events, and never sees a camera name, label, or image. Your device then fetches the readable notification (title, body, snapshot) from your own gateway, so you get convenient managed push without the relay ever seeing inside your home.

The components

Cameras

Your IP cameras, connected to Frigate over RTSP. Beacon follows one hard rule: the high-resolution H.265 main stream is for recording only; everything a person watches uses the lower-bandwidth H.264 substream.

Frigate

The self-hosted NVR that does the heavy lifting: object detection (typically with a Coral TPU), recordings, snapshots and clips, an HTTP API, an MQTT event bus, and go2rtc for restreaming and WebRTC. Beacon treats Frigate as the source of truth and never copies its data.

Beacon gateway

A small Go service you run next to Frigate - the only surface the apps talk to. It authenticates users, turns MQTT events into push, proxies snapshots and clips, brokers WebRTC signaling, and stores users, roles, per-camera scope, and event metadata in a single SQLite file.

Push: the hosted relay

Notifications go out through a hosted relay that holds the Apple/Google push keys, so you don't need a developer account of your own. Your gateway always decides who to notify; the relay only signs and delivers. (Self-signing with your own key is an advanced option.)

The apps

Native iOS and Android clients: event history with snapshots, live view, clip playback, and per-user alert rules. The gateway URL is configurable, so one build points at any Beacon instance. The app never talks to Frigate directly.

How data flows

1. Event → notification

When Frigate starts tracking an object it publishes to the frigate/events MQTT topic. The gateway is subscribed. On the first (new) phase it records the event, applies the recipient's alert rules, per-camera scope, and mute settings, then sends a push to each eligible device via the relay. On the device, a notification-service extension enriches the banner with the camera name and snapshot, fetched from your gateway.

2. Live view

The app asks the gateway for a live descriptor and posts a WebRTC offer to POST /api/cameras/{id}/webrtc. The gateway relays the SDP exchange to go2rtc (WHEP) and hands back the answer. From then on the video flows directly between the phone and go2rtc - the gateway is only in the signaling path, never the media path. When WebRTC can't traverse the network (it needs UDP), the app falls back to HLS, which the gateway proxies over ordinary HTTPS.

3. Snapshots & clips

Thumbnails, event snapshots, and clip playback are proxied by the gateway from Frigate, with HTTP Range support so video seeks and streams properly. This keeps Frigate private (only the gateway reaches it) and lets the gateway enforce per-user camera access on every request.

How Beacon fits with Frigate

The gateway integrates with Frigate over three well-defined surfaces. Nothing about your Frigate config has to change for Beacon beyond what a standard Frigate stack already exposes (MQTT + go2rtc).

MQTT - the event bus

Frigate announces every tracked object on frigate/events. Each message has a type of new, update, or end, and carries before/after state including the camera, label, score, zones, and snapshot info. The gateway records each phase and pushes only on new, so you get one alert per event, not one per frame.

go2rtc - live view & WebRTC

Frigate bundles go2rtc, which restreams your cameras and speaks WebRTC. Beacon brokers a WHEP SDP exchange against go2rtc so the phone can pull a low-latency, peer-to-peer live stream. The gateway talks to go2rtc's API directly on port 1984 - this bypasses the nginx in front of Frigate on :5000, which blocks the WHEP POST.

HTTP API - snapshots & clips

The gateway calls Frigate's HTTP API to fetch the latest detect-frame JPEG for dashboard tiles and to stream event snapshots and clips. If your Frigate sits behind Cloudflare Access, the gateway can attach a service-token header to every request; if it's on the same private network, no extra auth is needed.

The H.264 / H.265 rule

All user-facing playback uses the H.264 substream. H.265 stays in storage only.

H.265 (HEVC) doesn't decode reliably in browsers, so live view and anything browser-reachable must be H.264. In your camera entries, the stream name must point at the H.264 substream, not the H.265 main stream. (Clip playback can serve Frigate's H.265 recording, because native mobile players handle HEVC - but live view cannot.)