Displaying content¶
The device always has something on screen: a boot splash, the waiting page, a remote URL,
or an uploaded content bundle. This page covers the everyday recipes for
putting content on screen and controlling how it's shown, using the control API on
http://10.99.0.1/api/v1 (see API overview) and, where available, the
management UI.
All examples use curl against the device's fixed USB address 10.99.0.1. Anything shown here
also works unchanged over the serial (NDJSON) transport — see
Serial API — and through the Go client library.
Display a remote URL¶
curl -X POST http://10.99.0.1/api/v1/display/navigate \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/promo"}'
The kiosk browser navigates immediately. This is a full-page navigation to a page fetched over whatever network path the device has (see the wireless guide and dev host guide for connection sharing) — for content you host yourself, an uploaded content bundle served locally is usually a better fit: no network dependency, and no external origin.
Web UI: Display page → Navigate to URL field.
Display an uploaded content bundle¶
Once a bundle has been uploaded, show it with:
curl -X POST http://10.99.0.1/api/v1/display/bundle \
-H 'Content-Type: application/json' \
-d '{"name": "promo"}'
Web UI: Content page → pick a bundle → Display.
Return to the waiting page¶
This is also what the device falls back to automatically on boot (if nothing else is configured) and after a crash-looping page (see Crash recovery below).
Web UI: Display page → Show waiting page.
Reload the current page¶
Reloads whatever is currently shown (URL or bundle) without changing the target.
Restart the browser¶
If the page is stuck in a way a reload won't fix:
This kills and relaunches the kiosk browser process, then re-applies the configured display
target (rotation and startup URL/bundle) — not necessarily the last URL you navigated to by hand.
Returns 200 as soon as the relaunch is scheduled; watch the display_state event (below) for
completion.
Check what's currently on screen¶
Returns the current mode (waiting | url | bundle), the active URL or bundle name, whether
the screen is on, the current rotation, and the resolution. The same shape is pushed as a
display_state event (see Events) every time the mode or URL changes, or the
browser crashes/restarts — subscribe instead of polling if you need to react promptly.
Web UI: Dashboard page (live-updating "Display" card) and Display page.
Turn the screen on/off¶
curl -X POST http://10.99.0.1/api/v1/display/screen \
-H 'Content-Type: application/json' \
-d '{"on": false}'
This uses HDMI-CEC to put the connected display into standby — the kiosk browser and the current
page keep running, only the panel goes dark. It's best-effort: it requires a CEC-capable screen
and cable. GET /display reflects the commanded state in screen_on; if the screen doesn't
support CEC, the call succeeds but nothing visibly happens.
Change rotation¶
Rotation is a configuration field, applied at the next boot (see Configuration → Display settings for the full field list and the live-vs-reboot-required distinction):
curl -X PATCH http://10.99.0.1/api/v1/config \
-H 'Content-Type: application/json' \
-d '{"display": {"rotation": 90}}'
The response's applied map reports "display.rotation": "reboot_required" — reboot the device
(POST /api/v1/device/reboot) for it to take effect. The new rotation survives future reboots.
For 90°/270°, content must be authored for the swapped logical viewport size (rotation is
applied as a CSS transform on the page, not a real display-mode change) — see the configuration
guide for details.
Take a screenshot¶
Returns a PNG of exactly what's on screen right now (rotation already applied), captured from the browser's compositor — handy for remote monitoring or automated visual checks.
Web UI: Display page → Screenshot.
Run JavaScript in the current page¶
curl -X POST http://10.99.0.1/api/v1/display/execute-js \
-H 'Content-Type: application/json' \
-d '{"script": "document.title"}'
Returns {"result": <json>} with whatever the script's last expression evaluated to. This is a
blunt, one-shot tool for diagnostics or simple pokes; if your page and host need to exchange
messages routinely, use the page channel instead (window.mcd in the page, POST
/api/v1/page/message / the page_message event on the host side) — see
REST and WebSocket API and the display-client.js reference in the
client library guide.
Enumerate display outputs¶
Returns the list of physical outputs the device knows about: id, connector (e.g.
HDMI-A-1), resolution, rotation, connected. In the current release every board renders
on a single screen, so this returns exactly one entry even on Pi 4/5 boards with two HDMI ports;
the field exists so the same API call keeps working once multi-output rendering ships. Every
display/* call above accepts an optional screen query parameter for forward-compatibility —
omit it (the device uses the primary screen automatically).
Crash recovery and fail-safe behavior¶
The device is designed to always converge on something being shown:
- If the kiosk browser process crashes,
displaydrestarts it automatically (within a few seconds) on the same content, withdisplay_stateevents marking the crash and recovery. - If the same URL or bundle crashes three times within two minutes, the device gives up on it
and falls back to the waiting page, emitting a
display_stateevent witherror: "content_crash_loop". This is a strong signal your content has a fatal bug (an infinite synchronous loop, a hard JS exception on load, etc.) — check it before re-displaying the same content. - If configured content is missing or invalid at boot (a startup bundle that was deleted, for example), the device falls through to the next configured target and ultimately the waiting page, rather than getting stuck.
There is no API call needed to "recover" from this — just fix the content and re-navigate/re-display it.
See also¶
- Content bundles — uploading, listing, deleting local content.
- Configuration — rotation, startup target, resume-on-boot.
- REST and WebSocket API — the page channel and event subscriptions in detail.
- Management UI tour — the Display and Page channel pages.