BirdLense Hub — HTTP API
Version: the release semver in repository root VERSION (mirrored in app/web/openapi.yaml).
Authoritative contract: OpenAPI YAML (import into Redoc, Stoplight, or IDE).
Interactive (browser): OpenAPI (Redoc).
UI API (/api/ui/*)
All paths in this table are prefixed with /api/ui (e.g. /health → GET /api/ui/health).
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Liveness |
/status |
GET | Component status: web, processor, mqtt, esphome, yolo — ok | error | not_configured | not_used | unknown |
/cameras |
GET | Camera list |
/weather |
GET | Weather snapshot |
/timeline |
GET | Visits in range (start_time, end_time) |
/timeline/export |
GET | CSV, JSON, or eBird (format=csv|json|ebird) |
/videos/:id |
GET | Video detail |
/videos/:id/neighbors |
GET | Previous/next video IDs. Supports local day and cross-day fallback via day_scope, tz_offset_minutes, cross_day; response includes day_scope, day_label, timezone_offset_minutes |
/overview |
GET | Overview dashboard payload |
/species |
GET | Species list |
/birdfood |
GET/POST | Food list / add |
/birdfood/:id/toggle |
PATCH | Toggle food entry |
/bird_families |
GET | Bird family list |
/feed/dispense |
POST | Trigger feeder (Admin session or MCP Bearer — see ACCESS_CONTROL) |
/settings |
GET/PATCH | Read/update settings |
/settings/requires-password |
GET | Whether a password is configured |
/settings/verify-password |
POST | Unlock session (password → role: admin | contributor). 401 if wrong password; 429 + Retry-After after 5 failed attempts / 60s per IP — see ACCESS_CONTROL |
/settings/check-access |
GET | Session unlock state: { unlocked, role? } — always 200 (locked → unlocked: false; no red 403 in browser for probes) |
/unknowns |
GET | Low-confidence detections (start_time, end_time, limit) |
/region-comparison |
GET | Your species vs regional eBird (needs secrets.ebird_api_key) |
/detections/:id |
PATCH | Correct species (species_id) — Contributor+ |
/detections/:id/crop |
GET | JPEG crop for iNaturalist |
/dataset/export |
GET | Dataset ZIP — Contributor+ |
/push/vapid-public |
GET | Web Push VAPID public key |
/push/subscribe |
POST | Register push subscription |
/report/pdf |
GET | Monthly PDF (month=YYYY-MM or time range) |
/migration-calendar |
GET | Visits aggregated by species × month. Query: catalog=active|full, evidence=all|video, plus optional year/date filters |
/species/:id/xeno-canto |
GET | Xeno-canto clips for species |
/species/:id/summary |
GET | Species summary |
/restart-processor |
POST | Restart processor (Admin) |
Prometheus
| Endpoint | Method | Description |
|---|---|---|
/metrics |
GET | Prometheus text format |
/api/metrics |
GET | Same (Grafana-friendly path) |
Scrape config: CONFIGURATION → Prometheus / Grafana.
System & storage (/api/ui/...)
| Path | Method | Description |
|---|---|---|
/api/ui/system/metrics |
GET | Live snapshot: CPU, RAM, disk, GPU (encoding hints when GPU chart applies) |
/api/ui/system/metrics/history |
GET | Downsampled time series for System charts (?hours=, ?max_points=) |
/api/ui/system/visitors |
GET | Unique visitor sessions over ?days= (SpeciesVisit aggregate) |
/api/ui/system/activity |
GET | Activity by day |
/api/ui/storage/stats |
GET | Recording storage stats |
/api/ui/storage/purge |
POST | Purge by date (Admin) |
/api/ui/system/retention |
POST | Run retention policy |
/api/ui/system/regenerate-spectrograms |
POST | Regenerate spectrograms |
/api/ui/system/regenerate-spectrograms/status |
GET | Job status |
/api/ui/system/regenerate-tracks |
POST | Regenerate tracks |
/api/ui/system/regenerate-tracks/status |
GET | Job status |
/api/ui/system/recordings/scan |
POST | Scan & import recordings |
/api/ui/system/logs |
GET | Processor log tail (?lines=100) |
More maintenance endpoints exist — see ui_system_routes.py and OpenAPI.
Processor API (/api/processor/*)
Internal contract between processor and web. When PROCESSOR_SECRET is set, send header X-Processor-Token: <secret>.
| Endpoint | Method | Description |
|---|---|---|
/videos |
POST | Upsert recording + detections |
/species/active |
PUT | Active species snapshot |
/notify/detections |
POST | Detection notification (e.g. Telegram pipeline) |
/notify/motion |
POST | Motion notification |
/activity_log |
POST | Heartbeat / processor status |
Authentication summary
| Surface | Behavior |
|---|---|
| Default | No login; all UI routes open if no passwords configured |
| Settings / feeder / system | Optional settings_password; Admin unlock via verify-password |
| Contributor | Optional contributor_password — labeling & exports without full admin |
| MCP | Optional MCP_TOKEN — Authorization: Bearer <token> |
| Processor | Optional PROCESSOR_SECRET — X-Processor-Token |
Details: ACCESS_CONTROL · CONFIGURATION.
UI routing note (operator-facing)
- Legacy route
/unknownsis kept for bookmarks and redirects to/timeline?review=1. - Review mode uses the same unknown-detection API (
GET /api/ui/unknowns), while normal Timeline mode usesGET /api/ui/timeline.
See also
CONFIGURATION · ARCHITECTURE · ACCESS_CONTROL · FEATURES · GLOSSARY