Tokens
Generate popout tokens for browser sources, dashboards, and other unattended views that need access to your channel without a logged-in browser session. Open Settings, select the channel, then choose Access → Popout Tokens (/dashboard/settings/channel/tokens). A token link is a secret: treat it like a password. API keys authenticate programmatic API calls; popout tokens authenticate popout views such as OBS browser sources.
What Are Popout Tokens?
Popout tokens (prefix lm_pop_) are secret strings that authenticate a single URL without your browser cookies. By default they never expire, but you can optionally set an expiry time or revoke a token at any point (see Token Management). They are designed for:
- Browser sources - drop a URL with
?token=lm_pop_…into OBS, no login UI required - Stream-deck buttons - open a popout view directly to a control surface
- Shared dashboards - give a moderator read-only access to a single view
- Remote control overlays - receive live events on another machine
Creating a Token
Creating a token opens a full-screen wizard over the settings window with three steps. Choose New Token in Access → Popout Tokens to start:
- Identity - optionally enter a label (only for your reference) and choose who the token belongs to. Leaving the assignment on Yourself binds the token to you; pick a member to attribute its actions to that user instead. Every token is always bound to someone - removing a member assignment later binds the token to you, the person editing it. The step names whose Cockpit the token can edit: a token edits the Cockpit of the user it is bound to (layout and Cockpit presets) - "your Cockpit" for a token bound to you, otherwise the member's name. You can only pick a member whose role has no permission you lack yourself, so only someone holding every permission can assign a token to the account owner.
- Permissions - tick the permissions the token may use (e.g.
events:read,events:create,events:userinfo,overlays:read,spotify:read,spotify:playback,chat:read,chat:write,chat:userinfo,chat:ban,chat:timeout,chat:delete,chat:notes,obs:read,obs:edit). Ticking either OBS permission shows a warning: withobs:readthe popout receives your OBS WebSocket password so it can connect to OBS directly, so give such a token only to people you trust with OBS. Thechat:userinfo/events:userinfoscopes are what let a popout open the user info card when you click a name (profile, follow status, moderation log); leave them unticked for a display-only browser source. You can only select permissions you hold yourself - ones outside your own access are shown disabled. At least one permission is required before you can continue. - Lifetime - choose when the token expires (see Token lifetime below). The default is Never.
Click Create token on the last step, then copy the full token immediately - the secret is shown only once on the final screen. That screen has no close (✕); press Done when you have copied the token.
A token can never grant more permissions than the user who creates or edits it. This is enforced on both the create and the edit path (identically on the GraphQL and REST APIs): if you request a permission you do not currently hold, the request is rejected. If the member a token is assigned to loses a permission later, the token stops using it on the next request; it works again if the member gets the permission back. When you edit such a token, the wizard marks each stored permission that is not in effect right now and names the member whose role lacks it.
Using a Token
Append the token as a ?token= query parameter to any URL that supports popout authentication:
https://lumio.vision/popout/events?token=lm_pop_xxxxxxxxxxxx
On the first load, the raw token in the URL is exchanged once, server-side, for a short-lived popout session (a 15-minute httpOnly cookie), and the page redirects to the token-less URL. From then on the raw token no longer appears in the address bar, the WebSocket URL, or any network request - WebSocket subscriptions, REST proxy calls, and SSR data all authenticate through the session cookie. The session is refreshed transparently for as long as the token stays valid, so a browser source can stay open indefinitely.
You still only pass the token once in the URL. Saved URLs keep working: an existing OBS browser source whose stored URL contains ?token=lm_pop_… is exchanged automatically on load - no setup breaks.
Where Popout Tokens Work
Lumio exposes seven popout pages plus the overlay route. Popouts live on the dashboard host (lumio.vision) and accept ?token= for popout-token auth. Overlays live on their own host (overlay.lumio.vision) and carry their own access token, which is not a popout token - you get the complete URL from Copy Link on the overlay card.
| URL | Host | What it shows | Recommended permissions |
|---|---|---|---|
/popout/events | lumio.vision | Live event feed (followers, subs, cheers, raids, redemptions, tips) with channel-status indicator | events:read (+ events:userinfo to open the user info card from event rows) |
/popout/test-events | lumio.vision | Test-event catalog and sending confirmation, usable as an OBS dock from 320 px width | events:create (required to show the catalog and send) |
/popout/chat | lumio.vision | Unified multi-platform chat view with moderation actions | chat:read (+ chat:write to send, chat:ban/chat:timeout/chat:delete to moderate, chat:userinfo to open the user info card from chat rows) |
/popout/music | lumio.vision | Spotify "now playing" widget with playback controls | spotify:read and connections:read for channel status (+ spotify:playback to control playback) |
/popout/obs | lumio.vision | OBS Remote control panel (scenes, stream/recording state) | obs:read (+ obs:edit to switch scenes and control audio) |
/popout/chatters | lumio.vision | The viewer list as its own window or OBS dock | chat:read |
/popout/cockpit | lumio.vision | The whole Cockpit with its preset choice, settings and every module (see below) | the permissions of the modules you want to see; a module without its right names what is missing |
/overlay/\{key\} | overlay.lumio.vision | Any overlay, rendered as a browser source | none - the overlay's own access token is already in the URL |
/overlay/\{key\}/preview | overlay.lumio.vision | Preview of an overlay inside the dashboard | same as above |
A token window and an OBS dock with a token show the channel's 7TV, BTTV and FFZ emotes in chat and events (/popout/chat, /popout/events, /popout/cockpit) like the dashboard: chat:read or events:read is enough, no connection permission needed.
Overlays are intentionally separate: each one has its own access token, minted for the overlay rather than for a person, and revocable on its own from the overlay's menu. Loading /overlay/\{key\} without that token returns "403 - Access token required". See Overlays.
Without a usable sign-in. Every popout (/popout/cockpit, /chat, /events, /music, /obs, /test-events, /chatters) shows the same notice instead of its module when the window has no sign-in or popout session, when the sign-in has expired, or when the popout token behind the window was revoked: Sign in, with a hint for adding a popout token as ?token= to the address. Signing in returns to the same address. When Lumio's server cannot be reached, the window shows the connection notice with Try again. A signed-in window or a token window that only lacks a permission keeps its own notice naming that permission. If the window is signed in but still cannot load your channel (for example because your role has none of the permissions it needs), it says so with Try again instead of reloading.
Every single popout (/popout/chat, /events, /music, /obs, /test-events, /chatters) has a slim window bar on top, like the Cockpit popout: the Lumio logo, the module's name, the channel switch ▾, the preset choice ▾ for chat, events and music, and the settings cog. In the chat and events popouts the bar is part of the header: with Show Header off there is no bar, and the cog sits in the input row or search bar, or floats in a corner, where it always sat. The cog opens the module's settings - the Cockpit's settings page with only that module's areas plus Window & account. OBS control and test events have no settings of their own: their cog opens Window & account straight away, the OBS one with a link to where its connection is set up (Settings → Connections → Services). On a plan without presets the bar has no preset choice and the settings no Presets area. The channel switch appears only when you are signed in and belong to more than one channel; it is hidden with one channel and in a window opened with a popout token (a token window cannot switch). Choosing a channel there works like Window & account → Account: the window, the dashboard and every other open popout of the browser reload on the new channel (in OBS: every dock of that OBS), and a failed switch keeps the current one with a message. With Show Header off it goes with the bar; Window & account keeps the switch. A popout keeps its own display settings and presets: changing a Cockpit tile never changes a popout, and changing a popout never changes a Cockpit tile.
A narrow bar. The window bars of the single popouts and of /popout/cockpit make room by the width of the bar itself, not of the screen, in this order: first the channel switch shows only the channel's picture and ▾; then the preset choice shows only its symbol and ▾ (the preset's name stays in its menu, its tooltip and for screen readers); then the module's symbol and name (Chat, Events, Cockpit …) are hidden - the window title still names the module; last, only when even that does not fit, the channel switch leaves the bar - switch the channel under the cog in Window & account. The Lumio logo and the buttons on the right (screen lock, Streamer Mode, the token chip, Edit, the cog) always stay. As the bar gets wider again, the parts come back in the reverse order. Nothing in the bar wraps onto a second line, down to a 320 px wide window or dock.
The Test-Events popout uses the same searchable catalog as the dashboard side sheet. A popout link must carry events:create in its own permission list. If it does not, the page says This popout link is missing a permission and sends nothing. A signed-in browser uses the current user's permissions; when that user's role lacks the permission, the page says Your role is missing a permission and asks them to have the channel owner add it to their role. Tests appear in overlays and dashboard activity, not in the Events popout or stored history. The dashboard Popouts ▾ menu opens or copies the token-free page URL; create the token under Tokens for a delegated OBS dock.
The Cockpit popout
/popout/cockpit is the whole Cockpit in a window of its own or as an OBS dock. Open it from Popout ▾ in the Cockpit bar (Open in a new window, Copy link, Set up as OBS dock…) or from Popouts ▾ on the dashboard home. Links never carry a token, only the preset (?preset=…), so each dock can start with its own preset.
The Cockpit has no built-in preset templates. Its only built-in starting point is Without preset: it is live (every change applies at once), does not count toward the preset quota, and a window without a stored layout starts with chat and events side by side (chat above events up to 767 px wide), with Test Events as a tab behind Events; OBS, Music and the viewer list wait under Not in layout. Every further preset is one you create yourself. Without preset has Reset instead of Delete - on its card in Layout & Presets and, while it is active, as Reset "Without preset"… in the preset menu of the bar. After a confirmation its layout and display settings go back to the start in every window without a preset (dashboard, other tabs, popouts and docks); your own presets stay unchanged. A popout token resets the Cockpit of its bound member, like any other change there.
Hand a Cockpit preset to someone else with Share on its card in Layout & Presets: Copy code, Copy link or Download file under Hand on gives them a copy, also in another channel - only you can change your original. In the channel makes the original visible to every member. To take one in, use Import preset… in Layout & Presets (a file or a code), or open the link: you see the name, the layout, the modules and the displays, give it a name and Save as new preset. It counts toward your preset quota; nothing is overwritten. Details: Setting Presets → Cockpit presets.
In an OBS dock your sign-in is enough. Paste the copied link under Docks → Custom Browser Docks and sign in once in the dock; you keep all your rights, editing included. Every dock in OBS shares that sign-in, so signing out there signs out every dock. A popout token is the alternative for someone else's PC or for a dock with only some rights.
With a popout token the bar shows a chip Token · {name}: the token edits the Cockpit of that member - its layout and Cockpit presets - not the Cockpit of whoever sits in front of the dock. Only Token appears when the browser is also signed in as that same member. Hover or tap the chip for the explanation and Set up the dock with a sign-in, which opens the guide with a link without a token (a dock that once opened a token link keeps using the token even after a sign-in). Sharing a Cockpit preset, region and language, switching account and signing out need a sign-in; importing a Cockpit preset works with the token.
Browser Source Setup
- Create the popout token with the permissions you need (for
/popout/eventsyou only needevents:read) and copy the secret on the final screen - it is never shown again - Build the URL yourself: take the popout page you want and append
?token=plus the secret, e.g.https://lumio.vision/popout/events?token=lm_pop_… - In OBS: Add → Browser, paste the URL
- Width/height: 400×600 for chat, 600×120 for music, 500×400 for events, or at least 320 px wide for the Test-Events dock (rule of thumb)
- Custom CSS (optional):
body { background: transparent; }if the popout doesn't already render transparent - Optional: during a season the popout wears the seasonal look of the token's user. Append
&season=off,&seasonStrength=subtle(colours only) or&seasonMotion=off(no animations) to change it for this URL only - the final screen of the wizard lists these parameters next to the token
Token Management
The list groups tokens into Active, Expiring soon, and Revoked & expired. The last group starts collapsed; expand it to inspect or restore a revoked token. Open a token row to see permissions grouped by category, its assigned member, prefix and usage dates, then use its edit, revoke or delete actions. Rows stack their details on a phone or narrow window.
Each token in Settings → Channel → Access → Popout Tokens shows an always-visible status line - Never expires, Expires on {date}, Expired on {date}, or Revoked on {date} - alongside a badge that flags a token that is Expired, Revoked, or Expiring soon (within 7 days of its expiry). Each card also shows the assigned member - or Unknown member when your role cannot resolve member names (members:read) - plus when the token was created and last used. Clicking the pencil icon opens the token in the same three-step wizard, where you can jump straight to any step:
- Edit - change label, assigned member, or permissions any time; Save is available on every step and only submits the fields you actually changed.
- Set an expiry - on the Lifetime step, pick a preset or a custom date (see Token lifetime); the token stops working automatically after that moment. Choose Never to make the token non-expiring again. An already-expired token can be pushed back into the future here - its status updates accordingly.
- Revoke - on the Lifetime step, mark the token revoked without deleting it; all popout URLs using it stop working immediately. A revoked token can be restored later from the same step (its secret stays valid).
- Delete - permanently remove the token (the trash icon on the card). Unlike revoke, a deleted token cannot be restored; deletion is confirmed in a separate dialog.
Token lifetime
The Lifetime step offers presets - In 7 days, In 30 days, In 90 days, In 1 year, Never, and Custom date - with Never as the default. A finite preset expires at the end of that day in your browser's timezone (not at an arbitrary minute), and Custom date opens a date picker for any future day. Only the resulting absolute moment is stored, never a relative "7 days" rule, so the expiry does not shift if you edit the token later. When creating a token you cannot pick a date in the past; when editing, a back-dated expiry is allowed and acts as a soft-revoke.
Expiry and revocation are enforced on every request by the backend resolver - for both the raw popout token and the short-lived session it is exchanged for on load (the OBS session cookie). An expired or revoked token is rejected exactly like an invalid one, without disclosing which state it is in. A popout that is already open notices within about 30 seconds: its live connection is checked again and closed once the token is revoked, expired or deleted.
Assigned member leaves - a token assigned to a member stops working once that member is no longer part of the account. When you remove the member (or they leave), the tokens assigned to them are deleted, and any of their popouts that are still open close within about 30 seconds. Tokens bound to other members are not affected.
Audit - actions performed via a popout token are attributed in the audit log to the member the token is bound to (the creator, unless you picked someone else).
Security Notes
- A popout token is a bearer credential - anyone with the URL has the same access. Treat it like a password.
- On load the raw token is swapped for a short-lived session cookie and dropped from the live URL and WebSocket URL, so it no longer lingers where a screen share or proxy log can catch it mid-stream. The URL you store (in OBS, a bookmark, a stream-deck button) still contains the raw token, though - so the storage points below still matter.
- URLs are visible in browser history, screen shares and OBS scene exports. Use a member assignment + minimum-permission set so a leaked token can't be abused.
- Tokens assigned to a member are removed automatically when that member leaves the team. A token bound to you keeps working when someone else who used it leaves - revoke it yourself in that case, and revoke any token immediately if you suspect a leak.
- Never paste a popout token into a public chat, ticket, or screenshot.
API
| Type | Endpoint | Permission |
|---|---|---|
| GraphQL Query | popoutTokens | tokens:read |
| GraphQL Query | myPermissions | any authenticated - used by popout pages to know what they can render |
| GraphQL Query | emoteChannels | chat:read or events:read - the channel list chat and events popouts load their 7TV, BTTV and FFZ emotes from |
| GraphQL Mutation | createPopoutToken(input) | tokens:create |
| GraphQL Mutation | updatePopoutToken(id, input) | tokens:edit |
| GraphQL Mutation | deletePopoutToken(id) | tokens:delete |
| REST | GET /v1/tokens | tokens:read |
| REST | GET /v1/tokens/me | any authenticated - returns the current caller's resolved permission set |
| REST | GET /v1/emotes/channels | chat:read or events:read - REST twin of emoteChannels |
| REST | POST /v1/tokens | tokens:create |
| REST | PATCH /v1/tokens/\{id\} | tokens:edit |
| REST | DELETE /v1/tokens/\{id\} | tokens:delete |