Skip to main content

Extension Sounds

Extensions can bundle audio files that are automatically added to the user's sound library when the extension is installed. Bundled sounds are managed by the extension developer — users cannot delete or rename them.

Declaring sounds

Add a sounds array to 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. No .., \, or leading /.
namestringyesDisplay name shown in the Sounds Panel. 1-255 characters.
default_volumenumbernoDefault playback volume, 0.0 to 1.0.

Supported formats

MP3, WAV, OGG, WebM, M4A, AAC, FLAC.

Place audio files in dist/sounds/ before running lumio deploy.

Limits

The sounds array in lumio.config.json is capped at 200 entries by the schema itself (packages/extension-types/src/config.ts) — a longer array fails config validation before any limit lookup happens.

The effective per-extension limit is resolved by resolve_max_sounds() in this order, first hit wins:

  1. Per-extension overrideextensions.max_sounds (reason extension_override)
  2. Per-developer overridedeveloper_limit_overrides row with limit_key = 'max_sounds_per_extension' (reason developer_override)
  3. DefaultDEFAULT_MAX_SOUNDS_PER_EXTENSION = 50 (reason default)

An admin-set override is validated to 0..=500.

Two further limits apply alongside the count: max_sound_file_size (per file) and max_sound_storage_bytes (total across the extension's sounds). The lumio deploy CLI pre-flights all three against the resolved values from the API and fails the deploy with a descriptive message before uploading. It also warns on any single sound file over 5 MB. Request a limit increase via the Developer Dashboard or contact support.

System extensions bypass all sound limits (skip_limits in bundled_sounds.rs).

Lifecycle

EventBehavior
Extension installedSound rows created in the user's library
Extension uninstalledSound rows removed from the library
Extension version updatedSounds reconciled (old removed, new created)
User tries to delete bundled soundBlocked with error message
User tries to rename bundled soundBlocked with error message

Bundled sounds do not count against the account's plan sound limit (e.g. Free plan max 10 sounds): a bundled row carries source_extension_id = {extension_id}, and the plan-limit queries filter on source_extension_id IS NULL.

How storage works

Sound files are uploaded once during lumio deploy to extension storage under {ext_id}/versions/{ver}/sounds/{file} (ExtensionStorageKeys::file_key). When a user installs the extension, the API creates database rows that reference these storage keys directly. No file duplication occurs — all installs share the same uploaded files.

Referencing sounds in config

Use a config field of type sound to let users select from their sound library (including bundled sounds):

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

The SchemaEditor renders a dropdown picker. The stored value is a sound ID (UUID string).

Key files

PathDescription
packages/extension-types/src/config.tsSound schema definition (lumioExtensionSoundSchema)
apps/api/src/services/bundled_sounds.rsInstall/reconcile logic
apps/api/src/db/developer_extensions.rsresolve_max_sounds limit resolution
packages/cli/src/commands/deploy.tsCLI sound validation and limit check