Skip to content

Server API

Lumora exposes an HTTP API for triggering graphics from external tools. Stream Deck via Bitfocus Companion, automation scripts, vision-mixer macros, anything that can fire an HTTP request. Requests are authenticated with a long-lived API key minted from the control panel.

Client API

If you're running the Lumora Controller application on your Windows PC, you also have access to the Client API, documented here.

Authentication

Every /api/* endpoint requires an API key on the standard Authorization header:

http
Authorization: Bearer lumora_live_sk_<43 chars>

Keys are long-lived workspace credentials. Stream Deck, Companion, and CI scripts store one once and reuse it indefinitely.

Minting a key

  1. In the control panel, open SettingsAPI Keys.
  2. Give it a label (e.g. "Stream Deck") then click Create key
  3. The raw key is shown once. Copy it into your automation tool immediately, as you can't retrieve it again.

API keys are available on Standard, Professional, and Enterprise plans. The Free plan does not include API access. Paid plans can mint as many keys as needed.

Key format

PartLengthDetail
Prefix15 charslumora_live_sk_
Body43 charsBase64URL random
Total58 chars256 bits of entropy

Scope and safety

  • Keys can call any /api/* endpoint within the workspace they were minted in.
  • Keys only work against their own workspace. Using a key from one workspace against a different workspace's URL returns 403.
  • Keys cannot mint or revoke other keys. Only a signed-in human operator can manage keys via the modal.
  • A leaked key's blast radius is bounded to /api/* and can be cut off with one click from SettingsAPI KeysRevoke.
  • Treat keys like passwords: don't commit them to git, don't paste them in screenshots, don't share them between workspaces.

Endpoints

All endpoints are rooted at your workspace's origin, e.g. https://your-workspace.app.lumora.live.

GET Requests

EndpointDescription
/api/status/channelIdList all graphics currently live on a channel
Returns: { "live": [...] }
/api/status/channelId/graphicIdCheck if a specific graphic is currently live on a channel
Returns: { "live": true/false }
/api/tally/channelId/pgmReturns true if the channel is on program, false if not
/api/tally/channelId/pvwReturns true if the channel is on preview, false if not

POST Requests

EndpointDescription
/api/trigger/channelId/graphicId/onTake a graphic live on a channel
/api/trigger/channelId/graphicId/offTake a graphic off on a channel
/api/trigger/channelId/graphicId/action/actionNameFire a named action on a live graphic (e.g. Advance, Reset). The graphic must be live
/api/refresh-allRefresh all data sources (Google Sheets, etc.). Equivalent to pressing F9 in the control panel.

Parameters

NameWhere to find it
channelIdOutput channel ID, e.g. cg1. Found in OutputsConfigure Outputs.
graphicIdUnique graphic instance ID. Found in the graphic's Edit modal.
actionNameAction name as defined in the template, e.g. Advance. Case-sensitive.

Responses

Success

POST triggers and refresh-all return:

json
{ "ok": true }

GET /status/{channelId}/{graphicId} returns:

json
{ "live": true }

Error

json
{ "error": "Graphic not found" }

Status codes

CodeMeaning
200Success
401Missing or invalid token
403Workspace URL doesn't match API key
404Channel, graphic, or action not found
409Graphic is not live (action endpoints only)

Examples

Read channel status

bash
curl -H "Authorization: Bearer lumora_live_sk_<your key>" \
  https://your-workspace.app.lumora.live/api/status/cg1

Take a graphic on-air

bash
curl -X POST \
  -H "Authorization: Bearer lumora_live_sk_<your key>" \
  https://your-workspace.app.lumora.live/api/trigger/cg1/<graphicId>/on

Fire a custom action

bash
curl -X POST \
  -H "Authorization: Bearer lumora_live_sk_<your key>" \
  https://your-workspace.app.lumora.live/api/trigger/cg1/<graphicId>/action/Advance

Refresh all data sources

bash
curl -X POST \
  -H "Authorization: Bearer lumora_live_sk_<your key>" \
  https://your-workspace.app.lumora.live/api/refresh-all

Common integrations

There's no Lumora-specific plugin for any of these. They all drive the HTTP endpoints above directly. Configure each tool's generic HTTP action with your endpoint URL, set the method (GET or POST), and add the Authorization: Bearer ... header.

  • Stream Deck. Elgato's built-in HTTP Request action (or the Web Requests plugin on older firmware) fires a request per button press. One button per endpoint is the typical setup: a "take on" button and a "take off" button per graphic you control regularly.
  • Bitfocus Companion. Drop these endpoints into Companion's generic HTTP action; the Authorization header is set per-button or globally in connection config.
  • OBS / vMix macros. Most switchers can fire an HTTP POST as part of a macro; use the trigger endpoints with the relevant channelId / graphicId.
  • Custom scripts. Any language with an HTTP client works. The endpoints are stateless, so retry logic is straightforward.

Rate limits

API requests are rate-limited per workspace across two dimensions: a 60-second burst ceiling and a rolling 24-hour daily ceiling. Both apply on every request; whichever runs out first triggers a 429 Too Many Requests with a Retry-After header.

PlanBurst (per minute)Daily
Standard10010,000
Professional30030,000
EnterpriseSet per account, contact usSet per account, contact us

Stream Deck / Companion typical usage (a handful of triggers per minute) is well within these limits. They exist to protect the workspace from runaway scripts.

Every response carries the standard RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers so you can pace yourself without waiting for a 429.

Troubleshooting

401 Unauthorized. The Authorization header is missing, malformed, or the key has been revoked. Re-mint a key and update your automation tool. Check for accidental whitespace before/after the key when pasting.

404 Not Found. Usually the wrong channelId or graphicId. The channel ID is the short ID (e.g. cg1), not the channel name. The graphic ID is shown in the graphic's Edit modal, not in the graphic list.

409 Conflict on an action endpoint. The graphic isn't currently live on that channel. Custom actions can only fire while the graphic is on-air. Take it on first, then fire the action.

Triggers fire but nothing happens on-air. Check the channel matches an actually-mapped output. A trigger to a channel with no output bound will return 200 but produce no visible result.