Permissions
Extensions that need to trigger Lumio actions (send chat messages, control OBS scenes, emit events) must declare the required permissions in lumio.config.json.
Declaring permissions
{
"permissions": ["chat:send", "obs:set_scene"]
}
Declared permissions are shown to users in the install dialog, together with your egress hosts. Users confirm them by installing (see User consent).
Lumio's own system extensions use the same manifest permission checks. The built-in Chat Box declares chat:read; Alert Box and Event List declare events:read and sounds:play; Spotify Now Playing declares events:read. Link Protection, Spam Protection and Word Filter declare chat:read and the action permissions chat:delete, chat:timeout, chat:ban and chat:send for their moderation decisions. Timed Messages declares chat:read and chat:send. Text, Image, Timer and Browser Source declare none. System identity does not grant an undeclared permission.
Available permissions
| Permission | Action | Notes |
|---|---|---|
"chat:send" | Send a message to the platform chat | Sent by the bot that serves the account's chat (on Twitch, the Lumio bot) |
"chat:read" | Receive chat messages it was not addressed with | In a bot module, keyword, pattern and moderation triggers run only with this permission; without it Lumio drops them and the module never sees those messages. Commands are addressed to the module by name and run without it. In a widget or layer, useLumioEvent() receives chat:message, twitch:chat, youtube:chat, kick:chat, twitch:ban and twitch:unban only with this permission |
"events:read" | Receive platform events (follows, subs, raids, Spotify, …) | In a bot module, event() handlers receive events only with this permission; without it nothing listed in triggers.events is delivered. In a widget or layer, useLumioEvent() receives every non-chat event type only with this permission (useLumioEvent) |
"chat:delete" | Delete a chat message by ID | Runs as the account's own bot, which must be a channel moderator (Twitch, YouTube). Enhanced review. |
"chat:ban" | Ban a user | Runs as the account's own bot, which must be a channel moderator (Twitch, YouTube). Enhanced review. |
"chat:unban" | Lift a ban | Runs as the account's own bot, which must be a channel moderator (Twitch). Enhanced review. |
"chat:timeout" | Time out a user | Runs as the account's own bot, which must be a channel moderator (Twitch, YouTube). Enhanced review. |
"obs:set_scene" | Switch the active OBS scene | Requires OBS WebSocket to be connected |
"obs:set_source_visible" | Show or hide an OBS source | Requires OBS WebSocket to be connected |
"obs:start_stream" | Start the OBS stream | Requires OBS WebSocket to be connected |
"obs:stop_stream" | Stop the OBS stream | Requires OBS WebSocket to be connected |
"obs:start_recording" | Start the OBS recording | Requires OBS WebSocket to be connected |
"obs:stop_recording" | Stop the OBS recording | Requires OBS WebSocket to be connected |
"spotify:play" | Resume playback or play a track | Requires a connected Spotify account |
"spotify:pause" | Pause playback | Requires a connected Spotify account |
"spotify:skip" | Skip to the next track | Requires a connected Spotify account |
"spotify:seek" | Seek within the current track | Requires a connected Spotify account |
"spotify:volume" | Set the player volume | Requires a connected Spotify account |
"spotify:shuffle" | Turn shuffle on or off | Requires a connected Spotify account |
"spotify:repeat" | Set the repeat mode | Requires a connected Spotify account |
"spotify:queue_add" | Add a track to the queue | Requires a connected Spotify account |
"events:emit" | Emit a custom Lumio event | Triggers automations and other extensions listening for this event |
"overlay:update_layer" | Toggle the visibility of another overlay layer | Must be on the same overlay |
"sounds:play" | Play, stop and list sounds of the account's sound library with useLumioSound | The sound plays only in the overlay, widget or dashboard preview that renders the extension, never on the account's other overlays. Listing works only in the dashboard. Not a useLumioAction() action |
Using permissions
Request the permission with useLumioAction() in your extension:
import { useLumioAction, Button } from "@zaflun/lumio-sdk";
function SendChatButton() {
const { execute: sendChat, isLoading } = useLumioAction("chat:send");
return (
<Button
label="Send to chat"
onClick={() => sendChat({ platform: "twitch", message: "Game is starting!" })}
disabled={isLoading}
/>
);
}
The permission you declare is exactly the string you pass to useLumioAction() - each action maps to its own granular permission, and there are no coarse capability groupings (e.g. there is no obs:control that unlocks every OBS action; declare obs:set_scene to switch scenes, obs:start_stream to start the stream, and so on).
If the permission is not declared in lumio.config.json, the action call is rejected at runtime with a permission error. The action also needs the plan feature of the service it drives (feature:music for Spotify, feature:obs_remote for OBS, feature:multichat for chat); see useLumioAction. Chat actions run as the account's bot; see useLumioAction → Chat for the platform matrix and error codes.
Who calls the action
The manifest permission is the only check when the call comes from the extension itself (its extension token, or the overlay or widget token of the OBS URL that renders it). When a signed-in member or a personal API key calls the action, an extension must not let that member do more than the dashboard lets them do. The caller then also needs extension-store:configure and the member permission the matching dashboard operation checks. A missing one is refused with Missing permission: <permission>:
| Action | Caller also needs |
|---|---|
chat:send | chat:write |
chat:delete | chat:delete |
chat:ban, chat:unban | chat:ban |
chat:timeout | chat:timeout |
obs:* | obs:edit |
spotify:play, pause, skip, seek, shuffle, repeat | spotify:playback |
spotify:volume | spotify:playback and spotify:volume |
spotify:queue_add | spotify:queue |
events:emit | events:create |
overlay:update_layer | overlays:edit |
Admin review
Permissions are reviewed during the extension approval process. Reviewers check:
- Does the declared permission match the extension's stated purpose?
- Does the code actually use the declared permission?
- Are any undeclared permissions used in the code?
Extensions that declare permissions they do not use, or use permissions they did not declare, are rejected.
Enhanced review
Permissions marked with Enhanced review (chat:ban, chat:delete) trigger additional manual code review during the store approval process. Reviewers verify that moderation logic is sound and cannot be exploited for mass-banning or mass-deletion. Extensions requesting these permissions may take longer to approve.
User consent
When a user installs an extension, the store's install dialog lists what the version they receive declares:
- The data it receives from their channel (
chat:read,events:read) and every other permission as a plain-language action - The hosts in
egress.allowHosts, marked as servers you run, not Lumio, with a link to the privacy policy section on extensions from other developers - The user confirms with Allow and install
The dialog reads the latest published version, so a new permission or egress host is shown to anyone who installs after you publish it. A user withdraws consent by uninstalling the extension; there is no per-permission revoke.
Future permissions
Additional permissions will be added as new Lumio actions are introduced. Check this page for updates. Custom permissions (for inter-extension communication via events:emit) use the standard events:emit permission with a custom event type.