Repository navigation
Expand file tree
/
Copy pathreference.html
More file actions
8 lines (8 loc) · 47.3 KB
/
Copy pathreference.html
File metadata and controls
8 lines (8 loc) · 47.3 KB
1
2
3
4
5
6
7
8
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="color-scheme" content="light dark"><title>PCController API Reference</title>
<style>:root{font-family:Inter,Segoe UI,system-ui,sans-serif;color-scheme:light dark;--bg:#f6f7fb;--panel:#fff;--text:#172033;--muted:#647087;--line:#dfe3ec;--accent:#6d4aff}@media(prefers-color-scheme:dark){:root{--bg:#11131a;--panel:#191c25;--text:#edf0f7;--muted:#a8b0c2;--line:#303543;--accent:#a995ff}}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text)}main{width:min(1180px,calc(100% - 32px));margin:auto;padding:48px 0 80px}header{display:grid;gap:12px;margin-bottom:34px}h1{font-size:clamp(2rem,5vw,4rem);letter-spacing:-.05em;margin:0}p{color:var(--muted);max-width:76ch;line-height:1.65}.pills{display:flex;flex-wrap:wrap;gap:8px}.pills a,.pills span,td span{border:1px solid var(--line);border-radius:999px;padding:6px 10px;color:var(--text);text-decoration:none;background:color-mix(in srgb,var(--panel) 88%,var(--accent) 12%)}section{margin-top:34px;background:color-mix(in srgb,var(--panel) 92%,transparent);border:1px solid var(--line);border-radius:20px;overflow:hidden;box-shadow:0 18px 55px color-mix(in srgb,var(--text) 8%,transparent)}section>div{padding:22px 24px 6px}h2{margin:0;font-size:1.25rem}table{border-collapse:collapse;width:100%;font-size:.9rem}th,td{text-align:left;padding:13px 16px;border-top:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-weight:600}code{font-family:Cascadia Code,ui-monospace,monospace;color:var(--accent);overflow-wrap:anywhere}@media(max-width:720px){main{width:min(100% - 20px,1180px);padding-top:26px}section{overflow:auto}table{min-width:760px}}</style></head>
<body><main><header><span>OFFLINE CONTRACT · LIVING API</span><h1>PCController API</h1><p>The primary host exposes one unversioned, safety-gated living surface across REST, JSON-RPC, WebSocket, and the bounded Socket.IO adapter. Loopback is the default; immediate-alpha application authentication and authorization are disabled under issue #148.</p><div class="pills"><a href="openapi.json">OpenAPI 3.1</a><a href="asyncapi.json">AsyncAPI 3.0</a><a href="jsonrpc.schema.json">JSON-RPC schema</a><span>189 RPC methods</span><span>88 HTTP operations</span></div></header>
<section><div><h2>HTTP operations</h2><p>Canonical routes live directly under <code>/api/</code>. JSON bodies are capped at 1 MiB.</p></div><table><thead><tr><th>Method</th><th>Path</th><th>Purpose</th><th>Capability</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>/healthz</code></td><td>Service liveness and API identity</td><td><span>public</span></td></tr><tr><td><code>GET</code></td><td><code>/upnp/public.json</code></td><td>Bounded public host, board, endpoint, health, and telemetry directory</td><td><span>public</span></td></tr><tr><td><code>GET</code></td><td><code>/api/ui-config</code></td><td>Non-secret browser bootstrap</td><td><span>public</span></td></tr><tr><td><code>GET</code></td><td><code>/api/auth/server-proof</code></td><td>Dormant alpha compatibility endpoint; returns 409 while application authentication is disabled</td><td><span>public</span></td></tr><tr><td><code>POST</code></td><td><code>/api/session/ticket</code></td><td>Dormant alpha compatibility endpoint; returns 409 while application authentication is disabled</td><td><span>session</span></td></tr><tr><td><code>POST</code></td><td><code>/api/rpc</code></td><td>JSON-RPC 2.0 request</td><td><span>dynamic</span></td></tr><tr><td><code>GET</code></td><td><code>/api/snapshot</code></td><td>Authoritative cached controller snapshot</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/diagnostics/cpu-profile</code></td><td>Explicit five-second application CPU profile; loopback callers only, one active capture, no board actions or request body</td><td><span>local-only</span></td></tr><tr><td><code>GET</code></td><td><code>/api/estop</code></td><td>Authoritative effect and motion interlock state</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/estop</code></td><td>Engage or release the effect and motion interlock</td><td><span>board_commands</span></td></tr><tr><td><code>POST</code></td><td><code>/api/estop</code></td><td>Engage or release the effect and motion interlock</td><td><span>board_commands</span></td></tr><tr><td><code>GET</code></td><td><code>/api/peripherals</code></td><td>Peripheral descriptors and host-owned names</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/peripherals</code></td><td>Replace host-owned peripheral names</td><td><span>host_configuration</span></td></tr><tr><td><code>GET</code></td><td><code>/api/pwm</code></td><td>Authoritative PWM state</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/pwm</code></td><td>Mutate PWM state with board readback</td><td><span>board_commands</span></td></tr><tr><td><code>DELETE</code></td><td><code>/api/pwm</code></td><td>Mutate PWM state with board readback</td><td><span>board_commands</span></td></tr><tr><td><code>GET</code></td><td><code>/api/commands</code></td><td>Shared command catalog</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/program-state</code></td><td>Host-owned program state</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/program-state</code></td><td>Update host-owned program state</td><td><span>board_commands</span></td></tr><tr><td><code>POST</code></td><td><code>/api/program-state</code></td><td>Update host-owned program state</td><td><span>board_commands</span></td></tr><tr><td><code>GET</code></td><td><code>/api/menu/catalog</code></td><td>Live board menu catalog</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/menu/layout</code></td><td>Live board menu layout</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/menu/layout</code></td><td>Persist a validated board menu layout</td><td><span>board_commands</span></td></tr><tr><td><code>POST</code></td><td><code>/api/menu/layout</code></td><td>Persist a validated board menu layout</td><td><span>board_commands</span></td></tr><tr><td><code>GET</code></td><td><code>/api/host-menus</code></td><td>Host-presented menu directory</td><td><span>read</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/host-menus</code></td><td>Replace the host-presented menu directory</td><td><span>host_configuration</span></td></tr><tr><td><code>POST</code></td><td><code>/api/host-menus</code></td><td>Replace the host-presented menu directory</td><td><span>host_configuration</span></td></tr><tr><td><code>GET</code></td><td><code>/api/os/status</code></td><td>Host status and policy</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/os/facts</code></td><td>Bounded read-only host facts</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/os/key</code></td><td>Validated virtual-key action</td><td><span>virtual_keys</span></td></tr><tr><td><code>POST</code></td><td><code>/api/os/power</code></td><td>Confirmed system or display action</td><td><span>power_actions</span></td></tr><tr><td><code>POST</code></td><td><code>/api/command</code></td><td>Shared command dispatcher</td><td><span>dynamic</span></td></tr><tr><td><code>POST</code></td><td><code>/api/messages</code></td><td>Typed source-tagged message</td><td><span>messages</span></td></tr><tr><td><code>POST</code></td><td><code>/api/display</code></td><td>Present arbitrary seven-segment or LCD text with scroll and repeat timing</td><td><span>board_commands</span></td></tr><tr><td><code>POST</code></td><td><code>/api/opcode</code></td><td>Exchange an opaque versionless UART opcode</td><td><span>board_commands</span></td></tr><tr><td><code>GET</code></td><td><code>/api/app/bridge</code></td><td>Original coordinator bridge instance and process identity</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/app/instances</code></td><td>List or query live application instances</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/app/instances</code></td><td>Report or remove one live application instance</td><td><span>host_configuration</span></td></tr><tr><td><code>DELETE</code></td><td><code>/api/app/instances</code></td><td>Report or remove one live application instance</td><td><span>host_configuration</span></td></tr><tr><td><code>POST</code></td><td><code>/api/app/action</code></td><td>Freeze and route a correlated action to exact live application instances</td><td><span>host_configuration</span></td></tr><tr><td><code>POST</code></td><td><code>/api/app/action/ack</code></td><td>Acknowledge one exact app-action target outcome</td><td><span>host_configuration</span></td></tr><tr><td><code>GET</code></td><td><code>/api/app/action/outcome</code></td><td>Read one bounded app-action operation outcome</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/app/navigate</code></td><td>Navigate all, one surface, or one exact application instance</td><td><span>host_configuration</span></td></tr><tr><td><code>POST</code></td><td><code>/api/app/launch</code></td><td>Ensure, launch, or focus a named TUI or WebUI surface</td><td><span>host_configuration</span></td></tr><tr><td><code>GET</code></td><td><code>/api/bridges</code></td><td>Configured bridge state</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/bridges/call</code></td><td>Correlated bridge call</td><td><span>bridge_calls</span></td></tr><tr><td><code>GET</code></td><td><code>/api/artifacts/manifest</code></td><td>Artifact/default/current manifest</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/artifacts</code></td><td>Content-addressed artifact catalog</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/artifacts/upload</code></td><td>Import a verified artifact</td><td><span>programming</span></td></tr><tr><td><code>POST</code></td><td><code>/api/artifacts/fetch</code></td><td>Queue a bounded remote artifact fetch</td><td><span>programming</span></td></tr><tr><td><code>POST</code></td><td><code>/api/artifacts/capture</code></td><td>Capture flash or EEPROM explicitly</td><td><span>programming</span></td></tr><tr><td><code>GET</code></td><td><code>/api/artifacts/{kind}/{sha256}</code></td><td>Immutable ranged artifact download</td><td><span>read</span></td></tr><tr><td><code>HEAD</code></td><td><code>/api/artifacts/{kind}/{sha256}</code></td><td>Immutable ranged artifact download</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/artifacts/current/{kind}</code></td><td>Latest explicitly captured artifact</td><td><span>read</span></td></tr><tr><td><code>HEAD</code></td><td><code>/api/artifacts/current/{kind}</code></td><td>Latest explicitly captured artifact</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/board/firmware/upload</code></td><td>Queue a guarded staged-firmware transfer to the board</td><td><span>programming</span></td></tr><tr><td><code>GET</code></td><td><code>/api/board/firmware/download</code></td><td>Download the latest verified board flash readback</td><td><span>read</span></td></tr><tr><td><code>HEAD</code></td><td><code>/api/board/firmware/download</code></td><td>Download the latest verified board flash readback</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/board/firmware/download</code></td><td>Queue a fresh verified board flash readback</td><td><span>programming</span></td></tr><tr><td><code>POST</code></td><td><code>/api/updates/{kind}</code></td><td>Queue an explicitly authorized update</td><td><span>programming</span></td></tr><tr><td><code>POST</code></td><td><code>/api/restores/flash</code></td><td>Queue an explicitly authorized flash restore</td><td><span>programming</span></td></tr><tr><td><code>GET</code></td><td><code>/api/updates/status/{id}</code></td><td>Update operation progress</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/discovery/github/workflow</code></td><td>Discover workflow artifacts</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/discovery/github/release</code></td><td>Discover release assets</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/discovery/manifest</code></td><td>Serve or validate an update manifest</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/discovery/manifest</code></td><td>Serve or validate an update manifest</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/discovery/check</code></td><td>Compare candidate and installed identities</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/discovery/stage</code></td><td>Stage a verified candidate without programming</td><td><span>programming</span></td></tr><tr><td><code>GET</code></td><td><code>/api/discovery/status/{id}</code></td><td>Discovery or staging progress</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/webhooks/inbound</code></td><td>Optional inbound typed webhook</td><td><span>messages</span></td></tr><tr><td><code>GET</code></td><td><code>/api/webhooks/outbound/status</code></td><td>Outbound delivery queue and dead-letter status</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/webhooks/outbound/pending</code></td><td>Bounded non-secret pending delivery list</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/webhooks/outbound/dead</code></td><td>Bounded non-secret dead-letter list</td><td><span>read</span></td></tr><tr><td><code>POST</code></td><td><code>/api/webhooks/outbound/replay</code></td><td>Replay explicitly selected dead-letter deliveries</td><td><span>integrations</span></td></tr><tr><td><code>POST</code></td><td><code>/api/webhooks/outbound/clear</code></td><td>Clear explicitly selected dead-letter deliveries</td><td><span>integrations</span></td></tr><tr><td><code>GET</code></td><td><code>/api/integrations/status</code></td><td>Requested and effective buzzer routing and playback state</td><td><span>read</span></td></tr><tr><td><code>GET</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>HEAD</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>POST</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>PATCH</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>DELETE</code></td><td><code>/api/integrations/datahub/{path}</code></td><td>Sanitized loopback data-service proxy</td><td><span>integrations</span></td></tr><tr><td><code>GET</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr><tr><td><code>HEAD</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr><tr><td><code>POST</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr><tr><td><code>PUT</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr><tr><td><code>PATCH</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr><tr><td><code>DELETE</code></td><td><code>/api/integrations/device/{path}</code></td><td>Fail-closed device route; use typed RPC</td><td><span>integrations</span></td></tr></tbody></table></section>
<section><div><h2>JSON-RPC methods</h2><p>Standard JSON-RPC errors are preserved; host extensions use -32001 for authentication, -32003 for capability denial, and -32000 for runtime or device failures.</p></div><table><thead><tr><th>Method</th><th>Purpose</th><th>Capability</th><th>Idempotency</th></tr></thead><tbody><tr><td><code>controller.action.invoke</code></td><td>Invoke one stable action ID advertised by the attached board profile and wait for the board acknowledgement.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.action</code></td><td>Freeze a validated action to exact live targets and return its correlated per-target delivery operation.</td><td><span>dynamic</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.action.ack</code></td><td>Acknowledge one exact app-action target as applied or rejected.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.app.action.outcome</code></td><td>Return one bounded app-action operation and its exact per-target outcomes.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.app.bridge</code></td><td>Return the original coordinator bridge instance and its bounded process self-information.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.app.instance.get</code></td><td>Read one live application instance by ID.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.app.instance.remove</code></td><td>Remove one application instance from the live registry.</td><td><span>host_configuration</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.instance.report</code></td><td>Create or refresh one leased application-instance report.</td><td><span>host_configuration</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.instances</code></td><td>List live application instances and their bounded non-secret state.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.app.launch</code></td><td>Ensure, launch, or focus a named TUI or WebUI surface without arbitrary process execution.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.app.navigate</code></td><td>Navigate all, one surface, or one exact live application instance.</td><td><span>host_configuration</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.navigation.commit</code></td><td>Commit one follower group's canonical page and return its correlated coordinator outcome.</td><td><span>host_configuration</span></td><td>non-idempotent</td></tr><tr><td><code>controller.app.page</code></td><td>app page</td><td><span>host_configuration</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.capture</code></td><td>artifact capture</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.fetch</code></td><td>artifact fetch</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.list</code></td><td>artifact list</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.artifact.manifest</code></td><td>artifact manifest</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.artifact.upload</code></td><td>artifact upload</td><td><span>programming</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.artifact.upload.abort</code></td><td>Abort and remove an incomplete peer artifact transfer.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.upload.begin</code></td><td>Begin a bounded correlated peer artifact transfer.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.upload.chunk</code></td><td>Append one ordered bounded chunk to a peer artifact transfer.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.artifact.upload.finish</code></td><td>Revalidate and publish a completed peer artifact transfer.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.audio.cues</code></td><td>Return the receiving host's declared local sound-effect intent vocabulary.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.audio.play</code></td><td>Play one validated sound-effect intent on the receiving host while honoring its mute and volume policy.</td><td><span>integrations</span></td><td>non-idempotent</td></tr><tr><td><code>controller.board_automation.clear</code></td><td>Clear the board automation table and verify the empty snapshot.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.board_automation.list</code></td><td>Read one generation-consistent board automation snapshot.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.board_automation.put</code></td><td>Transactionally add or edit one board automation and verify readback.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.board_automation.remove</code></td><td>Remove one board automation and verify its absence.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.board_profile.get</code></td><td>Return the attached board identity, configured wiring mode, and opaque profile revision.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.board_profile.update</code></td><td>Bind the attached physical board identity to one explicit host-owned wiring profile.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.board.firmware.download</code></td><td>Queue a fresh verified flash-only readback from the board.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.board.firmware.upload</code></td><td>Queue a guarded transfer of a staged immutable firmware artifact to the board.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.bridge.call</code></td><td>bridge call</td><td><span>bridge_calls</span></td><td>non-idempotent</td></tr><tr><td><code>controller.bridge.list</code></td><td>bridge list</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.close</code></td><td>close</td><td><span>connection_control</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.command.catalog</code></td><td>Return the machine-readable shared command catalog.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.command.execute</code></td><td>Run a shared command after semantic capability classification.</td><td><span>dynamic</span></td><td>non-idempotent</td></tr><tr><td><code>controller.connect</code></td><td>connect</td><td><span>connection_control</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.device.action</code></td><td>device action</td><td><span>integrations</span></td><td>non-idempotent</td></tr><tr><td><code>controller.device.inspect</code></td><td>device inspect</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.device.status</code></td><td>device status</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.discovery.check</code></td><td>discovery check</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.config</code></td><td>Return persistent network advertisement configuration.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.config.get</code></td><td>Return persistent network advertisement configuration.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.config.set</code></td><td>Persist and hot-apply network advertisement configuration.</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.discovery.connect</code></td><td>Verify an authenticated discovered host and return its health and snapshot.</td><td><span>bridge_calls</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.discovery.github.release</code></td><td>discovery github release</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.github.workflow</code></td><td>discovery github workflow</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.local_manifest</code></td><td>discovery local manifest</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.manifest</code></td><td>discovery manifest</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.scan</code></td><td>discovery scan</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.discovery.stage</code></td><td>discovery stage</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.discovery.status</code></td><td>discovery status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.display.send</code></td><td>display send</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.estop.get</code></td><td>Return the authoritative PCController-wide effect and motion interlock state.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.estop.set</code></td><td>Engage or release the PCController-wide effect and motion interlock; release never resumes cancelled work.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.event.latest</code></td><td>event latest</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.event.next</code></td><td>Long-poll the next retained event after an event ID, optionally selecting activity, state, telemetry, or debug.</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.exit</code></td><td>exit</td><td><span>shutdown</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.firmware.build</code></td><td>Compile the canonical host project with reviewed feature names and publish correlated ordered program progress events.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.front_panel</code></td><td>front panel</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.front-panel</code></td><td>front panel</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.history.status</code></td><td>history status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.history.timeline</code></td><td>history timeline</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.host_menu.config</code></td><td>host menu config</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.host_menu.config.get</code></td><td>host menu config get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.host_menu.config.set</code></td><td>host menu config set</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.host_menu.configure</code></td><td>host menu configure</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.host_menu.content.push</code></td><td>host menu content push</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.host_menu.directory.replace</code></td><td>host menu directory replace</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.host_menu.state</code></td><td>host menu state</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.host.facts</code></td><td>host facts</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.host.facts.catalog</code></td><td>host facts catalog</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.hotkeys.get</code></td><td>hotkeys get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.hotkeys.set</code></td><td>hotkeys set</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.illumination.get</code></td><td>Read persisted enclosure-light policy, live door-selected target, and exact applied MOSFET channel-12 PWM.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.illumination.override</code></td><td>Temporarily apply exact 0..4095 PWM to MOSFET channel 12 without changing or taking ownership from the enclosure-light policy, then return authoritative readback.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.illumination.set</code></td><td>Change only mode/on/off illumination fields, verify EEPROM durability, and return authoritative live state.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.integrations.local.get</code></td><td>integrations local get</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.integrations.local.set</code></td><td>integrations local set</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.integrations.status</code></td><td>Return requested and effective buzzer routing and playback state.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.lcd.presentation.configure</code></td><td>lcd presentation configure</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.lcd.presentation.status</code></td><td>lcd presentation status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.lcd.priority</code></td><td>lcd priority</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.lcd.prompt</code></td><td>lcd prompt</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.media.authority.change</code></td><td>Request, accept, reject, release, lock, or unlock playback authority for a registered client.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.media.authority.get</code></td><td>Return the registered playback authority owner, pending requests, exclusivity, and revision.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.media.playback.get</code></td><td>Return the authoritative registered consumer playback clock and prepared-timeline state.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.media.playback.update</code></td><td>Publish one sequenced playback-clock update from the registered authority owner.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.media.timeline.get</code></td><td>Return the prepared media timeline, acknowledgement ledger, and sticky failure state.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.media.timeline.prepare</code></td><td>Validate and arm a revisioned host-executed hardware timeline for a registered paused consumer.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.melodies.list</code></td><td>Return the effective configured host melody catalog.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.menu.current</code></td><td>menu current</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.menu.jump</code></td><td>menu jump</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.menu.layout.get</code></td><td>menu layout get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.menu.layout.set</code></td><td>menu layout set</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.menu.list</code></td><td>menu list</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.menu.page</code></td><td>menu page</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.message.send</code></td><td>message send</td><td><span>messages</span></td><td>non-idempotent</td></tr><tr><td><code>controller.mirror.apply</code></td><td>mirror apply</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.mirror.configure</code></td><td>mirror configure</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.mirror.inspect</code></td><td>mirror inspect</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.mirror.resync</code></td><td>mirror resync</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.mirror.status</code></td><td>mirror status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.network.peers.get</code></td><td>Return persistent peer topology with secret references and no plaintext credentials.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.network.peers.set</code></td><td>Replace and hot-apply peer topology; events, state, and status topics are accepted, and only optional secret references may carry compatibility credentials.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.opcode.exchange</code></td><td>Exchange an opaque versionless UART opcode and caller-selected response opcode.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.opcode.request</code></td><td>Alias for an opaque versionless UART opcode exchange.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.opcode.send</code></td><td>Send an opaque versionless UART opcode; ACK is expected by default.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.open</code></td><td>open</td><td><span>connection_control</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.os.configure</code></td><td>os configure</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.os.facts</code></td><td>os facts</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.os.facts.catalog</code></td><td>os facts catalog</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.os.key</code></td><td>os key</td><td><span>virtual_keys</span></td><td>non-idempotent</td></tr><tr><td><code>controller.os.policy</code></td><td>os policy</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.os.power</code></td><td>os power</td><td><span>power_actions</span></td><td>non-idempotent</td></tr><tr><td><code>controller.os.status</code></td><td>os status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.peer.update.host</code></td><td>Transfer a verified executable using a caller-generated idempotency_key, wait through the peer restart, and verify its exact active SHA-256 acknowledgement. Retry uncertain outcomes with the same key.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.peripheral.folder.update</code></td><td>Atomically create, rename, set the icon, delete or move members of a board-profile channel folder using required expected_revision; return the complete authoritative folder/control catalog.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.peripheral.presentation.update</code></td><td>Update one advertised peripheral name, icon, group, kind-local order, visibility, or lock using optional optimistic concurrency.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.peripherals</code></td><td>peripherals</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.peripherals.get</code></td><td>peripherals get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.peripherals.set</code></td><td>peripherals set</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.ping</code></td><td>Return service health and protocol identity.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.port.close</code></td><td>port close</td><td><span>connection_control</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.port.open</code></td><td>port open</td><td><span>connection_control</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.port.owner</code></td><td>port owner</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.port.process</code></td><td>port process</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.port.reset</code></td><td>port reset</td><td><span>reset</span></td><td>non-idempotent</td></tr><tr><td><code>controller.ports</code></td><td>ports</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.program_state.get</code></td><td>program state get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.program_state.set</code></td><td>program state set</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.program-state.get</code></td><td>program state get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.program-state.set</code></td><td>program state set</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.pwm.channel.configure</code></td><td>Persist a partial PWM channel configuration (output type, icon, curve, gamma, step_percent, on_behavior full|restore), preserving omitted fields, then publish the changed descriptor.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.pwm.off</code></td><td>pwm off</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.pwm.set</code></td><td>pwm set</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.pwm.trace.get</code></td><td>Return bounded DEBUG-only PWM acknowledgements; no board read or output change.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.pwm.trace.start</code></td><td>Temporarily capture one channel 0..15 for explicit duration_ms 1..60000, off by default; no board operation.</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.pwm.trace.stop</code></td><td>Stop temporary PWM acknowledgement capture and retain bounded receipts; no board operation.</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.pwm.values</code></td><td>pwm values</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.quit</code></td><td>quit</td><td><span>shutdown</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.reset</code></td><td>reset</td><td><span>reset</span></td><td>non-idempotent</td></tr><tr><td><code>controller.reset.lines</code></td><td>reset lines</td><td><span>reset</span></td><td>non-idempotent</td></tr><tr><td><code>controller.restore.flash</code></td><td>Restore a captured flash backup through the guarded restore path.</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.rf.binding.put</code></td><td>Create a uniquely named validated RF binding, or explicitly edit with previous_name; reject name/stale-target conflicts without replacing unrelated assignments.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.binding.remove</code></td><td>Remove one named host-owned RF application binding.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.catalog</code></td><td>Return learned RF records, live capture state, persisted bindings, and currently advertised action choices.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.rf.clear</code></td><td>rf clear</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.learn.cancel</code></td><td>rf learn cancel</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.learn.start</code></td><td>rf learn start</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.rf.learn.status</code></td><td>rf learn status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.rf.list</code></td><td>rf list</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.rf.map</code></td><td>Replace one learned RF mapping and return board readback.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.observed.add</code></td><td>Save a waveform actually received from the current board, unassigned, with preserved records and verified readback.</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.preferences.set</code></td><td>Save timed-learning, duration and continuous-capture preferences without entering learning.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.presentation</code></td><td>rf presentation</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.rf.remove</code></td><td>rf remove</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.rf.transmit</code></td><td>Transmit one validated RF waveform request.</td><td><span>board_commands</span></td><td>non-idempotent</td></tr><tr><td><code>controller.session.snapshot</code></td><td>session snapshot</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.session.snapshot.last</code></td><td>session snapshot last</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.snapshot</code></td><td>Return the authoritative cached controller snapshot.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.status</code></td><td>status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.status_led.release</code></td><td>status led release</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.status_led.set</code></td><td>status led set</td><td><span>board_commands</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.subscribe</code></td><td>Subscribe this WebSocket connection to activity events, changed state, explicit debug, raw opcodes, and/or status.</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.system.status</code></td><td>system status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.temperatures</code></td><td>temperatures</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.udp.call</code></td><td>udp call</td><td><span>bridge_calls</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.udp.config.get</code></td><td>udp config get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.udp.config.set</code></td><td>udp config set</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.udp.events.get</code></td><td>udp events get</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.udp.status</code></td><td>udp status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.udp.subscribe</code></td><td>udp subscribe</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.udp.unsubscribe</code></td><td>udp unsubscribe</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.ui.config</code></td><td>Return host-owned UI settings, including status_interval_ms and measurement_freshness_ms.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.ui.config.get</code></td><td>Return host-owned UI settings, including status_interval_ms and measurement_freshness_ms.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.ui.config.set</code></td><td>Atomically persist host UI fields; status_interval_ms is 50..60000 and measurement_freshness_ms is refresh+100..120000.</td><td><span>host_configuration</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.unsubscribe</code></td><td>Remove this WebSocket connection's active subscriptions.</td><td><span>events</span></td><td>safe</td></tr><tr><td><code>controller.update.eeprom</code></td><td>update eeprom</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.update.firmware</code></td><td>update firmware</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.update.host</code></td><td>update host</td><td><span>programming</span></td><td>non-idempotent</td></tr><tr><td><code>controller.update.status</code></td><td>update status</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.virtual_key</code></td><td>virtual key</td><td><span>virtual_keys</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.webhooks.clear</code></td><td>Clear explicitly selected dead-letter deliveries.</td><td><span>integrations</span></td><td>idempotent-with-authoritative-readback</td></tr><tr><td><code>controller.webhooks.dead</code></td><td>List bounded non-secret dead-letter deliveries.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.webhooks.pending</code></td><td>List bounded non-secret pending outbound deliveries.</td><td><span>read</span></td><td>safe</td></tr><tr><td><code>controller.webhooks.replay</code></td><td>Replay explicitly selected dead-letter deliveries.</td><td><span>integrations</span></td><td>non-idempotent</td></tr><tr><td><code>controller.webhooks.status</code></td><td>Return bounded outbound queue and dead-letter counters.</td><td><span>read</span></td><td>safe</td></tr></tbody></table></section>
<p>Contract digest <code>37d7181d0d839dbe2aba78f731adc11b93378796c26478bbff0c5bd7cc6bf5fa</code>. Generated by <code>Tools/Audit/generate-api-reference.mjs</code>.</p></main></body></html>