Events & alarms
The event feed, snapshots and clips, acknowledgement, and how alarms turn into notifications.
What is an event
An event is a single confirmed detection — for example "person at 14:32:05 on camera 3, confidence 0.87". Events store:
- The label (
person,car,face:alice,plate:AB12CDE, …) - The confidence score
- A snapshot JPEG of the frame that triggered it
- (Optionally) a short video clip
- The start and end time
- Whether it has been acknowledged
- Whether it was suppressed by a schedule
Every event is written to MariaDB and served from /api/events.
Depending on the event type, Vistralio may also store:
- an object crop/snippet
- a plate crop for ALPR
- zone metadata
- inferred scene details derived from the crop
Doorbells can also create a doorbell_press event. When that event arrives,
the Web UI can raise a browser notification and jump straight into the live
doorbell view.
Viewing events
Open Events in the sidebar. You'll see:
- A reverse-chronological list, newest first
- Filters at the top for camera, label, acknowledged state, and time window
- The default view is unacknowledged only
- Hover-to-play cards when an event clip exists
- Quick acknowledgement without leaving the page
- Human-readable scene summaries where available, such as clothing colour, likely hi-vis / hard-hat cues, vehicle colour, or animal colour
The dashboard's Unacknowledged Events widget shows the same data as a compact grid with hover-to-play. It only shows unacknowledged events.
The per-camera Events view uses the same event data but adds playback, snippets, and richer detail panels for the selected event.
Acknowledging an alarm
Click Acknowledge on the event card (or call POST /api/events/{id}/ack).
Acknowledged events drop out of the Active alarms dashboard widget but
remain in the history forever (until retention deletes the underlying clip).
Suppression
If a schedule was active when the event fired, it will be
recorded with suppressed_by_schedule=true and the notifier will skip
publishing it. You'll still see it in the history view, with a faint badge.
This is intentional — you want a complete record of detections even when you don't want to be paged about them.
How alarms become notifications
When the worker creates an event, it calls notifier.publish_event(). That
function:
- Checks active schedules → drop if suppressed
- Publishes to MQTT topic
sentinel/events/<camera_id>/<label> - Publishes to Home Assistant discovery topics
- (If the action attached to a known face/plate says so) sends an email via the SMTP service
Doorbell presses also flow through the normal event pipeline, so they appear in the event feed, dashboard widgets, MQTT topics, and browser notifications just like any other event.
See Notifications & SMTP for the channel details.
Event clips
When a detection event ends, the worker automatically builds a short MP4 clip by concatenating recording segments that cover the event's time window. The clip includes a configurable pre-roll and post-roll window (default: 10 seconds each, adjustable via settings events.clip_pre_roll_seconds and events.clip_post_roll_seconds).
Clip availability: Clips are built immediately after an event finalises. If the clip cannot be built at that time (e.g. the current recording segment is still being written), a background retry runs every hour as part of the retention sweep to catch any events that are missing clips.
Clips appear as hover-to-play cards in the Events page and in the camera Events view.
Segment health: Vistralio validates recording segments before including them in a clip. Segments smaller than 64 KB or that cannot be probed by ffprobe (e.g. missing moov atom from an interrupted recording) are automatically skipped. This prevents clip build failures caused by interrupted recording workers.
Permissions
| Action | Permission |
|---|---|
| See the event feed | events.view |
| Acknowledge an event | events.acknowledge |
| Delete an event | events.delete |
Related API endpoints
GET /api/events?camera_id=&label=&acknowledged=&since_minutes=&limit=— filtered feedPOST /api/events/{id}/ackGET /api/recordings/snapshot/{event_id}— JPEGGET /api/recordings/clip/{event_id}— MP4