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 }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
file | string | yes | Relative path in dist/sounds/. 1-255 characters. No .., \, or leading /. |
name | string | yes | Display name shown in the Sounds Panel. 1-255 characters. |
default_volume | number | no | Default 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:
- Per-extension override —
extensions.max_sounds(reasonextension_override) - Per-developer override —
developer_limit_overridesrow withlimit_key = 'max_sounds_per_extension'(reasondeveloper_override) - Default —
DEFAULT_MAX_SOUNDS_PER_EXTENSION = 50(reasondefault)
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
| Event | Behavior |
|---|---|
| Extension installed | Sound rows created in the user's library |
| Extension uninstalled | Sound rows removed from the library |
| Extension version updated | Sounds reconciled (old removed, new created) |
| User tries to delete bundled sound | Blocked with error message |
| User tries to rename bundled sound | Blocked 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
| Path | Description |
|---|---|
packages/extension-types/src/config.ts | Sound schema definition (lumioExtensionSoundSchema) |
apps/api/src/services/bundled_sounds.rs | Install/reconcile logic |
apps/api/src/db/developer_extensions.rs | resolve_max_sounds limit resolution |
packages/cli/src/commands/deploy.ts | CLI sound validation and limit check |