Backend for the first-run wizard (phase 4).
- POST /api/v1/setup/scaffold: given an existing device_id + display_index
(+ optional calibration), wires a working chain via the real validated
store create paths — create-or-reuse capture template -> raw picture
source -> picture color-strip source (calibration or default) -> LED
output target -> returns the ids. Does NOT auto-start. Rolls back every
entity it created (reverse order) on any partial failure, leaving no
orphans; "created" events are deferred until the whole chain succeeds so
a rolled-back scaffold never leaves ghost cards in the UI.
- Requires an existing device_id (no inline device creation) — the wizard
creates the device first via the canonical, URL-validated POST /devices,
so the scaffold can't bypass device validation. display_index is bounded.
- GET/PUT /api/v1/preferences/onboarding: persistent first-run flag
({onboarded, completed_at}) via db.set_setting; server stamps completed_at.
- Both routes AuthRequired. Tests: 25 (scaffold happy/reuse/rollback/
validation + onboarding + calibration round-trip integration). docs/API.md.
Part of the edge-calibration + first-run-wizard feature (Big Bang; intermediate
phase — full build/suite gated at the final phase).
42 KiB
LedGrab API Reference
Complete REST + WebSocket API reference for the LedGrab server.
- Base URL:
http://localhost:8080 - API version:
v1(all REST paths are under/api/v1, except/health) - Interactive docs: Swagger UI at
/docs, ReDoc at/redoc, raw schema at/openapi.json. The interactive docs are always the authoritative, up-to-date source for request/response schemas — this file is a hand-maintained overview.
The application version is reported by
GET /api/v1/version; this document is version-agnostic.
Table of Contents
- Authentication
- Conventions
- WebSocket protocol
- Worked examples
- Endpoint reference
- Health & system info
- System settings
- User preferences
- Backup, restore & server control
- Updates
- Snapshot
- Devices
- Capture templates, engines & filters
- Picture sources
- Post-processing templates
- Output targets
- Output target control & live preview
- Color strip sources
- Color strip processing templates
- Pattern templates
- Gradients
- Audio devices
- Audio sources
- Audio templates & engines
- Audio processing templates
- Audio filters
- Value sources
- Weather sources
- Automations
- Scene presets
- Scene playlists
- Sync clocks
- Webhooks
- HTTP endpoints
- Game integration
- Home Assistant
- MQTT sources
- Assets
- Graph wiring
- Web UI & PWA
Authentication
LedGrab uses API-key authentication. The behavior depends on whether any keys are configured under auth.api_keys (see INSTALLATION.md):
| Situation | Loopback (127.0.0.1 / ::1 / localhost) |
LAN / remote |
|---|---|---|
| No keys configured (default) | Allowed anonymously | Rejected with 401 |
| Keys configured | Valid Bearer token required | Valid Bearer token required |
Pass the key as a Bearer token:
Authorization: Bearer <your-api-key>
A few sensitive endpoints require a real API key even from localhost (they reject the loopback-anonymous identity): the backup download/restore endpoints, and any endpoint that reveals stored secrets (e.g. GET /api/v1/home-assistant/sources?include_secrets=true). Configure a key to use those.
WebSocket endpoints authenticate with a first-message handshake rather than the Authorization header.
Conventions
- Content type: request and response bodies are JSON (
application/json) unless noted (file uploads usemultipart/form-data; some endpoints stream binary or file responses). - Errors: failures return the standard FastAPI shape with an HTTP status code and a body of
{"detail": "<message>"}. Validation errors return422with a structureddetailarray. - IDs: entities are addressed by string IDs (e.g.
dev_…,ot_…,css_…) generated on creation. - Common create/update fields: most configurable entities accept
name,description,tags(string array), and UI styling fieldsiconandicon_color. - Referential integrity: deleting an entity that is still referenced (e.g. a device used by an output target) returns
409 Conflict. - Timestamps: ISO-8601 UTC strings.
WebSocket protocol
All WebSocket endpoints share the same auth handshake:
- The client connects. The server accepts the socket.
- The client sends a JSON auth message as the first message, within ~3 seconds:
{"type": "auth", "token": "<your-api-key>"}. On loopback with no keys configured,tokenmay benullor the message omitted. - The server replies
{"type": "auth_ok"}on success, or{"type": "auth_error", "reason": "..."}then closes (close code4401) on failure. A cross-siteOriginis rejected with close code4403.
Browser clients must connect from an allowed cors_origins origin. After auth_ok, the stream payload depends on the endpoint (JSON event objects, JSON spectrum/metric frames, or binary RGB frames — see each endpoint's description).
The WebSocket endpoints are listed within their resource sections below (method WS).
Worked examples
Example values are illustrative.
Health check — GET /health (no auth on loopback):
{
"status": "healthy",
"timestamp": "2026-05-29T12:00:00Z",
"version": "0.8.1",
"demo_mode": false,
"auth_required": false,
"setup_required": false,
"uptime_seconds": 3600
}
Create a WLED device — POST /api/v1/devices:
{
"name": "Living Room TV",
"url": "http://192.168.1.100",
"device_type": "wled",
"led_count": 150
}
Response 201 Created returns the stored device, including its generated id. (For Adalight, send device_type: "adalight", the serial url like COM3 or /dev/ttyUSB0, led_count, and baud_rate. Each device type accepts its own fields — see /docs.)
Start / stop a target — POST /api/v1/output-targets/{target_id}/start:
{ "status": "started", "target_id": "ot_abc123" }
Authenticated request with a configured key:
curl -H "Authorization: Bearer your-api-key" \
http://localhost:8080/api/v1/devices
Endpoint reference
Health & system info
Health checks, version information, displays, system metrics, and integration status.
| Method | Path | Description |
|---|---|---|
| GET | /health |
Service health: status, version, uptime, and whether auth/setup is required. |
| GET | /api/v1/version |
Application version, Python version, and API version. |
| GET | /api/v1/tags |
All tags used across every entity in the system. |
| GET | /api/v1/config/displays |
Available displays/monitors for screen capture (optional engine_type query, e.g. scrcpy). |
| GET | /api/v1/system/processes |
Running process names, for use in automation conditions. |
| GET | /api/v1/system/performance |
Current CPU, RAM, and GPU utilization metrics. |
| GET | /api/v1/system/metrics-history |
Last ~2 minutes of system and per-target metrics for dashboard charts. |
| GET | /api/v1/system/api-keys |
API-key labels with masked values (read-only; keys live in YAML config). |
| GET | /api/v1/system/integrations-status |
Connection status for MQTT and Home Assistant integrations. |
System settings
Server configuration: MQTT broker, external URL, shutdown action, log level, ADB connection, and live log streaming.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/system/mqtt/settings |
Current MQTT broker settings (password masked). |
| PUT | /api/v1/system/mqtt/settings |
Update MQTT broker settings (empty password preserves existing). |
| GET | /api/v1/system/external-url |
Configured external base URL. |
| PUT | /api/v1/system/external-url |
Set the external base URL for webhooks and user-visible links. |
| GET | /api/v1/system/shutdown-action |
Configured server shutdown action (stop_targets or nothing). |
| PUT | /api/v1/system/shutdown-action |
Set what happens to targets when the server shuts down. |
| WS | /api/v1/system/logs/ws |
Live server log stream with a buffered backlog. |
| POST | /api/v1/adb/connect |
Connect to a Wi-Fi ADB device by IP (auto-appends :5555). |
| POST | /api/v1/adb/disconnect |
Disconnect a Wi-Fi ADB device. |
| GET | /api/v1/system/log-level |
Current root logger level. |
| PUT | /api/v1/system/log-level |
Change the log level at runtime without restart. |
User preferences
Dashboard layout, notification settings, card display modes, the global daylight timezone, and the first-run onboarding flag.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/preferences/dashboard-layout |
Read the saved dashboard layout (empty when unset). |
| PUT | /api/v1/preferences/dashboard-layout |
Save the dashboard layout (opaque versioned JSON blob). |
| DELETE | /api/v1/preferences/dashboard-layout |
Delete the saved layout; revert to default. |
| GET | /api/v1/preferences/notifications |
Read notification preferences (server defaults when unset). |
| PUT | /api/v1/preferences/notifications |
Persist notification preferences (channels, discovery, grace/debounce). |
| GET | /api/v1/preferences/card-modes |
Read per-surface card-mode preferences. |
| PUT | /api/v1/preferences/card-modes |
Save per-surface card modes (comfortable/compact/dense/row). |
| DELETE | /api/v1/preferences/card-modes |
Delete card-mode preferences; revert to defaults. |
| GET | /api/v1/preferences/daylight-timezone |
Read the global IANA timezone for daylight cycles. |
| PUT | /api/v1/preferences/daylight-timezone |
Persist the daylight-cycle timezone (empty = server local). |
| GET | /api/v1/preferences/onboarding |
Read the first-run onboarding flag (onboarded: bool, completed_at: str|null). Defaults to false. |
| PUT | /api/v1/preferences/onboarding |
Persist the onboarding flag. Server auto-stamps completed_at when onboarded is set to true without a timestamp. |
Onboarding flag response shape:
{
"onboarded": true,
"completed_at": "2026-06-08T12:00:00.000000+00:00"
}
Defaults to {"onboarded": false, "completed_at": null} when never set.
Backup, restore & server control
Database backup/restore, server restart/shutdown, and auto-backup management.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/system/backup |
Download a full backup .zip (database + assets). 🔒 requires a key. |
| POST | /api/v1/system/restore |
Upload a .db/.zip backup to restore config and trigger a restart. 🔒 requires a key. |
| POST | /api/v1/system/restart |
Schedule a server restart and return immediately. |
| POST | /api/v1/system/shutdown |
Gracefully shut down the server. |
| GET | /api/v1/system/auto-backup/settings |
Auto-backup settings and status (enabled, interval, retention, last/next). |
| PUT | /api/v1/system/auto-backup/settings |
Update auto-backup settings. |
| POST | /api/v1/system/auto-backup/trigger |
Trigger a backup now and return its metadata. |
| GET | /api/v1/system/backups |
List saved auto-backup files. |
| GET | /api/v1/system/backups/{filename} |
Download a specific saved backup file. |
| DELETE | /api/v1/system/backups/{filename} |
Delete a specific saved backup file. |
🔒 = requires a real API key even from localhost (rejects loopback-anonymous access).
Updates
Auto-update management: check, apply, dismiss, and configure.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/system/update/status |
Current update status (available version, install type, capability). |
| POST | /api/v1/system/update/check |
Trigger an immediate update check. |
| POST | /api/v1/system/update/dismiss |
Dismiss the notification for a specific version. |
| POST | /api/v1/system/update/apply |
Download and apply the available update, then shut down. |
| GET | /api/v1/system/update/settings |
Update settings (enabled, interval, include prereleases). |
| PUT | /api/v1/system/update/settings |
Change auto-update settings. |
Snapshot
A single aggregated poll endpoint for low-overhead clients.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/snapshot |
Full poll payload (targets, states, metrics, devices, brightness, color/value sources, scene presets, scene playlists + cycling state, sync clocks, system) in one response. Use ?include= to request a subset; per-section fault isolation. |
Devices
LED device CRUD, pairing, discovery, health checks, brightness/power control, and the WS pixel stream.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/devices |
Create/attach a new LED device (validates connectivity). |
| POST | /api/v1/devices/pair |
Run a pairing handshake before creating a device. |
| GET | /api/v1/devices |
List all attached devices. |
| GET | /api/v1/devices/discover |
Scan the network for devices (optional timeout, device_type). |
| GET | /api/v1/devices/openrgb-zones |
List zones on an OpenRGB device (url query). |
| GET | /api/v1/devices/batch/states |
Health/connection state for all devices at once. |
| GET | /api/v1/devices/{device_id} |
Get a device by ID. |
| PUT | /api/v1/devices/{device_id} |
Update device configuration. |
| DELETE | /api/v1/devices/{device_id} |
Delete/detach a device (409 if referenced). |
| GET | /api/v1/devices/{device_id}/state |
Get device health/connection state. |
| POST | /api/v1/devices/{device_id}/ping |
Force an immediate health check. |
| GET | /api/v1/devices/{device_id}/brightness |
Get current (cached) brightness. |
| PUT | /api/v1/devices/{device_id}/brightness |
Set brightness (0–255). |
| GET | /api/v1/devices/{device_id}/power |
Get current power state. |
| PUT | /api/v1/devices/{device_id}/power |
Turn the device on or off. |
| WS | /api/v1/devices/{device_id}/ws |
Pixel stream for ws device type ([brightness][R G B …]). |
Capture templates, engines & filters
Capture template CRUD/testing, capture engine discovery, and post-processing filter discovery.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/capture-templates |
List all capture templates. |
| POST | /api/v1/capture-templates |
Create a capture template. |
| GET | /api/v1/capture-templates/{template_id} |
Get a capture template by ID. |
| PUT | /api/v1/capture-templates/{template_id} |
Update a capture template (partial). |
| DELETE | /api/v1/capture-templates/{template_id} |
Delete a template (409 if used by streams). |
| GET | /api/v1/capture-engines |
List capture engines with platform availability. |
| POST | /api/v1/capture-templates/test |
Test a capture config; returns FPS metrics + preview. |
| WS | /api/v1/capture-templates/test/ws |
Real-time capture test with intermediate frame previews. |
| GET | /api/v1/filters |
List post-processing filter types and option schemas. |
| GET | /api/v1/strip-filters |
List filter types that support 1D LED-strip processing. |
Picture sources
Screen captures, static images, video files, and processed streams used for color extraction.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/picture-sources |
List all picture sources. |
| POST | /api/v1/picture-sources/validate-image |
Validate an image source and return a preview thumbnail. |
| GET | /api/v1/picture-sources/full-image |
Serve a full-resolution image for lightbox preview (source query). |
| POST | /api/v1/picture-sources |
Create a picture source (raw/processed/static/video). |
| GET | /api/v1/picture-sources/{stream_id} |
Get a picture source by ID. |
| PUT | /api/v1/picture-sources/{stream_id} |
Update a picture source. |
| DELETE | /api/v1/picture-sources/{stream_id} |
Delete a picture source (409 if referenced). |
| GET | /api/v1/picture-sources/{stream_id}/thumbnail |
Thumbnail (first frame) for a video source. |
| POST | /api/v1/picture-sources/{stream_id}/test |
Resolve the chain and run a capture test. |
| WS | /api/v1/picture-sources/{stream_id}/test/ws |
Test stream with intermediate frame previews. |
Post-processing templates
Reusable filter chains applied to picture sources.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/postprocessing-templates |
List all post-processing templates. |
| POST | /api/v1/postprocessing-templates |
Create a template (name + filter list). |
| GET | /api/v1/postprocessing-templates/{template_id} |
Get a template by ID. |
| PUT | /api/v1/postprocessing-templates/{template_id} |
Update a template (partial). |
| DELETE | /api/v1/postprocessing-templates/{template_id} |
Delete a template (409 if referenced). |
| POST | /api/v1/postprocessing-templates/{template_id}/test |
Capture from a source and apply the filters. |
| WS | /api/v1/postprocessing-templates/{template_id}/test/ws |
Real-time test with intermediate frame previews. |
Output targets
LED strips, Home Assistant light groups, and Zigbee2MQTT bulb groups.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/output-targets |
Create a target (led / ha_light / z2m_light). |
| GET | /api/v1/output-targets |
List all output targets. |
| GET | /api/v1/output-targets/batch/states |
Processing state for all targets at once. |
| GET | /api/v1/output-targets/batch/metrics |
Metrics for all targets at once. |
| GET | /api/v1/output-targets/{target_id} |
Get a single target. |
| PUT | /api/v1/output-targets/{target_id} |
Update a target (partial, per type). |
| DELETE | /api/v1/output-targets/{target_id} |
Delete a target (stops processing first). |
Output target control & live preview
Start/stop processing, state & metrics, the calibration overlay, the global event stream, and live color/LED preview WebSockets.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/output-targets/bulk/start |
Start processing for multiple targets. |
| POST | /api/v1/output-targets/bulk/stop |
Stop processing for multiple targets. |
| POST | /api/v1/output-targets/{target_id}/start |
Start processing for one target. |
| POST | /api/v1/output-targets/{target_id}/stop |
Stop processing for one target. |
| GET | /api/v1/output-targets/{target_id}/state |
Current processing state (FPS, timing, device, errors). |
| GET | /api/v1/output-targets/{target_id}/metrics |
Processing metrics (uptime, frames, error count). |
| WS | /api/v1/events/ws |
Real-time state-change events across all targets. |
| POST | /api/v1/output-targets/{target_id}/overlay/start |
Start the on-screen sampling/LED overlay. |
| POST | /api/v1/output-targets/{target_id}/overlay/stop |
Stop the overlay. |
| GET | /api/v1/output-targets/{target_id}/overlay/status |
Whether the overlay is active. |
| POST | /api/v1/output-targets/{target_id}/ha-light/turn-off |
Turn off all HA light entities for the target. |
| WS | /api/v1/output-targets/{target_id}/ha-light/ws |
Live HA light color preview. |
| POST | /api/v1/output-targets/{target_id}/z2m-light/turn-off |
Publish OFF to all Zigbee2MQTT bulbs for the target. |
| WS | /api/v1/output-targets/{target_id}/z2m-light/ws |
Live Zigbee2MQTT bulb color preview. |
| WS | /api/v1/output-targets/{target_id}/led-preview/ws |
Live LED-strip preview (binary RGB frames). |
Color strip sources
CRUD, calibration, raw color push, notifications, and preview streaming for color strip sources.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/color-strip-sources |
List all color strip sources. |
| POST | /api/v1/color-strip-sources |
Create a color strip source (by source_type). |
| GET | /api/v1/color-strip-sources/{source_id} |
Get a color strip source by ID. |
| PUT | /api/v1/color-strip-sources/{source_id} |
Update a source; hot-reloads running streams. |
| DELETE | /api/v1/color-strip-sources/{source_id} |
Delete a source (409 if referenced). |
| POST | /api/v1/color-strip-sources/{source_id}/overlay/start |
Start the screen overlay (picture-type, calibrated). |
| POST | /api/v1/color-strip-sources/{source_id}/overlay/stop |
Stop the screen overlay. |
| GET | /api/v1/color-strip-sources/{source_id}/overlay/status |
Whether the overlay is active. |
| POST | /api/v1/color-strip-sources/{source_id}/colors |
Push raw LED colors to an api_input source. |
| POST | /api/v1/color-strip-sources/{source_id}/notify |
Trigger a one-shot notification effect. |
| GET | /api/v1/color-strip-sources/os-notifications/history |
Recent OS-notification capture history. |
| PUT | /api/v1/color-strip-sources/{source_id}/calibration/test |
Light up LED edges to verify calibration. |
| POST | /api/v1/color-strip-sources/{source_id}/key-colors/test |
Test a key_colors source (extract colors from rectangles). |
| WS | /api/v1/color-strip-sources/{source_id}/key-colors/test/ws |
Real-time key-colors test preview. |
| WS | /api/v1/color-strip-sources/preview/ws |
Transient ad-hoc source preview stream. |
| WS | /api/v1/color-strip-sources/{source_id}/ws |
Push raw colors to an api_input source over WS. |
| WS | /api/v1/color-strip-sources/{source_id}/test/ws |
Real-time source preview (binary RGB, optional JPEG). |
Color strip processing templates
Reusable filter chains applied to color strips (1D LED data).
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/color-strip-processing-templates |
List all color-strip processing templates. |
| POST | /api/v1/color-strip-processing-templates |
Create a template (name + filter list). |
| GET | /api/v1/color-strip-processing-templates/{template_id} |
Get a template by ID. |
| PUT | /api/v1/color-strip-processing-templates/{template_id} |
Update a template. |
| DELETE | /api/v1/color-strip-processing-templates/{template_id} |
Delete a template (409 if referenced). |
| WS | /api/v1/color-strip-processing-templates/{template_id}/test/ws |
Real-time preview: apply the filter chain to an input source. |
Pattern templates
Layout templates of named rectangles for LED device configuration.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/pattern-templates |
List all pattern templates. |
| POST | /api/v1/pattern-templates |
Create a pattern template (named rectangles). |
| GET | /api/v1/pattern-templates/{template_id} |
Get a pattern template by ID. |
| PUT | /api/v1/pattern-templates/{template_id} |
Update a pattern template. |
| DELETE | /api/v1/pattern-templates/{template_id} |
Delete a template (409 if referenced by targets). |
Gradients
Reusable gradient definitions (color stops). Built-in gradients are read-only but clonable.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/gradients |
List all gradients (built-in and user-created). |
| POST | /api/v1/gradients |
Create a user-defined gradient. |
| GET | /api/v1/gradients/{gradient_id} |
Get a gradient by ID. |
| PUT | /api/v1/gradients/{gradient_id} |
Update a gradient (built-ins are read-only). |
| POST | /api/v1/gradients/{gradient_id}/clone |
Clone a gradient into a customizable copy. |
| DELETE | /api/v1/gradients/{gradient_id} |
Delete a gradient (400 if built-in or referenced). |
Audio devices
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/audio-devices |
List audio input/output devices (flat list + per-engine grouping). |
Audio sources
Audio capture and processing sources for audio-reactive effects.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/audio-sources |
List all audio sources (optional source_type). |
| POST | /api/v1/audio-sources |
Create an audio source (capture or processed). |
| GET | /api/v1/audio-sources/{source_id} |
Get an audio source by ID. |
| PUT | /api/v1/audio-sources/{source_id} |
Update an audio source (partial). |
| DELETE | /api/v1/audio-sources/{source_id} |
Delete an audio source (409 if referenced). |
| WS | /api/v1/audio-sources/{source_id}/test/ws |
Real-time spectrum/RMS/peak/beat analysis (~20 Hz). |
Audio templates & engines
Audio capture templates and engine discovery.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/audio-templates |
List all audio capture templates. |
| POST | /api/v1/audio-templates |
Create an audio capture template. |
| GET | /api/v1/audio-templates/{template_id} |
Get an audio template by ID. |
| PUT | /api/v1/audio-templates/{template_id} |
Update an audio template. |
| DELETE | /api/v1/audio-templates/{template_id} |
Delete a template (cascades to audio sources). |
| GET | /api/v1/audio-engines |
List audio capture engines and availability. |
| WS | /api/v1/audio-templates/{template_id}/test/ws |
Real-time spectrum test for a template + device. |
Audio processing templates
Reusable audio filter chains.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/audio-processing-templates |
List all audio processing templates. |
| POST | /api/v1/audio-processing-templates |
Create a template (name + filter list). |
| GET | /api/v1/audio-processing-templates/{template_id} |
Get a template by ID. |
| PUT | /api/v1/audio-processing-templates/{template_id} |
Update a template (hot-updates running streams). |
| DELETE | /api/v1/audio-processing-templates/{template_id} |
Delete a template (409 if referenced). |
Audio filters
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/audio-filters |
List audio filter types and their option schemas. |
Value sources
Dynamic data inputs (brightness and other parameters): static, animated, audio, adaptive, color, sensor, HTTP, Home Assistant, and template — a sandboxed-Jinja combinator that evaluates an expression over the live values of other value sources.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/value-sources |
List all value sources (optional source_type). |
| POST | /api/v1/value-sources |
Create a value source (discriminated by source_type). |
| POST | /api/v1/value-sources/validate-template |
Validate a template expression + inputs (advisory; always 200 with {valid, error, errors, warnings, variables}). |
| GET | /api/v1/value-sources/{source_id} |
Get a value source by ID. |
| PUT | /api/v1/value-sources/{source_id} |
Update a value source; hot-reloads running streams. |
| DELETE | /api/v1/value-sources/{source_id} |
Delete a value source (400 if referenced by a target or another value source). |
| WS | /api/v1/value-sources/{source_id}/test/ws |
Real-time value output stream (~20 Hz). |
Template value source (source_type: "template")
A float combinator. Fields: template (a Jinja expression), inputs ([{name, value_source_id}] bindings to other value sources), default_value (fallback in [0,1] on any error), and eval_interval (optional re-eval throttle in seconds; 0/null = every poll). At runtime each input is exposed by its name (the source's normalized 0..1 value) plus raw[name] (its un-normalized value, where available). Globals: min, max, abs, round, clamp(x, lo=0, hi=1). The expression runs in a hardened ImmutableSandboxedEnvironment (no statements/blocks, filters, attribute access, **, or string repetition); results are coerced, NaN/inf-rejected, and clamped to [0,1]. Reference cycles and over-deep nesting are rejected at save time. For time-of-day logic, bind an adaptive_time or daylight source as an input.
Weather sources
Weather data providers feeding weather-driven value sources.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/weather-sources |
List all weather sources. |
| POST | /api/v1/weather-sources |
Create a weather source (provider, lat/lon, interval). |
| GET | /api/v1/weather-sources/{source_id} |
Get a weather source by ID. |
| PUT | /api/v1/weather-sources/{source_id} |
Update a weather source. |
| DELETE | /api/v1/weather-sources/{source_id} |
Delete a weather source. |
| POST | /api/v1/weather-sources/{source_id}/test |
Force-fetch current weather and return it. |
Automations
Rules that trigger scene presets (time, display state, MQTT, webhooks, Home Assistant, HTTP polling, active window).
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/automations |
Create an automation (rules + scene preset + deactivation). |
| GET | /api/v1/automations |
List automations with current activity state. |
| GET | /api/v1/automations/{automation_id} |
Get an automation by ID (includes webhook URL if any). |
| PUT | /api/v1/automations/{automation_id} |
Update an automation (partial); re-evaluates if enabled. |
| DELETE | /api/v1/automations/{automation_id} |
Delete and deactivate an automation. |
| POST | /api/v1/automations/{automation_id}/enable |
Enable and immediately evaluate rules. |
| POST | /api/v1/automations/{automation_id}/disable |
Disable and deactivate. |
Scene presets
Captured snapshots of target state that can be restored.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/scene-presets |
Create a preset by capturing current target state. |
| GET | /api/v1/scene-presets |
List all scene presets. |
| GET | /api/v1/scene-presets/{preset_id} |
Get a scene preset by ID. |
| PUT | /api/v1/scene-presets/{preset_id} |
Update metadata and optionally change targets. |
| DELETE | /api/v1/scene-presets/{preset_id} |
Delete a scene preset. |
| POST | /api/v1/scene-presets/{preset_id}/recapture |
Re-capture current state into the preset. |
| POST | /api/v1/scene-presets/{preset_id}/activate |
Activate the preset (restore captured state). |
Scene playlists
Ordered, timed sequences of scene presets that auto-cycle. The engine drives
one playlist at a time — starting a playlist stops any other. Each item
references a scene preset and holds it for its duration_seconds (min 1s)
before advancing; loop repeats from the start and shuffle randomises the
order each cycle.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/scene-playlists |
Create a playlist (items reference scene presets). |
| GET | /api/v1/scene-playlists |
List all playlists plus the current cycling state. |
| GET | /api/v1/scene-playlists/state |
Get the current cycling state (idle if nothing runs). |
| GET | /api/v1/scene-playlists/{playlist_id} |
Get a playlist by ID. |
| PUT | /api/v1/scene-playlists/{playlist_id} |
Update metadata, items, and loop/shuffle. |
| DELETE | /api/v1/scene-playlists/{playlist_id} |
Delete a playlist (stops it first if running). |
| POST | /api/v1/scene-playlists/{playlist_id}/start |
Start cycling (stops any other playlist first). |
| POST | /api/v1/scene-playlists/stop |
Stop the active playlist (leaves the last scene applied). |
Sync clocks
Shared clocks that drive linked animations with configurable speed.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/sync-clocks |
List all synchronization clocks. |
| POST | /api/v1/sync-clocks |
Create a sync clock. |
| GET | /api/v1/sync-clocks/{clock_id} |
Get a sync clock by ID. |
| PUT | /api/v1/sync-clocks/{clock_id} |
Update a clock (speed changes hot-applied). |
| DELETE | /api/v1/sync-clocks/{clock_id} |
Delete a clock (409 if referenced). |
| POST | /api/v1/sync-clocks/{clock_id}/pause |
Pause the clock (freeze linked animations). |
| POST | /api/v1/sync-clocks/{clock_id}/resume |
Resume a paused clock. |
| POST | /api/v1/sync-clocks/{clock_id}/reset |
Reset the clock to t=0. |
Webhooks
Inbound trigger endpoint for external services.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/webhooks/{token} |
Trigger an automation by secret token (activate/deactivate; rate-limited 30/min/IP). |
HTTP endpoints
Outbound HTTP polling endpoints for integrations. 🔒 These require a real API key even on loopback.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/http/endpoints |
List all HTTP polling endpoints. |
| POST | /api/v1/http/endpoints |
Create an endpoint (URL, method, auth token, headers). |
| GET | /api/v1/http/endpoints/{endpoint_id} |
Get an endpoint by ID. |
| PUT | /api/v1/http/endpoints/{endpoint_id} |
Update an endpoint. |
| DELETE | /api/v1/http/endpoints/{endpoint_id} |
Delete an endpoint. |
| POST | /api/v1/http/endpoints/test |
One-shot test fetch to validate a config before saving. |
| POST | /api/v1/http/endpoints/{endpoint_id}/test |
Test a stored endpoint without re-entering its token. |
Game integration
Game event ingestion, adapter metadata, presets, and diagnostics.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/game-integrations/presets |
List built-in effect presets. |
| GET | /api/v1/game-integrations |
List all game integration configs. |
| POST | /api/v1/game-integrations |
Create a game integration config. |
| GET | /api/v1/game-integrations/{integration_id} |
Get a config by ID. |
| PUT | /api/v1/game-integrations/{integration_id} |
Update a config. |
| DELETE | /api/v1/game-integrations/{integration_id} |
Delete a config. |
| POST | /api/v1/game-integrations/{integration_id}/event |
Ingest a game event (adapter-level auth; 16–64 Hz). |
| GET | /api/v1/game-integrations/{integration_id}/status |
Runtime status (connected state, event counts). |
| GET | /api/v1/game-integrations/{integration_id}/events |
Recent events for debugging (limit). |
| GET | /api/v1/game-adapters |
List adapter types and supported events. |
| POST | /api/v1/game-integrations/{integration_id}/apply-preset |
Apply a built-in preset (optionally replacing mappings). |
| POST | /api/v1/game-integrations/{integration_id}/auto-setup |
Write game config files and generate an auth token. |
Home Assistant
Home Assistant WebSocket sources, entity discovery, and live status.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/home-assistant/sources |
List HA sources with status and entity counts (?include_secrets=true 🔒). |
| POST | /api/v1/home-assistant/sources |
Create an HA source (host, long-lived token, filters). |
| GET | /api/v1/home-assistant/sources/{source_id} |
Get an HA source (?include_secrets=true 🔒). |
| PUT | /api/v1/home-assistant/sources/{source_id} |
Update an HA source; refreshes the connection. |
| DELETE | /api/v1/home-assistant/sources/{source_id} |
Delete an HA source and release its runtime. |
| GET | /api/v1/home-assistant/sources/{source_id}/entities |
List available HA entities (live + cache fallback). |
| POST | /api/v1/home-assistant/sources/{source_id}/test |
Test connection/auth and report HA version. |
| GET | /api/v1/home-assistant/status |
Overall HA integration status per source. |
MQTT sources
MQTT broker connections (sources) and status monitoring.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/mqtt/sources |
List MQTT sources with connection status. |
| POST | /api/v1/mqtt/sources |
Create an MQTT source (broker connection). |
| GET | /api/v1/mqtt/sources/{source_id} |
Get an MQTT source by ID. |
| PUT | /api/v1/mqtt/sources/{source_id} |
Update a source; restarts the broker runtime. |
| DELETE | /api/v1/mqtt/sources/{source_id} |
Delete a source and release its runtime. |
| POST | /api/v1/mqtt/sources/{source_id}/test |
Test connection to the broker (10s timeout). |
| GET | /api/v1/mqtt/status |
Overall MQTT integration status per source. |
Assets
Media files (sounds, images, videos) used by effects and notifications.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/assets |
List assets (optional asset_type filter). |
| GET | /api/v1/assets/{asset_id} |
Get asset metadata by ID. |
| POST | /api/v1/assets |
Upload a new asset file (multipart/form-data). |
| PUT | /api/v1/assets/{asset_id} |
Update asset metadata. |
| DELETE | /api/v1/assets/{asset_id} |
Delete an asset (prebuilt assets are soft-deleted/restorable). |
| GET | /api/v1/assets/{asset_id}/file |
Serve the asset file (download). |
| POST | /api/v1/assets/restore-prebuilt |
Re-import any deleted prebuilt assets. |
Graph wiring
The wiring-graph: schema registry, topology, dependents, validation, and subgraph duplication.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/graph/schema |
Registry of connectable reference fields. |
| GET | /api/v1/graph |
Full wiring topology (nodes + edges) and validation report. |
| GET | /api/v1/graph/dependents/{kind}/{entity_id} |
Every entity that references (kind, entity_id). |
| POST | /api/v1/graph/validate-connection |
Validate a proposed wiring edit (existence, kind, no cycle). |
| POST | /api/v1/graph/duplicate |
Deep-clone selected value/color-strip sources with remapped wiring. |
Calibration
Guided LED chase and auto-solver for the CalibrationConfig stored on a
color-strip source. The flow is:
- Start a session (
POST /session) — stops any running target on the device and remembers it for restore on stop. - Position the chase pixel (
POST /session/position) to walk through each physical corner and record the LED index. - Solve (
POST /solve) — the server computes per-edge LED counts. - Persist — call
PUT /api/v1/color-strip-sources/{id}with the solvedcalibrationobject to save and hot-reload. - Stop (
POST /session/stop) — clears the device and restores the prior target.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/calibration/session |
Start a calibration session on a device (stops the running target, clears to black). |
| POST | /api/v1/calibration/session/position |
Advance the chase pixel to LED index (± window dim neighbours). |
| POST | /api/v1/calibration/session/stop |
End the session: clear to black and restore the prior target. |
| POST | /api/v1/calibration/session/cancel |
Alias for stop — no calibration is applied. |
| GET | /api/v1/calibration/session/state |
Current session state (active, device_id, led_count, last_activity). |
| POST | /api/v1/calibration/solve |
Solve per-edge LED counts from 4 corner tap indices. Returns solved config dict (does NOT persist). |
Session state response shape:
{
"active": true,
"device_id": "dev_abc123",
"led_count": 100,
"prior_target_id": "ot_xyz456",
"last_activity": "2026-06-08T12:34:56.789Z"
}
Solve request (body):
{
"device_id": "dev_abc123",
"start_position": "bottom_left",
"layout": "clockwise",
"corner_indices": [0, 30, 60, 80],
"offset": 0
}
corner_indices must be exactly 4 integers, one per screen corner, in the
strip-walk order defined by (start_position, layout). Provide either
device_id (preferred — server derives led_count) or led_count directly.
Important session behavior:
- Stops the running output target — starting a calibration session immediately stops any output target currently running on that device. Other clients driving that device will lose their output for the duration of the session.
- Single session only — only one calibration session runs at a time across the whole server. Starting a new session automatically ends the previous one (clearing and restoring its device first), regardless of which device each session is on.
- Idle auto-end — a session that receives no
positioncalls for ~60 seconds is automatically stopped and the prior target restored, so devices are never left dark indefinitely.
Idle timeout: a session that receives no position calls for 60 seconds
is automatically stopped and the prior target restored.
Setup scaffold
One-call first-run helper that creates the full capture-to-output chain and returns all entity ids. The wizard calls this, then starts the output target after optional calibration.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/setup/scaffold |
Create capture template + picture source + color-strip source + LED output target in one atomic call with rollback on partial failure. Does NOT auto-start the target. |
Wizard sequence (Phase 4):
- Discover or create the device via
POST /api/v1/devices(full URL normalisation + provider validation runs there). - Call
POST /api/v1/setup/scaffoldwith the resultingdevice_id. - Calibrate (Phase 1 endpoints).
- Start the output target via
POST /api/v1/output-targets/{id}/start.
Request body:
{
"device_id": "device_abc123",
"display_index": 0,
"calibration": null
}
device_id is required and must reference an existing device (created via
POST /api/v1/devices). display_index selects the monitor to capture
(0 = primary; range 0–63). calibration is an optional CalibrationConfig
dict; when omitted, create_default_calibration(led_count) is used.
Response (201 Created):
{
"device_id": "device_abc123",
"capture_template_id": "tpl_11223344",
"picture_source_id": "ps_aabbccdd",
"color_strip_source_id": "css_11223344",
"output_target_id": "pt_aabbccdd",
"capture_template_reused": true
}
capture_template_reused is true when an existing template matched the
platform engine (no new template was created).
Rollback: if any step fails, all entities created within the same call are deleted in reverse order so no orphans remain. The pre-existing device and any reused template are never deleted. Entity "created" events are emitted only after the full chain succeeds, so a rollback never produces ghost UI cards.
Web UI & PWA
App-level routes served by FastAPI (not under /api/v1).
| Method | Path | Description |
|---|---|---|
| GET | / |
The web dashboard UI. |
| GET | /manifest.json |
PWA manifest (root scope). |
| GET | /sw.js |
Service worker (root scope). |
| GET | /openapi.json |
OpenAPI schema. |
| GET | /docs |
Swagger UI (interactive API docs). |
| GET | /redoc |
ReDoc API reference. |
Next steps
- Installation Guide
- Calibration Guide
- Interactive, always-current schemas:
/docs