Switchboard manual ⚡ Web flasher

API

Every Switchboard remote already talks to this: Settings → Select room calls GET /api/devices, and each data refresh makes two requests — GET /api/devices/<slug>/bundle (its room’s config, the shared WiFi/HA connection and theme versions; a bodyless 304 when nothing changed) and GET /api/devices/<slug>/state (the room’s live Home Assistant state, which the server fetches from HA in parallel). Older firmware uses GET /api/devices/<slug>/config and GET /api/globals and talks to HA directly; those still work. For /state the server must be able to reach Home Assistant at the host in Settings → Home Assistant — if it can’t, the remote falls back to asking HA itself. Every one of these three now requires the remote to be paired (see Pairing & auth) — the admin UI’s own browser session works too, so nothing changes for you in the UI itself.

Method Path Purpose Auth
GET /api/devices List rooms session or device
GET /api/devices/<slug>/config One room’s full config session or device
GET /api/devices/<slug>/bundle Room config + globals + theme versions in one response (304 when unchanged, via If-None-Match) session or device
GET /api/devices/<slug>/state Live Home Assistant state for every entity the room’s pages show, fetched in parallel by the server and trimmed to what the remote reads (502 if HA is unreachable from the server) session or device
GET /api/devices/<slug>/state?page=music&wait=25 Just one live page’s entities, held open (with If-None-Match) until they change or wait seconds pass (304); the response’s live says which pages are live (playing, moving) or passive session or device
GET /api/art?src=<entity_picture or URL>&size=280&fmt=mask1\|spectra\|png A picture resized and dithered into exactly what the device draws: mask1 (the remote’s 1-bit icon format), spectra (six-colour palette indices, 4 bits a pixel) or png (the admin preview); cached, 304 on repeat session or device
POST /api/devices/<slug>/config Create/update a room session
POST /api/devices Create a room from just a name session
DELETE /api/devices/<slug> Remove a room session
GET /api/globals Shared WiFi + Home Assistant connection session or device
POST /api/globals Update Globals session
GET /api/clients Every paired device (remotes and viewports) with its effective layout session
GET /api/overview The Home page: device counts and health, what needs attention, how requests to Home Assistant are going session
PUT /api/clients/<mac> Set a device’s name, type, room or layout (layout: null goes back to the defaults) session
GET /api/clients/schema The pages, tile types, sizes and refresh intervals the layout builders offer session
GET /api/ha/publish Battery publishing to Home Assistant: on or off, the sensors, the last sync and any error session
GET /api/ha/status Whether the server can reach Home Assistant with the saved connection session
GET /api/ha/entities Search HA’s entities (domains, q, deviceClass, limit) for the admin UI’s pickers session
POST /api/ha/lookup Look up specific entity ids ({ids: [...]}): each entity, or null if HA doesn’t have it session
GET /api/viewports/<mac>/bundle A viewport’s layout (carousel + screens) plus every icon it can show, Wi-Fi networks, NTP server, time zone and its current UTC offset (utcOffsetMin), and any firmware offer (me = the calling device; 304 when unchanged) session or device
GET /api/viewports/<mac>/state Every screen’s finished values, each with its own etag, and refreshInSec; ?screen=<id> returns one screen with ETag, X-Refresh-In and (during quiet hours) X-Quiet: 1 headers, and a bodyless 304 when unchanged session or device
POST /api/viewports/<mac>/preview The state an unsaved layout ({layout}) would produce — the admin UI’s live preview session
POST /api/viewports/import A kitchen panel’s own /api/config JSON ({config}) as a layout, to review and save session
GET /api/dashboards Every viewport layout (“dashboard” in the API), with its screens and the displays using it session
POST /api/dashboards Create one: {name, template: kitchen\|meetingRoom\|blank}, {name, copyFrom} or {name, layout} session
GET/PUT/DELETE /api/dashboards/<slug> Read, save ({name, layout}) or delete one (its displays go back to “not set up”) session
POST /api/dashboards/preview The state an unsaved layout would produce — the builder’s live preview session
GET /api/viewports/defaults The kitchen panel’s default layout, or ?kind=meetingRoom for a meeting-room sign session
POST /api/meeting-rooms/parse Read a pasted room list ({text}: a line per room — name, then a calendar link or calendar. entity, an occupancy sensor and the display’s MAC, in any order): each room, anything wrong with its line, whether its layout exists, and what its display is now session
POST /api/meeting-rooms Set up a sign per room: {text} or {rooms: [{name, calendar, occupancy, mac}]}, with finder (each sign lists the others; default on), approve (approve the listed displays now, even before they connect) and settings (refreshIntervalMin, refreshAligned, quietHours, aheadMin). Rooms whose names have a layout already are updated. Returns a line per room session
POST /api/calendars/check Read a calendar link ({calendar}): its name, how many events in the next two weeks and the next few, or why it can’t be read session
POST /api/pairing/approve-many Approve several waiting displays as viewports: {devices: [{mac, name, dashboard}]} session
GET /api/health Liveness, version, mDNS info none
GET /api/server/version Whether a newer Switchboard Server is out: {enabled, current, latest, newer, url, checkedAt, error}, from the last check session
POST /api/server/version/check Ask GitHub again now; the same answer session
GET /api/auth/status {authenticated, setupRequired} none
POST /api/auth/setup Set the admin password (first run only) none
POST /api/auth/login / /api/auth/logout Session cookie in/out none
POST /api/pairing/register A device’s first-ever contact none (device self-registers)
GET /api/pairing/devices List every device that’s contacted the server session
POST /api/pairing/<mac>/approve Approve a pending device, optionally assign its room session
POST /api/pairing/<mac>/assign | /rename | /revoke Change room / rename / revoke session
DELETE /api/pairing/<mac> Remove a device record session
GET /api/theme Current icon/font pack version stamps, for the calling device’s kind (?kind=viewport from a session) session or device
GET /api/theme/icons.pack | /fonts.pack The compiled binary a device downloads: a remote gets the remotes’ pack, a viewport the viewports’ session or device
GET /api/assets/icon-slots The ~107 named icon slots, for Settings → Theme session
GET /api/assets/icons/search?q= Search MDI icons (with previews) session
POST /api/assets/icons/compile | /api/assets/fonts/compile Compile + publish a new theme session
POST /api/devices/<slug>/state/preview The state an unsaved room layout would produce — the remote preview under the layout editor session
POST /api/feeds/check Read an RSS or Atom feed ({url}) and show what an Announcements section would session
GET /api/firmware/offer The update on offer for the calling remote, if any session or device
GET /api/firmware/image/<version> A build’s image, for the remote to install session or device
POST /api/firmware/report A remote’s result for an update attempt session or device
GET /api/firmware Updates: settings, builds and every device’s update state session
GET/PUT /api/security Allowed networks ({enabled, allowed}), with the address you’re seen from and the other security settings session
PUT /api/security/settings {sessionHours, loginLockout, acceptNewDevices} session
POST /api/security/sign-out-others Sign out every other browser session
PUT /api/firmware/settings Save the update settings (on/off, release, stage, pilots, schedule, button, minimum battery, repositories) session
POST /api/firmware/upload Add a build from an uploaded .bin session
DELETE /api/firmware/builds/<version> Remove a build (not the current release) session
GET /api/firmware/releases?repo= A listed repository’s GitHub releases session
POST /api/firmware/import | /api/firmware/latest Add a release ({repo, tag}), or the newest one ({repo}), from GitHub session

session is the admin UI’s login cookie; device is a paired device’s token (see Pairing & auth).

Health headers

Any paired device — remote or viewport — can send X-Battery, X-Temperature, X-Humidity, X-RSSI, X-Firmware and X-Board headers on its requests. The Home page and the device’s page show them, warn on a low battery or weak signal, and learn battery life from X-Battery.