Files
alexei.dolgolyov 9dcd76d264 feat(setup): one-call setup scaffold + onboarding flag (phase 2)
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).
2026-06-08 15:22:04 +03:00

42 KiB
Raw Permalink Blame History

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

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 use multipart/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 return 422 with a structured detail array.
  • 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 fields icon and icon_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:

  1. The client connects. The server accepts the socket.
  2. 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, token may be null or the message omitted.
  3. The server replies {"type": "auth_ok"} on success, or {"type": "auth_error", "reason": "..."} then closes (close code 4401) on failure. A cross-site Origin is rejected with close code 4403.

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 checkGET /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 devicePOST /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 targetPOST /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 (0255).
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; 1664 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:

  1. Start a session (POST /session) — stops any running target on the device and remembers it for restore on stop.
  2. Position the chase pixel (POST /session/position) to walk through each physical corner and record the LED index.
  3. Solve (POST /solve) — the server computes per-edge LED counts.
  4. Persist — call PUT /api/v1/color-strip-sources/{id} with the solved calibration object to save and hot-reload.
  5. 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 indexwindow 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 position calls 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):

  1. Discover or create the device via POST /api/v1/devices (full URL normalisation + provider validation runs there).
  2. Call POST /api/v1/setup/scaffold with the resulting device_id.
  3. Calibrate (Phase 1 endpoints).
  4. 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 063). 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