# Host API ## Purpose The host API is the stable external product boundary for: - the creative web UI - the native engineering GUI - future remote operator clients - later external show-control adapters such as a grandMA bridge The realtime rule remains strict: - the API is a control and observation layer - the host core remains the timing authority - no frontend or external adapter is allowed to become the LED clock ## Runtime Components Core and API implementation: - `crates/infinity_host/src/control.rs` - `crates/infinity_host/src/scene.rs` - `crates/infinity_host/src/show_store.rs` - `crates/infinity_host/src/simulation.rs` - `crates/infinity_host/src/external_control.rs` - `crates/infinity_host_api/src/dto.rs` - `crates/infinity_host_api/src/server.rs` Server startup: ```powershell cargo run -p infinity_host_api -- --config config/project.example.toml --bind 127.0.0.1:9001 --runtime-state data/runtime_state.json ``` Creative web UI V1 is served by the same process: ```text http://127.0.0.1:9001/ ``` ## Versioning Policy The current public contract is `v1`. Rules: - all public HTTP and WebSocket routes are namespaced under `/api/v1` - every response body carries `api_version: "v1"` - additive fields are allowed inside `v1` - semantic breaking changes require a new version namespace - external consumers must treat undocumented internal-only fields as unstable and ignore them ## Stable External Models Stable external response families: - command response - state snapshot - preview snapshot - combined snapshot - catalog - event stream - typed error object Stable external command families: - global control - pattern and preset selection - group targeting - scene parameter updates - transition configuration - preset persistence - creative snapshot persistence and recall - panel test trigger ## Internal Versus External Fields External and stable in `v1`: - every field defined in `crates/infinity_host_api/src/dto.rs` - route names and payload shapes documented below - error object shape `{ api_version, error: { code, message } }` - event stream envelope shape `{ api_version, sequence, generated_at_millis, message }` Internal and not part of the API contract: - the exact shape of `HostSnapshot` in `crates/infinity_host/src/control.rs` - simulation-only storage layout in `data/runtime_state.json` - internal event history buffering size - internal scene library structures in `show_store.rs` - engineering-GUI-specific rendering or polling behavior ## HTTP Endpoints ### GET `/api/v1/state` Returns only the stable state snapshot. Example: ```json { "api_version": "v1", "generated_at_millis": 512, "state": { "system": { "project_name": "Infinity Vis", "schema_version": 1, "topology_label": "6 nodes / 18 outputs / 106 LEDs" }, "global": { "blackout": false, "master_brightness": 0.2, "selected_pattern": "gradient", "selected_group": "top_panels", "transition_duration_ms": 320, "transition_style": "chase" }, "engine": { "logic_hz": 120, "frame_hz": 60, "preview_hz": 15, "uptime_ms": 512, "frame_index": 30, "dropped_frames": 0, "active_transition": { "style": "chase", "from_pattern_id": "solid_color", "to_pattern_id": "gradient", "duration_ms": 320, "progress": 0.28 } } } } ``` ### GET `/api/v1/preview` Returns only the stable preview snapshot. Example: ```json { "api_version": "v1", "generated_at_millis": 512, "preview": { "generated_at_millis": 512, "panels": [ { "node_id": "node-01", "panel_position": "top", "representative_color_hex": "#FF8A5B", "sample_led_hex": [ "#FF8A5B", "#F36E43", "#D85A2F" ], "energy_percent": 47, "source": "transition" } ] } } ``` ### GET `/api/v1/snapshot` Returns the convenience composition of `state` plus `preview`. This route exists for lightweight clients and debugging. Consumers that want strict separation should prefer `GET /api/v1/state` and `GET /api/v1/preview`. ### GET `/api/v1/catalog` Returns the stable creative library: - patterns - presets - groups - creative snapshots Example preset summary: ```json { "preset_id": "ocean_gradient", "pattern_id": "gradient", "target_group": null, "transition_duration_ms": 320, "transition_style": "crossfade", "source": "built_in" } ``` Example creative snapshot summary: ```json { "snapshot_id": "variant_floor", "label": "Variant Floor", "pattern_id": "noise", "target_group": "bottom_panels", "transition_duration_ms": 220, "transition_style": "chase", "saved_at_unix_ms": 1760000000000 } ``` ### GET `/api/v1/presets` Returns only preset summaries. ### GET `/api/v1/groups` Returns only group summaries. ### POST `/api/v1/command` Accepts one versioned command envelope. Example request: ```json { "request_id": "web-1713352662000", "command": { "type": "save_creative_snapshot", "payload": { "snapshot_id": "variant_floor", "label": "Variant Floor", "overwrite": false } } } ``` Example response: ```json { "api_version": "v1", "accepted": true, "request_id": "web-1713352662000", "generated_at_millis": 522, "command_type": "save_creative_snapshot", "summary": "creative snapshot saved: variant_floor" } ``` ## Stable Error Object All API failures return: ```json { "api_version": "v1", "error": { "code": "unknown_creative_snapshot", "message": "creative snapshot 'does_not_exist' does not exist" } } ``` Stable `v1` error families currently include: - `invalid_request_json` - `invalid_command` - `unknown_group` - `unknown_preset` - `unknown_creative_snapshot` - `preset_exists` - `snapshot_exists` - `group_exists` - `persist_failed` - `missing_websocket_key` - `not_found` ## WebSocket Event Stream ### WS `/api/v1/stream` The stream emits a typed envelope with a monotonic sequence counter: ```json { "api_version": "v1", "sequence": 19, "generated_at_millis": 880, "message": { "type": "event", "payload": { "kind": "warning", "code": "unknown_creative_snapshot", "message": "creative snapshot 'does_not_exist' does not exist" } } } ``` Stable message types: - `snapshot` - `preview` - `event` Stable event kinds: - `info` - `warning` - `error` ## Guaranteed Commands In `v1` Guaranteed control commands: - `set_blackout` - `set_master_brightness` - `select_pattern` - `recall_preset` - `select_group` - `set_scene_parameter` - `set_transition_duration_ms` - `set_transition_style` - `trigger_panel_test` Guaranteed persistence and creative-library commands: - `save_preset` - `save_creative_snapshot` - `recall_creative_snapshot` - `upsert_group` ## Persistence Behavior The simulation-backed host service now persists runtime-facing creative data to `data/runtime_state.json` by default. Persisted data includes: - active scene - global blackout and brightness state - transition duration and style - runtime user presets - runtime user groups - creative snapshots and variants This persistence file is an internal runtime artifact, not the public API contract. ## External Show Control Adapter Boundary The generic internal adapter surface lives in: - `crates/infinity_host/src/external_control.rs` Key rule: - future adapters may only translate external intent into the defined host command surface - they must not reach into simulation internals, UI state, or hardware driver details directly ## Contract And Integration Coverage Current software-side hardening lives in: - `crates/infinity_host_api/tests/contract.rs` - `crates/infinity_host/src/show_store.rs` tests - `crates/infinity_host/src/simulation.rs` tests Covered flows include: - state, preview, snapshot, catalog, presets, and groups endpoints - command success and typed command failure - WebSocket snapshot, preview, and event messages - group targeting - parameter updates - transition configuration - blackout - preset save - creative snapshot save and recall - persistence across restart - a longer ignored load-oriented sequence for platform hardening ## Web UI Scope The current web UI intentionally focuses on creative use: - pattern and preset selection - group targeting - transition configuration - scene parameters - preset save and overwrite - creative snapshot save and recall - preview - raw snapshot display - filterable event feed Mapping, topology diagnostics, panel-test administration, and low-level node status remain primarily in the native engineering GUI.