Skip to main content

Sounds

Overview

The Sounds module provides a per-account audio library. Sounds are uploaded once and can be played directly in browser sources without leaving the dashboard. Extensions can bundle their own sounds and reference them via config fields, and automations can trigger playback in response to stream events.

Sounds are stored in the account's library and played back via the sounds:{accountId} WebSocket channel. Browser sources subscribed to this channel receive sound:play and sound:stop commands and execute them locally, keeping audio latency minimal.

Upload limits

Upload limits are enforced per plan:

LimitFreeProEnterprise
Max sounds10100Configurable
Max sound file size2 MB10 MBConfigurable
Max total sound storage20 MB500 MBConfigurable

Supported audio formats: MP3, WAV, OGG, FLAC.

Playback in browser sources

Browser sources (layers) that subscribe to sounds:{accountId} receive real-time playback commands. When a sound is played from the dashboard or via automation, the server publishes a sound:play event to the channel and all subscribed browser sources execute the audio locally.

Playback commands include:

  • sound:play — start playing a specific sound at an optional volume (0.0–1.0).
  • sound:stop — stop playback of a specific sound.

Commands can be targeted to a specific overlay by key or broadcast to all connected browser sources.

Targeting

When triggering sound playback, you can either broadcast to all browser sources or send to a specific overlay:

  • All browser sources (default) — every browser source subscribed to the account's sounds channel receives the command.
  • Specific overlay — pass the overlay key as the target parameter. Only the browser source for that overlay executes the playback.

This is useful when you have multiple overlays (e.g. a gameplay overlay and a facecam overlay) and want sounds to play from one specific source.

RBAC

PermissionDescriptionOwnerAdminModViewer
sounds:readView the sound libraryxxxx
sounds:createUpload new soundsxx
sounds:editRename and update soundsxx
sounds:deleteDelete sounds from the libraryxx
sounds:playTrigger and stop sound playbackxxx

Extension-bundled sounds

Extensions can ship their own sounds in the dist/sounds/ directory. When an extension is installed, its bundled sounds are registered in the account's sound library and can be referenced in config fields of type sound.

The lumio deploy command automatically detects audio files placed in dist/sounds/ and includes them in the upload. Bundled sounds are scoped to the extension install — uninstalling the extension removes its sounds from the library.

Bundled sound behavior

  • Bundled sounds appear alongside user-uploaded sounds in the Sounds Panel
  • Users cannot delete or rename bundled sounds — they are controlled by the extension developer
  • Bundled sounds do not count against the account's plan sound limit
  • The Sounds Panel shows an extension badge on bundled sounds and provides a filter dropdown to show only sounds from a specific extension or only user-uploaded sounds
  • Installing or uninstalling an extension broadcasts a sound:list:updated event for live sync in the editor

Sound limits for extensions

Each extension has a configurable limit on how many sounds it can bundle. The limit resolves in priority order:

  1. Per-extension override — set by admin on the extension itself (extensions.max_sounds)
  2. Per-developer override — set by admin on the developer profile (developer_limit_overrides with key max_sounds_per_extension)
  3. Platform default — 50 sounds per extension

System extensions bypass all limits.

The lumio deploy CLI checks the resolved limit before uploading. The server validates the count again during the upload and at install time (defense in depth).

Declaring sounds in lumio.config.json

{
"sounds": [
{ "file": "alert.mp3", "name": "Alert" },
{ "file": "chime.wav", "name": "Chime", "default_volume": 0.8 }
]
}
FieldTypeRequiredDescription
filestringyesRelative path in dist/sounds/. 1-255 characters.
namestringyesDisplay name. 1-255 characters.
default_volumenumbernoDefault volume (0.0-1.0).

Supported formats: MP3, WAV, OGG, WebM, M4A, AAC, FLAC.

Referencing sounds in config

Use a config field of type sound to let users pick from the sound library:

{
"config_schema": [
{
"key": "alertSound",
"type": "sound",
"label": "Alert sound"
}
]
}

The SchemaEditor renders a dropdown picker listing all sounds in the account's library (including extension-bundled sounds). The stored value is a sound ID (UUID string).

API

GraphQL

OperationPermissionDescription
sounds(offset, limit, search)sounds:readList sounds with pagination and search
sound(id)sounds:readGet a single sound
updateSound(id, input)sounds:editRename a sound
deleteSound(id)sounds:deleteDelete a sound
playSound(id, volume, target)sounds:playTrigger playback
stopSound(id, target)sounds:playStop playback

See GraphQL for the full schema.

REST

MethodPathPermissionDescription
GET/v1/soundssounds:readList sounds
GET/v1/sounds/{id}sounds:readGet single sound
POST/v1/soundssounds:createUpload sound (multipart)
PATCH/v1/sounds/{id}sounds:editUpdate metadata
DELETE/v1/sounds/{id}sounds:deleteDelete sound
POST/v1/sounds/{id}/playsounds:playTrigger playback
POST/v1/sounds/{id}/stopsounds:playStop playback
GET/v1/sounds/{id}/streamsounds:readStream audio bytes

See REST API for request/response shapes.

WebSocket

Subscribe to sounds:{accountId} to receive real-time playback commands. Requires sounds:read permission and the feature:sounds flag.

See WebSocket for the channel protocol.

Key files

PathDescription
apps/api/src/routes/sounds.rsREST endpoints (list, get, upload, update, delete, play, stop, stream)
apps/api/src/graphql/sounds.rsGraphQL queries and mutations
apps/api/src/db/sounds.rsDatabase operations
apps/api/migrations/20260528000007_sounds.up.sqlSchema migration