Feature Flags
Manage feature flags to control feature availability across the platform.
Overview
Feature flags let administrators globally enable or disable features without redeploying. They are used as kill-switches for platforms, widgets, integrations, features, bot modules, automation actions, copyright providers, event types, and system-level controls.
Managing Flags
Access feature flag management via Admin > Feature Flags (/feature-flags). The page renders:
- A search box filtering on label and key.
- An "{enabled} of {total} enabled" summary.
- One tab per category, each with an
enabled/totalbadge. Only categories that actually contain flags get a tab. - Inside a tab, one row per flag showing its label, its key in monospace, and a switch.
Toggling a switch immediately persists the change via PATCH /v1/admin/feature-flags/{id} (GraphQL adminUpdateFeatureFlag).
The switch is rendered behind a feature-flags:edit gate — admins holding only feature-flags:read see a plain On / Off label instead of a control. The API itself enforces features:edit on the write and features:read on the read, so an admin needs both feature-flags:edit (to see the switch) and features:edit (for the call to succeed).
Categories
The admin UI orders category tabs like this:
platformfeaturewidgetintegrationbot_moduleautomationcopyright_providereventsystem
Categories are derived from the flags actually returned, so a category with no flags gets no tab. automation, copyright_provider, and event are reserved category names in that ordering — no flag is seeded into them today.
Flag Reference
system category
System flags are admin-scope, user-scope flags that apply to the platform as a whole rather than to individual accounts.
| Key | Label | Description |
|---|---|---|
system:account_creation | Account Creation | Controls whether users may create new streaming accounts. When disabled globally, all users are blocked from creating accounts. Per-user overrides (see Users) can grant or deny individual users regardless of the global setting. |
system:copyright_public_directory | Public Copyright Directory | Kill-switch for the unauthenticated /music surface on the marketing site (landing page, song browser, playlists, detail pages, reports). When off, the /music link disappears from header + footer and every page under /music/* returns 404. Account-level copyright detection (feature:copyright_detection) is unaffected. |
system:copyright_public_quick_check | Public Copyright Quick Check | Narrower kill-switch for just the inline paste-a-URL quick-check widget on /music. The rest of the directory stays live when this is off. Typically used for rollout or to shed API load. |
system:ideas_hub | Ideas Hub | Master switch for the Ideas Hub, including the admin moderation surfaces. |
system:ideas_hub_public | Ideas Hub (Public) | Controls whether the Ideas Hub is reachable without authentication. |
feature:extension_development | Extension Development | Seeded in the system category despite the feature: key prefix. Gates the extension developer surfaces. |
feature category
Feature flags gate individual dashboard pages and major feature areas.
Turning a feature:* flag off — globally, per plan, or per account — removes the
sidebar entry and closes the route. Every page under the feature's URL prefix
(a deep link such as /dashboard/widgets/{id}/designer, not just
/dashboard/widgets) then renders the "feature unavailable" page naming the
layer that disabled it, and the API rejects the matching requests.
| Key | Label | Description |
|---|---|---|
feature:bots | Bot Control | Bot Control dashboard page |
feature:bot_modules | Bot Modules | Bot Modules configuration page |
feature:bot_commands | Bot Commands | Bot Commands management page |
feature:music | Music | Music feature (player page + popout, Spotify polling worker, track events, REST/GraphQL controls). Gates the entire music stack. The overlay widget and the {song} bot variable are gated separately by widget:spotify_now_playing. |
feature:connections | Connections | Connections page umbrella — disabling hides the entire Connections section |
feature:multichat | Multichat | Cross-platform combined chat |
feature:automation | Automation Engine | Automation builder and execution |
feature:copyright_detection | Copyright Detection | Account-level copyright detection |
feature:streamelements | StreamElements | StreamElements tip ingestion |
feature:obs_remote | OBS Remote | OBS WebSocket remote control feature — gates the OBS integration dashboard page and all OBS config endpoints |
feature:advanced_overlays | Advanced Overlays | Advanced overlay builder features (e.g. multi-plan-only widget library, custom CSS) |
feature:overlay_folders | Overlay Folders | Folder organisation in the overlay list |
feature:overlay_access | Overlay Access Control | Per-overlay access restrictions |
feature:overlay_sharing | Overlay Shared Links | Shared overlay links |
feature:custom_bot | Custom Bot Account | Allows the account to register a custom bot identity per platform instead of using the shared Lumio bot |
feature:multi_account | Multi-Account | Owning more than one streaming account |
feature:extensions | Extensions | The extension platform |
feature:extension_paid | Paid Extensions | Paid extension purchases |
feature:widgets | Widget Gallery | The widget gallery |
feature:sounds | Sound Uploads | Sound uploads for extensions |
Whether a flag is on for a given plan is a separate, per-plan decision made in the Plans Feature Grid — the flag here is the global kill-switch only.
widget category
Widget flags gate overlay widgets that render inside a broadcast overlay.
| Key | Label | Description |
|---|---|---|
widget:obs_browser_source | OBS Browser Source | OBS Browser Source widget — overlay element that renders in OBS via browser source |
widget:spotify_now_playing | Spotify Now Playing | Gates the Spotify Now Playing overlay widget and the {song} chat-bot variable (both surfaces that embed "now playing" data in a broadcast). Does not gate the music player, popout, worker, or API controls — those live behind feature:music. |
widget:chat_box | Chat Box | Chat Box overlay widget |
widget:event_list | Event List | Event List overlay widget |
widget:sub_goal | Sub Goal | Sub Goal overlay widget |
widget:viewer_count | Viewer Count | Viewer Count overlay widget |
widget:stream_uptime | Stream Uptime | Stream Uptime overlay widget |
integration category
Integration flags gate third-party tool integrations displayed in the Connections integrations modal.
| Key | Label | Description |
|---|---|---|
integration:shopify | Shopify | Shopify e-commerce integration. Shopify is registered as an integration-only platform, so it does not appear on the Providers page. |
integration:obs_websocket | OBS WebSocket | OBS WebSocket integration entry in the integrations modal — must be enabled for users to save or delete OBS connection settings |
integration:streamerbot | Streamer.bot | Streamer.bot integration |
platform category
One master flag per platform (platform:twitch, platform:youtube, platform:kick, platform:trovo, platform:discord, platform:spotify) plus :login / :channel / :bot sub-flags for the connection types each platform supports. These are what the Providers page toggles.
bot_module category
bot_module:link_protection, bot_module:spam_protection, bot_module:word_filter, bot_module:timed_messages, and feature:bot_module_extensions (seeded into the bot_module category despite the feature: key prefix).
Flag Taxonomy Rules
Use the correct category when adding new flags:
| Category | Use for |
|---|---|
feature:* | Dashboard pages and major feature areas |
widget:* | Overlay widgets only (things that render inside a broadcast overlay) |
integration:* | Third-party integrations in the integrations modal |
platform:{x} / platform:{x}:{type} | Streaming platforms (Twitch, YouTube, Kick, Trovo, Discord) — master switch + login/channel/bot sub-flags |
system:* | Admin-scope system switches with user-scope resolution (e.g., system:account_creation) |
bot_module:* | Individual bot moderation modules (link protection, spam protection, etc.) |
Resolution Chain
Flag resolution differs by scope:
Account-scope flags (feature:*, widget:*, integration:*, platform:*, bot_module:*):
GLOBAL_OFF— the flag is disabled globally (admin kill-switch). Stops here.PLAN_LOCKED— the flag requires a plan the account does not have.ACCOUNT_OVERRIDE— an explicit per-account override set by an admin.- Enabled (no reason set).
User-scope flags (system:account_creation):
USER_OVERRIDE— the user has an explicit per-user override (allowordeny). Stops here.GLOBAL_OFF— the global flag is disabled. Stops here.- Enabled (no reason set).
The reason field on FeatureStatus reflects the first layer that returned enabled=false. When a flag is enabled the reason field is null.
Permissions
feature-flags:read— the admin page and sidebar entryfeature-flags:edit— renders the toggle switch in the admin UIfeatures:read— the API read (adminFeatureFlags,adminFeatureFlagsDetail,GET /v1/admin/feature-flags)features:edit— the API write (adminUpdateFeatureFlag,adminUpdateFeatureFlagDetail,PATCH /v1/admin/feature-flags/{id})
An admin who is meant to flip flags needs feature-flags:read + feature-flags:edit for the UI and features:read + features:edit for the API calls behind it.
The dashboard entry itself is gated on admin:access. System admins (is_system: true) implicitly receive all admin permissions.
API
| UI action | GraphQL | REST |
|---|---|---|
| List flags | adminFeatureFlags | GET /v1/admin/feature-flags |
List flags with detail (description, default_for_accounts) | adminFeatureFlagsDetail | GET /v1/admin/feature-flags/detail |
| Toggle a flag | adminUpdateFeatureFlag | PATCH /v1/admin/feature-flags/{id} |
| Update flag detail | adminUpdateFeatureFlagDetail | PUT /v1/admin/feature-flags/{id}/detail |