Skip to main content
Version: 8.38

API Endpoints

FiestaBoard provides a REST API powered by FastAPI. Interactive API documentation is available at http://localhost:4420/api/docs when FiestaBoard is running.

Base URL​

http://localhost:4420

When using the default deployment, prefix all paths with /api (e.g. GET http://localhost:4420/api/health).

System Endpoints​

Health & Status​

MethodEndpointDescription
GET/healthHealth check, returns service health status
GET/statusService status, uptime, and current configuration
GET/configCurrent configuration settings

Display Control​

MethodEndpointDescription
POST/refreshRefresh the current display
POST/force-refreshForce refresh (bypasses preview cache)
POST/send-messageSend a custom message to the board

Service Control​

MethodEndpointDescription
POST/startStart the display service
POST/stopStop the display service

Page Endpoints​

MethodEndpointDescription
GET/pagesList all pages
POST/pagesCreate a new page
GET/pages/{id}Get a specific page
PUT/pages/{id}Update a page
DELETE/pages/{id}Delete a page
POST/pages/{id}/previewPreview a page (with variables resolved)

Page Fields​

When creating or updating a page, the following fields are available:

FieldTypeDescription
namestringPage name (required)
typestring"template", "single", or "composite"
device_typestring"flagship" (22×6) or "note" (15×3). Default: "flagship"
templatestring[]Template lines for template-type pages
duration_secondsnumberHow long to display (10–3600s, default 300)

Batch Operations​

MethodEndpointDescription
POST/pages/preview/batchPreview multiple pages at once
POST/displays/raw/batchGet raw display data for multiple pages

Schedule Endpoints​

MethodEndpointDescription
GET/schedulesList all schedule entries
POST/schedulesCreate a new schedule entry
GET/schedules/{id}Get a specific schedule entry
PUT/schedules/{id}Update a schedule entry
DELETE/schedules/{id}Delete a schedule entry

Plugin Endpoints​

MethodEndpointDescription
GET/pluginsList all plugins with status
GET/plugins/{id}Get plugin details
PUT/plugins/{id}/configUpdate plugin configuration
POST/plugins/{id}/enableEnable a plugin
POST/plugins/{id}/disableDisable a plugin
GET/plugins/{id}/dataGet current plugin data
GET/plugins/{id}/variablesGet available template variables

Settings Endpoints​

MethodEndpointDescription
GET/settings/allGet all settings in a single call
GET/settings/transitionsGet transition animation settings and the built-in strategy list
PUT/settings/transitionsUpdate transition settings. strategy accepts a built-in name (column, reverse-column, edges-to-center, row, diagonal, random), "plugin:<id>" to drive a transition plugin, or null for no animation
GET/settings/outputGet output target settings
PUT/settings/outputUpdate output target
GET/settings/boardGet board configuration
PUT/settings/boardUpdate board configuration
GET/settings/temporary-overrideGet the current temporary override
POST/settings/temporary-overrideShow a saved page — or one-off content — until it expires or is cancelled
DELETE/settings/temporary-overrideCancel the override and apply its revert mode

Temporary Override​

A temporary override puts something on the board ahead of whatever the schedule or manual active page would show. It carries exactly one of:

  • page_id — a saved page or collection, or
  • template — one-off content that is never saved as a page.

A user-initiated override deliberately beats the silence schedule, so these endpoints are not blocked while a board is snoozing.

POST /settings/temporary-override — request body fields​

FieldTypeDescription
page_idstringSaved page or collection to show. Mutually exclusive with template
templatestring[]One-off board lines, never persisted as a page. Mutually exclusive with page_id
line_metadataobject[]Per-line { alignment, wrap } for the template form
device_typestringGeometry the one-off was composed for: "flagship", "note", or "note_array" (default "flagship")
notes_wide / notes_tallnumberNote-array grid dimensions for the template form
duration_minutesnumber1–480. Omit for an indefinite override that lasts until it is cancelled
revert_modestring"schedule" (default), "blank", or "page" — what happens when a timed override expires
revert_page_idstringRequired when revert_mode is "page"

remaining_seconds is null in the response both when no override is active and when the active override is indefinite. The same override block is embedded in GET /schedules/active/page so the dashboard needs no extra call.

Board Management​

Installs with more than one board follow a per-board model: each board has its own active page, schedule, and send routing, addressed by a board_id query param (or body field) on the relevant endpoints below. Omitting board_id always falls back to the primary board (boards[0]), which keeps single-board installs behaving exactly as before. Pages and Collections are not per-board — they're one shared library, and their pickers filter to the boards they're compatible with (see Board Instance Fields for the size model).

MethodEndpointDescription
PUT/settings/boardUpdate board configuration (devices, connection)
POST/settings/board/addAdd a new board instance
DELETE/settings/board/{id}Remove a board instance
GET/settings/active-pageGet a board's active page id (?board_id=)
PUT/settings/active-pageSet a board's active page (renders and sends immediately)
GET/silence-statusGet a board's silence schedule status (?board_id=)
PUT/settings/silence-scheduleSet a board's silence schedule (board_id in the body)
POST/pages/{id}/sendSend a page (?target=board&board_id=)
GET/board/current-messageRead a board's current display (?board_id=)

PUT /settings/board — request body fields​

FieldTypeDescription
boardsobject[]Array of BoardInstance objects (V2 format)
devicesstring[]Device type list e.g. ["flagship", "note"] (backward-compatible)
board_typestringLegacy field — still accepted

PUT /settings/active-page — request body fields​

FieldTypeDescription
page_idstring | nullPage (or collection) id to activate, or null to clear
board_idstringOptional. Omitted → primary board (legacy behavior)

PUT /settings/silence-schedule — request body fields​

FieldTypeDescription
enabledbooleanWhether silence is on for this board
start_timestringWindow start, UTC ISO (e.g. "04:00+00:00")
end_timestringWindow end, UTC ISO
modestring"freeze" (default), "indicator", or "page"
page_idstring | nullPage shown when mode is "page". Required in that mode, and validated against the target board's size
indicator_textstring | nullText shown when mode is "indicator". Trimmed and forced to uppercase; defaults to SNOOZING
indicator_positionstring | null"center" (default), "top-left", "top-right", "bottom-left", "bottom-right"
board_idstringOptional. Unknown board → 404. Note the exception below

Reads and writes here use board_id differently, on purpose:

  • PUT /settings/silence-schedule without board_id writes the install-wide schedule — the default every board without its own override resolves to. That is how an existing install keeps one set of quiet hours until you deliberately give a board its own, and how a board you add later inherits the install's quiet hours rather than staying loud. On an install with exactly one board there is no such distinction, so the write also drops that board's override rather than leaving it to shadow what you just saved.
  • GET /silence-status without board_id reports the primary board, like every other status and send guard. It answers "is silence on right now?", so it has to describe a board rather than a config layer. The response echoes the board it describes. To read the install-wide layer itself, use GET /settings/all → silence_schedule.config, which includes by_board.

With board_id, both resolve that board: its own entry wins key by key, and anything it does not define falls back to the install-wide values.

Board Instance Fields​

FieldTypeDescription
idstringUUID (auto-generated on create)
namestringDisplay name for this board
device_typestring"flagship" (22×6), "note" (15×3), or "note_array" (variable W×H)
board_colorstring"black" or "white"
api_modestring"local" or "cloud"
hoststringBoard IP address (local mode)
local_api_keystringLocal API key
cloud_keystringCloud Read/Write key
note_array_tokenstringCloud API token (note-array boards in cloud mode)
notes_wide / notes_tallnumberNote-array grid dimensions — resolves to (notes_wide × 15) × (notes_tall × 3) characters
enabledbooleanWhether this board is active
schedule_enabledbooleanWhether this board follows its schedule (vs. manual mode)
pausedbooleanWhether this board's output is paused

Transition Plugin Endpoints​

These endpoints back the Transition Lab and the transition pickers in the UI. They are gated behind the Transition Plugins beta flag (Settings → Advanced → Beta Features) and return 404 while it is off. See Transitions for the feature itself.

MethodEndpointDescription
GET/transitions/pluginsList installed transition plugins with their settings schema, runtime caps, and plugin:<id> strategy string
POST/transitions/previewRun a transition plugin in-process and return its frame sequence — nothing is sent to a board
POST/transitions/test-liveRun a transition plugin once on the real board
POST/transitions/restoreSnap a board back to its active page after a live test

POST /transitions/preview — request body fields​

FieldTypeDescription
plugin_idstringTransition plugin to drive (required)
to_textstringText rendered into the target grid
from_textstringOptional. Text rendered into the starting grid. Default: blank
configobjectOptional. Per-run overrides for the plugin's settings fields
device_typestringOptional. "flagship" (default), "note", or "note_array"
notes_wide / notes_tallnumberOptional. Note-array geometry (1–8 each)

The response is {"frames": [{"grid": [[...]], "delay_ms": n}, ...], "total_delay_ms": n, "capped": bool, "plugin_id": "..."}. capped is true when the plugin hit its max_frames or max_runtime_seconds limit and the sequence was truncated.

POST /transitions/test-live — request body fields​

FieldTypeDescription
plugin_idstringTransition plugin to drive (required)
to_page_idstringPage the transition lands on (required)
from_page_idstringOptional. Page snapped to the board first, so the transition visibly starts from it
configobjectOptional. Per-run overrides for the plugin's settings fields
board_idstringOptional. Omitted → primary board

Live tests respect silence mode and board pause, returning 409 rather than writing to a quiet or paused board. The board is left showing the target page — call POST /transitions/restore (body: optional board_id) to return it to its active page, or wait for the normal display loop.

Example Requests​

Get Service Status​

curl http://localhost:4420/api/status

Send a Message​

curl -X POST http://localhost:4420/api/send-message \
-H "Content-Type: application/json" \
-d '{"text": "Hello World!"}'

Message formatting: text longer than the board width is word-wrapped onto the following rows automatically, sized to your board's real geometry (6 rows × 22 columns on Flagship, 3 × 15 on Note). Width is counted in flaps, so a colour marker like {red} costs one tile, not five characters, and a word wider than the board is split across rows rather than cut off. A newline in the JSON body starts a new row, and wrapping fills within those explicit breaks. Lines beyond the board's row count are dropped (and logged).

Backslashes are never reinterpreted here — JSON can already carry a real newline, so {"text": "C:\\new"} renders C:\new verbatim. The \n-as-line-break shorthand exists only on the MQTT plain-string send_message payload, for single-line clients that cannot type a newline; see Home Assistant control.

List Plugins​

curl http://localhost:4420/api/plugins

Preview a Page​

curl -X POST http://localhost:4420/api/pages/1/preview

Interactive Documentation​

For a complete interactive API explorer with request/response schemas, visit:

http://localhost:4420/api/docs

This provides a Swagger UI where you can try out any endpoint directly in your browser.

Next Steps​