Appearance
Data sources
A data source lets graphics pull values from a spreadsheet or remote file rather than having every value typed by hand into the control form. Useful for fixtures, scoreboards, lineups, and anything else that lives in a sheet you're already maintaining.
Subscription tier limits
Data sources are a paid-tier feature. The number of sources you can configure per workspace, and how often they're polled for changes, varies by plan. See Subscription plans for the current limits. The Free tier doesn't include data sources at all.
Adding a data source
In the control panel navbar, click Configure Data Sources. Once the workspace has a spreadsheet-type source, that button becomes a Refresh Data Sources button with a settings cog next to it. Click the cog to get back to the configuration modal. The modal lists every source attached to the current workspace and lets you add new ones.
What you can connect depends on whether you're driving Lumora from a browser or from the desktop controller app:
From any browser
- Google Sheets
- Remote
.csvfiles via URL - Remote
.jsonfiles via URL
From the desktop controller app (additional)
- Local
.csvfiles - Local
.jsonfiles - Local Excel
.xlsxfiles
Local-file sources only work in the desktop controller because the browser sandbox can't read your filesystem directly. The controller only reads files you pick with Browse…, from your Documents, Desktop or Downloads folder, up to 5 MB. See The desktop Controller.
Refreshing data sources
Sources with Auto-refresh turned on are re-fetched at their polling interval. To refresh everything now, any of these does the same thing:
- click Refresh Data Sources in the navbar,
- press F9,
- call
POST /api/v1/refresh-allfrom Stream Deck, Companion or a script.
Every open control panel on the workspace shows the refresh while it runs, then the result for a few seconds: Updated ✓, N Failed ⚠ when some sources failed, or Failed ✗ when all of them did. Hover the button to see which sources failed and why. To refresh a single source, use the ↺ button on its row in the configuration modal.
If a source's last refresh failed, whether it was a manual refresh, an automatic poll, or an API call, a red dot appears on the settings cog. Open the modal to see the error under that source's row. The dot clears as soon as the source refreshes successfully.
If a source keeps failing for more than about 15 seconds, a warning also appears in the Status tab of the status panel, naming the source and the reason, and the collapsed panel tab shows a warning marker. A failure that recovers within those 15 seconds (a single dropped request, for example) never reaches the panel, so it stays quiet mid-show. The warning clears on its own once the source refreshes successfully. You can dismiss it if you already know about the problem; it comes back only if the source recovers and then fails again.
Local files (Excel, and CSV/JSON in local-file mode) are read by the desktop controller app on the computer that has the file. Every refresh (from any control panel, browser or desktop, or from the API) asks each open desktop controller app to re-read its files, and waits a few seconds for them. A local file that no desktop controller app re-reads during the refresh counts as failed (the app is closed, signed out, showing a different workspace, or the file has moved); its last received data stays in use.
Data API sources are push-only, so they aren't part of a refresh: their row shows when the last push arrived.
Google Sheets: a range is required
Every Google Sheets source must specify a cell range in A1 notation, including the tab name, for example Sheet1!A1:D10. The range is mandatory; you can't save a Google Sheets source without one.
Only the cells inside that range are fetched, rather than the entire spreadsheet. This keeps each refresh small and fast, and means a Sheets source comfortably stays within the size limit. Choose a range that covers the cells your graphics read. There's no harm in leaving room to grow (for example Sheet1!A1:Z200).
When you bind a graphic field to a cell, the picker grid shows that range using your sheet's own column letters and row numbers. Importing Sheet1!C5:F20, for example, shows columns C–F and rows 5–20, so the address you pick matches what you see in Google Sheets.
Pulling from more than one tab
A range targets a single tab, by design. To bring in data from multiple tabs, either:
- Consolidate the data you need into one range on a single tab (for example with cell references or
IMPORTRANGE), and point the source at that range; or - Add a separate Google Sheets data source for each tab, each with its own range.
How JSON is interpreted
Lumora expects an array of objects as the canonical JSON shape, where each object becomes a row and the object's keys become the columns:
json
[
{ "name": "Team A", "score": 3 },
{ "name": "Team B", "score": 2 }
]Other JSON shapes (a top-level object, nested arrays, mixed types) are converted on a best-effort basis. If a graphic isn't picking up the values you expect, normalising the source to the array-of-objects shape is the most reliable fix.
Size limits
Each data source has a maximum size per fetch or push. Sources over the limit are rejected with a clear error, and the previously fetched values keep serving your graphics.
| Source | Limit |
|---|---|
| Google Sheets | 5 MB per fetch |
Remote .csv / .json via URL | 5 MB per fetch |
Local .xlsx / .csv / .json (desktop controller) | 5 MB per push |
| Data API push | 1 MB per push |
For reference, a large esports control sheet is typically well under 1 MB, so these limits leave generous headroom. If you hit a limit, trim the sheet to the rows and columns the graphics actually use, or split it across multiple sources.
Linking a control form field to a data source cell
Once a data source is configured, you can bind any field on the graphic control form to a specific cell.
- Select the graphic in the rundown.
- On the control form, click the blue data link icon next to the field you want to bind.
- In the picker, choose the data source, then the cell.
- Click Link to cell.
The field now reflects the cell's current value, and updates whenever the data source is refreshed (manually via Refresh Data Sources, or automatically at the polling interval set by your subscription tier).
To unbind a field, click the data-link icon again and remove the binding.
Fields that expect a particular kind of value
Every field on the control form can be linked, including dropdowns, colours, teams, players, countdowns and JSON fields. These fields only work with certain values, so Lumora checks each value a data source sends them:
| Field | Accepted values | What the graphic receives |
|---|---|---|
| Dropdown (incl. Yes/No) | One of the dropdown's values, or its label (not case-sensitive). A cell's 1 or true matches a 1 or Yes option | The option's value |
| Colour | #rgb or #rrggbb, any case | Lowercase #rrggbb |
| Team | A team's name, or its tricode (not case-sensitive), from your workspace roster | The team's name as written in the roster |
| Player | A player's name (not case-sensitive) from your workspace roster | The player's name as written in the roster |
| Countdown target | A date and time, such as 2026-10-16T20:00 | The value as sent |
| Countdown duration | SS, MM:SS or HH:MM:SS | Normalised to MM:SS (or HH:MM:SS) |
| JSON | Valid JSON in the cell (a Data API value is already JSON, so any value works) | The parsed value |
| List of text values | A JSON array of strings in the cell, such as ["One","Two"] | The array |
An empty cell clears the field. Text, number and image fields take any value, as before.
When a field can't use a value, Lumora rejects it for that field only:
- The field keeps showing its last valid value, on the control form and on air.
- Its data-link icon turns amber. Hover it to see the rejected value and why.
- The Status Panel shows one warning per data source, listing every field that rejected a value. You can dismiss it.
- Every other field linked to the same cell keeps updating normally, and the data source itself is not marked as failing.
The field picks up the next value it can use automatically. Adding a missing team or player to the roster also fixes the field straight away, with no edit to the sheet. When you pick a cell, the picker warns you if its current value would be rejected, but you can still link it.
See also
For programmatic access, such as pushing live JSON to a workspace from your own system, see the Data API.