HTTP API
The daemon’s web UI is a client of a plain HTTP API — anything the UI does, your own tooling can do too. This page covers the stable, integration-friendly endpoints.
The API is stable in practice but not formally versioned yet. Pin automations to a daemon version and check the changelog on upgrades.
Auth#
With auth enabled, request a session by POSTing credentials, then send the session cookie with subsequent calls:
curl -c cookies.txt -H 'Content-Type: application/json'
--data '{"username":"admin","password":"..."}'
http://localhost:8085/api/login
curl -b cookies.txt http://localhost:8085/api/cameras With auth off (LAN trust), no credentials are needed. Over remote access, a signed ?grant= token takes the cookie’s place.
Reading state#
| Endpoint | What you get |
|---|---|
GET /api/cameras | Every configured camera: id, name, streams, record flag, live state |
GET /api/stats | Per-stream ingest metrics — bitrate, RTP loss, decode errors, frame age |
GET /api/events/{cam}?from=&to=&type= | Indexed events (motion, linecrossing, intrusion, tamper, videoloss, camera_offline) |
GET /api/recordings/{cam}/{stream} | Recorded-coverage metadata for a camera + stream |
GET /api/thumbnails/{cam}/{stream}?from=&to= | Scrub-preview thumbnail index for a window |
GET /api/version | Daemon version and build identity |
GET /api/health | Loopback health summary (drives the macOS menu-bar item) |
All times are epoch milliseconds unless noted. Responses are JSON.
Images and clips#
| Endpoint | What you get |
|---|---|
GET /api/snapshot/{cam}/latest.jpg | The most recent camera still — what the Wall tab polls |
GET /api/snapshot/{cam}?at={ms} | A still nearest a historical moment (from recorded footage) |
Media streams#
These are the endpoints the players use. They’re long-lived, so give them generous timeouts.
| Endpoint | What you get |
|---|---|
GET /mse/{cam}/{stream} | WebSocket carrying live fMP4 — keyframe-anchored prefix, then the live edge |
GET /hls/{cam}/{stream}/index.m3u8 | Live HLS (the iOS/Safari path) |
GET /hls/{cam}/{stream}/vod.m3u8?from=&to= | Recorded playback as HLS VOD over a time window |
GET /audio/{cam}/{stream} | A stream’s audio track, when audio: true is set |
A minimal integration#
Poll stats and alert when a camera’s frame age stalls — the whole thing is a few lines:
curl -fsS -b cookies.txt http://localhost:8085/api/stats
| jq '.streams[] | select(.last_frame_age_ms > 10000)' For heavier lifting — config changes, camera management, admin actions — use the web app’s Settings rather than scripting the admin endpoints; those are covered by the config editor’s validation and history.