Configuration
The odio installer generates ~/.config/odio-api/config.yaml automatically. The configuration shown below documents all available options — you only need to edit the file if you want to customize the defaults.
For standalone installations, the config file can also be specified with --config <path>.
Minimal config
Section titled “Minimal config”bind: lologLevel: info
api: enabled: true port: 8018 ui: enabled: true cors: origins: ["https://pwa.odio.love", "https://odio-pwa.vercel.app"]api.cors.origins lists the origins allowed to call the API from a browser. The defaults cover the hosted odio application; add your own origin here if you self-host it on a different address.
Network binding
Section titled “Network binding”bind controls which network interfaces the API listens on.
bind: lo # loopback only (default)# bind: enp2s0 # single LAN interface# bind: [lo, enp2s0] # loopback + LAN# bind: [lo, enp2s0, wlan0] # loopback + ethernet + wifi# bind: all # all interfaces (Docker, remote access)Backend configuration
Section titled “Backend configuration”Each backend can be enabled or disabled independently. Disabling a backend removes all its routes from the API.
Systemd (opt-in, whitelist required)
Section titled “Systemd (opt-in, whitelist required)”See Systemd for endpoint details.
systemd: enabled: true timeout: 90s system: - bluetooth.service user: - mpd.service - shairport-sync.service - snapclient.service - spotifyd.service - upmpdcli.serviceBluetooth
Section titled “Bluetooth”See Bluetooth for endpoint details.
bluetooth: enabled: true timeout: 5s pairingTimeout: 60s idleTimeout: 30mSystem setup
Section titled “System setup”Since odio doesn’t run as root, a few system configuration steps are required.
The user running odio must belong to the bluetooth group:
sudo usermod -a -G bluetooth <username>PulseAudio or PipeWire must be configured to handle Bluetooth audio:
# PulseAudiosudo apt install pulseaudio-module-bluetooth
# PipeWiresudo apt install libspa-0.2-bluetoothBlueZ configuration
Section titled “BlueZ configuration”Edit /etc/bluetooth/main.conf to identify the node as an audio receiver:
[General]Name = odioClass = 0x240428
[Policy]AutoEnable=falseClass of Device (0x240428) breakdown:
0x24— Major Device Class: Audio/Video0x0428— Minor + services: Audio Sink, Loudspeaker, Rendering device
This makes the node appear as a standard Bluetooth speaker. Phones and computers will show a headphone icon and route media audio to it.
AutoEnable=false keeps the adapter off at boot — power is managed by the API (or Home Assistant).
After modifying the configuration, restart the Bluetooth service:
sudo systemctl restart bluetoothmpris-proxy
Section titled “mpris-proxy”BlueZ provides mpris-proxy, a systemd user service that creates an MPRIS player for each connected Bluetooth device. This is what allows the odio API to discover and control Bluetooth playback alongside all other sources.
systemctl --user status mpris-proxy.servicePower management
Section titled “Power management”See Power for endpoint details.
power: enabled: true capabilities: poweroff: true reboot: truePolkit rule
Section titled “Polkit rule”On headless systems, logind requires a polkit rule to allow the odio user to reboot and power off without a graphical session:
/etc/polkit-1/rules.d/10-allow-shutdown.rulespolkit.addRule(function(action, subject) { if ((action.id == "org.freedesktop.login1.power-off" || action.id == "org.freedesktop.login1.power-off-multiple-sessions" || action.id == "org.freedesktop.login1.reboot" || action.id == "org.freedesktop.login1.reboot-multiple-sessions") && subject.user == "odio") { return polkit.Result.YES; }});On desktop systems with a graphical session, this rule is not needed — logind already grants these permissions.
Zeroconf / mDNS
Section titled “Zeroconf / mDNS”See Zeroconf for details. Requires bind to be set to a real network interface.
bind: enp2s0zeroconf: enabled: true