OverlayThing Docs
Home
Login / Request Access
01 Get started
Introduction Quickstart Add to your stream
02 Overlays
Overlays The editor Overlay URLs Alert queue
03 Chatbot
Chatbot overview Getting started Commands Variables Conditionals Recipes API commands Integrations Modules Chat moderation Bot settings
04 Remote Control
Overview Connect OBS Studio Connect Meld Studio Bindings & triggers Security & access
05 Widgets
Widgets overview Alerts Variations Text to speech Goals Countdown & subathon Chat box Data labels Counter Text, image & video
06 Monetize
Tip page Tip settings Merch with Fourthwall
07 Build your own
AI Magic Builder Custom widgets Widget SDK
08 Your data
Dashboard Stream data Chat log Moderation
09 Account
Settings & connections Export your data Import from StreamElements
10 Reference
Label tokens Keyboard shortcuts Troubleshooting
Get started/More than overlays
Get started

More than overlays.

OverlayThing is an all-in-one toolkit for your Twitch channel: a visual overlay editor, a full chatbot, remote control of OBS or Meld, branded tip and merch pages, and your stream data and chat logs, all hosted for you. Build it here, add one URL to your streaming software, and the rest runs in the cloud.

What you are working with

Overlays are where most people start. An overlay is a transparent canvas, sized to your stream (1080p by default), holding a stack of widgets: alerts, goals, timers, labels, a chat box, and anything you build yourself. You arrange them in the editor, and the overlay renders live on top of your gameplay.

But the platform goes well beyond that. The same dashboard runs a full chatbot (commands, variables, conditionals, timers, giveaways, song requests and moderation), lets you control OBS or Meld from a chat command or a hotkey, powers your tip and merch alerts, and keeps your stream data and chat logs. One login, one place.

There is nothing to install. Everything is hosted for you and streamed to your browser source or run by the bot, so it all keeps ticking (countdowns, goals, the chatbot, reconnects) even while you are heads-down in a game.

New here?

Jump straight to the Quickstart. You can have a live overlay on your stream in a few minutes, then explore the rest.

Overlays in three steps

The overlay flow, start to finish:

1

Design in the editor

Add widgets to the canvas, style them, and wire each alert to an event: a sub, a raid, a follow, a cheer, a tip, or a merch sale.

2

Copy your overlay URL

Every overlay has its own private URL. Your edits save as you work, so the URL always reflects your latest design.

3

Add it to your stream

Add the URL as a browser source once, in OBS, Meld Studio, or whatever you stream with. From then on, edits appear live, with no re-export and no re-paste.

Explore by area

Overlays & widgets

The visual editor, alerts, goals, timers, labels and a chat box, rendered live on your stream.

Read →

Chatbot

Commands, variables, conditionals, timers, giveaways, song requests and moderation.

Read →

Remote Control

Drive OBS or Meld from chat, a dashboard button or a hotkey. No alt-tabbing.

Read →

Tips & merch

A branded donation page plus Fourthwall merch sales that fire alerts on stream.

Read →

AI Magic Builder

Describe a widget in a sentence and get a styled, editable starting point.

Read →

Stream data

Your dashboard, stream stats, chat log and moderation history in one place.

Read →
Next From zero to live
Get started/From zero to live
Get started

From zero to live.

The fastest path to a working overlay on your stream. Sign in, build something, and add it to your streaming software. You can refine everything afterward.

Before you start

You need a Twitch account and streaming software that supports a browser source, such as OBS Studio, Meld Studio or Streamlabs. There is nothing to install for OverlayThing itself. It runs entirely in your browser.

The steps

1

Sign in with Twitch

Click Continue with Twitch and authorize. We read your profile and the events we need to fire alerts. Your dashboard is created automatically.

2

Create an overlay

From Overlays, hit New overlay, give it a name, and choose a resolution (1080p is the usual pick).

3

Add a widget

Open the editor and add your first widget, an alert is a good start. Pick a starter template so it looks good immediately, then tweak the colors and text.

4

Copy the overlay URL

Click Overlay URL in the editor topbar and copy it. This is the private link your streaming software will load.

5

Add it to your stream

In your streaming software, add a browser source, paste the URL, and set it to match your overlay size. Full walkthrough in Add to your stream.

Test before you go live

Use Test Alert in the editor to fire a fake sub or raid and confirm it shows up in your stream preview. No need to actually get raided.

Previous More than overlays Next Add to your stream
Get started/Add to your stream
Get started

Add to your stream.

One overlay, one URL, one browser source. OverlayThing works with any streaming software that supports a browser source, so set it up once and every future edit appears live without touching your software again.

Works with your software

An overlay is just a web page, so it drops into any streaming app that has a browser source (sometimes called a web source). That covers the popular ones:

  • OBS Studio and Streamlabs Desktop: add a Browser source.
  • Meld Studio: add a Web source.
  • Most other broadcasters and hardware encoders with a browser or web source.

The steps below use OBS-style wording since it is the most common, but the idea is the same everywhere: paste the URL, match the size.

Add the browser source

1

Copy your overlay URL

In the editor, click Overlay URL and copy it. It looks like this:

overlay url
https://overlaything.com/o/0175b70483…eae8b2ba38c
1

Create a browser source

In your software, add a new browser (or web) source and give it a name like OverlayThing.

2

Paste and size it

Paste the URL into the URL field of the source. Set its width and height to match your overlay resolution (1920 by 1080 for a 1080p overlay).

3

Confirm it is live

The overlay appears in your scene with a transparent background. Fire a Test Alert from the editor to confirm events reach your stream.

Recommended source settings

The exact names vary between apps, but the equivalents are worth setting:

SettingValueWhy
Width and height1920 x 1080Match it to your overlay resolution so everything lines up pixel for pixel.
Shut down source when not visibleOffKeeps timers and goals running while you are on another scene.
Refresh when scene becomes activeOffEdits already push live, so a manual refresh is not needed.
Control audio through the appOnLets you mix your alert and TTS volume in the audio mixer of your streaming software.
Keep your URL private

Your overlay URL is unique to you. Anyone with the link can render your overlay, so do not show it on stream or share it. If it leaks, regenerate it from Overlay URLs and re-paste the new one.

Alert sound is overlay audio

Alert sounds and text to speech play through the overlay browser source. Add that source to your software's audio mixer and set a comfortable level so a cheer train does not blow out your stream.

Previous From zero to live Next Overlays
Overlays/Overlays
Overlays

Overlays.

Your overlays live on the Overlays page, a gallery of every canvas you have built. Most streamers keep a few: one for gameplay, one for Just Chatting, a starting-soon screen.

Creating an overlay

Hit New overlay, give it a name, and pick a resolution. You can choose 4K, 1440p, 1080p, 720p, or set a custom size in pixels. Overlays start blank, so the next step is adding widgets.

The gallery

Each card shows a live thumbnail, the overlay name, its resolution, how many layers it has, and when it was last edited. You can switch between grid and list view, search by name, sort, and filter by resolution or by which overlays are currently live on your stream.

From a card you can:

  • Edit: open the overlay in the editor.
  • Copy overlay URL: grab the browser source link without opening the editor.
  • Duplicate: make a full copy, including every widget and all their variations. The copy gets its own URL, so your live overlay is never touched.
  • Rename and Regenerate URL from the card menu.
  • Delete: removes the overlay, with a few seconds to undo if you change your mind.
Duplicate, do not rebuild

Got a look you like? Duplicate it and tweak the copy for your next scene rather than starting over.

One overlay or many?

You can run a single overlay across every scene, or build a dedicated overlay per scene and add each as its own browser source. Both are common. Pick whichever keeps your scene list tidy.

Previous Add to your stream Next The editor
Overlays/The editor
Overlays

The editor.

Where overlays are built. A canvas in the middle, your layer stack on the left, and an inspector on the right that changes to match whatever you have selected.

The canvas

A true-to-size preview of your overlay, transparent like it will be on stream. Drag widgets to move them, pull the handles to resize, and zoom in for fine work. Turn on the grid and snapping from the canvas controls to keep things aligned. Hold a modifier and click to select more than one widget at a time.

The layers panel

Every widget is a layer. Reorder by dragging: higher in the list sits on top. Each layer has quick toggles:

  • Visibility: hide a layer in the editor without deleting it.
  • Lock: freeze a layer so you do not nudge it by accident.
  • Rename: useful once you have a dozen widgets.

Select a few widgets and group them so they move together. Groups can be nested.

The inspector

Select a widget and the right panel fills with its controls. What you see depends on the widget, but the common tabs are:

TabWhat it does
LayoutExact X / Y / W / H in pixels, stack order and opacity.
AnimationEntry and exit motion, their duration, and how long the widget holds on screen.
StyleBackground, colors, fonts, borders and shadows for the widget and its blocks.
VariationsAlternate looks that fire on different events. See Variations.

Text widgets can be edited right on the canvas. Double-click one to type, format the text, and drop in tokens like {latest_follower} that fill in live.

Saving and testing

Edits save as you go, the topbar shows when it is saving and when everything is saved. There is no separate publish step: because your edits save automatically, your overlay URL always serves your latest work.

Test Alert

Click Test Alert in the topbar to fire a realistic fake event (a sub, a 47-viewer raid, a merch order) so you can tune timing and motion without waiting for the real thing. You can play it on the canvas, send it to your live overlay, or isolate it so other widgets get out of the way.

Previous Overlays Next Overlay URLs
Overlays/Overlay URLs
Overlays

Overlay URLs.

Each overlay has its own private URL. Add it to your streaming software once and it keeps serving your latest design as you edit.

How it stays in sync

Your edits save automatically, and the overlay URL renders whatever is saved. So there is no draft-versus-published split to manage: change something in the editor and connected browser sources update in place, usually within a second or two, no refresh required. The Save button in the topbar simply flushes any pending changes immediately rather than waiting for the next autosave.

Anatomy of an overlay URL

structure
https://overlaything.com/o/0175b70483…eae8b2ba38c
                           └ the private token, unique to this overlay

The token is a long random string, unique to that overlay and impossible to guess. It is the only thing your streaming software needs.

Regenerating a URL

If a URL ever leaks (you showed it on stream by accident, say), open the overlay menu and choose Regenerate URL. A fresh token is issued and the old link stops working. Re-paste the new URL into your browser source once.

Regenerating breaks the old link

Any browser source still pointing at the previous URL will go blank. Always update your browser source right after regenerating.

Previous The editor Next Alert queue
Overlays/Alert queue
Overlays

Alert queue.

When events pile up (a gifted-sub train, a hype raid), you usually want alerts to play one after another instead of stacking on top of each other. The alert queue is a per-overlay setting that controls exactly that.

One at a time

Open Overlay settings (the gear in the editor topbar). The main switch is Play alerts one at a time. With it on, a new alert waits for the current one to finish its animation, sound and text to speech before it plays.

Timing

SettingWhat it does
Pause between alertsA short breather inserted between queued alerts so back-to-back events feel distinct. Defaults to a quarter second.
Custom widget fallbackHow long to wait for a custom alert widget to report that it finished before moving on. Only matters for custom widgets that never call alertEnded().

Which alerts queue

You can choose which event types go through the queue. By default subs, cheers, raids, tips, redemptions and shoutouts queue, while follows play instantly (they are frequent and light). Any type you leave unchecked skips the queue and fires immediately, even while another alert is on screen.

Per overlay

These settings live on the overlay, so a gameplay overlay and a Just Chatting overlay can queue alerts differently.

Previous Overlay URLs Next The chatbot
Chatbot/The chatbot
Chatbot

The chatbot.

A Twitch chat bot built into OverlayThing: custom commands, timers, counters, quotes, giveaways, a queue, song requests, loyalty tracking, chat moderation and more. It runs on a shared bot account, so there is nothing to host and nothing to install.

Off by default

The chatbot is opt-in. Nothing is posted to your chat until you turn it on and grant the bot moderator. Turn it off again at any time and it goes silent immediately.

What it does

One bot, many parts. Each part (a "module") can be switched on or off on its own from the Chatbot page in your dashboard.

Commands

Custom and default commands with permissions, cooldowns, aliases, keywords and live variables.

Read →

Variables

The $( ) tokens that fill commands with live data: viewer, uptime, followage, quotes and more.

Read →

API commands

Pull a live value from any external API into a command. For power users.

Read →

Modules

Timers, counters, quotes, giveaways, queue, song requests, loyalty and chat alerts.

Read →

How it fits together

1

Turn the bot on

From the Chatbot page, flip the master switch and make the bot a moderator. See Getting started.

2

Set up commands and modules

You start with a handy set of default commands. Add your own, then enable the modules you want.

3

It runs itself

The bot answers commands, posts your timers, runs giveaways and moderates chat live. Changes you make apply the moment you save.

Your public command list

Every command you mark as public shows up on a shareable command page at overlaything.com/c/yourname, which the built-in !commands links to automatically.

Previous Alert queue Next Getting started
Chatbot/Getting started
Chatbot

Getting started.

Turn the bot on, make it a moderator, and pick your command prefix. Three small steps and your chat is covered.

The shared bot account

OverlayThing runs a single shared bot account that joins your chat to post replies, run timers and moderate. You do not create or manage a separate bot login. When you enable the chatbot, that account joins your channel; when you disable it, the account leaves and says nothing.

Turn it on

1

Open the Chatbot page

In your dashboard, go to Chatbot. The big switch at the top is the master on/off for everything the bot does.

2

Flip the master switch

Turn it on. The bot account connects to your chat. The status row shows the bot name, whether it is connected, your prefix, and its mod status.

3

Make the bot a moderator

On the same status row, click Make moderator. Twitch requires the bot to be a mod so its messages are not rate-limited and so it can time out or remove messages.

Mod the bot

Twitch heavily rate-limits non-mod accounts. Without mod, replies can be dropped or delayed and chat moderation will not work. The Make moderator button does it for you in one click.

The command prefix

The prefix is the character viewers type before a command. The default is the exclamation mark, so a command called uptime is run by typing !uptime. You can change it to any of these from Bot settings:

PrefixExample
!!uptime (the default)
&&uptime
~~uptime
--uptime
Switching prefix is safe

Your commands are stored without a prefix, so changing it instantly applies to every command at once. You do not have to rewrite anything.

Starter commands

The first time you enable the bot it seeds a set of ready-to-use default commands like !commands, !uptime, !followage and !so. Edit them, disable the ones you do not want, or delete them. They are only ever added once, so deleting one sticks.

Previous The chatbot Next Commands
Chatbot/Commands
Chatbot

Commands.

Commands are the heart of the bot. A viewer types a trigger, the bot replies with your text, with live data filled in. Custom commands, keyword triggers, permissions, cooldowns and aliases are all here.

Custom commands

A command is a trigger plus a response. Type the trigger in chat (with your prefix) and the bot posts the response. The response can mix your own words with variables that fill in live.

commandexample
Trigger:  !discord
Response: Join the $(channel) Discord at discord.gg/yourcode

Variables make a command dynamic. A !uptime command whose response is $(channel) has been live for $(uptime) posts the real elapsed time every time.

Default commands

You start with a set of commands already made for you. They are normal commands you can edit, disable or delete.

CommandReplies withWho
!commandsA link to your public command list.Everyone
!uptimeHow long you have been live.Everyone
!followageHow long the viewer (or an @user) has followed.Everyone
!accountageHow old the viewer (or an @user) Twitch account is.Everyone
!watchtimeTracked watch time for the viewer (or an @user).Everyone
!titleYour current stream title.Everyone
!gameThe category you are streaming.Everyone
!soA shout-out to another streamer, plus a native Twitch shoutout.Mods
!socialsA pointer to your social links.Everyone
!discordYour Discord invite pointer.Everyone
!lurkA friendly lurk message.Everyone
Restore defaults

Deleted one you wanted back? The Commands page has a Restore defaults button that puts back any missing default without touching commands you have customised.

Keywords and match types

Most commands match the first word of a message (a prefix command). A keyword command instead watches the whole message and fires when it matches a pattern, no prefix needed. Each keyword has a match type:

Match typeFires when the message…Example
Exactis exactly the phrase, nothing more.Phrase hi bot matches only "hi bot".
Containshas the phrase anywhere in it.Phrase discord matches "what is your discord?"
Startsbegins with the phrase.Phrase gg matches "gg everyone".
Regexmatches a regular-expression pattern.Pattern h[ae]llo matches "hello" or "hallo".

Regex, plainly

A regular expression is a mini pattern language for "does this text look like X". You do not need it for most keywords, contains and starts cover the common cases. When you do, a few pieces go a long way:

PieceMeansExample
|either / orlol|lmao|haha matches any of the three.
?the thing before it is optionalcolou?r matches "color" and "colour".
[ae]any one character in the bracketsgr[ae]y matches "gray" and "grey".
\ba word boundary (so you match whole words)\bgg\b matches "gg" but not "egg".
Keyword matching is case-insensitive

All keyword matching ignores upper/lower case, and a long message is capped before a regex runs so a heavy pattern cannot bog the bot down.

What wins when several could match

One message fires at most one command. A prefix command (or one of its aliases) always beats a keyword. Only when no prefix command matches does the bot check keywords, in order, and the first match wins.

Permissions (user levels)

Each command has a who can use it level. A viewer must be at that level or higher to run it.

LevelWho can run it
EveryoneAnyone in chat.
SubscriberSubscribers, VIPs, mods and you.
VIPVIPs, mods and you.
ModeratorYour mods and you.
BroadcasterOnly you.

If a viewer below the level tries a command, the bot simply stays quiet.

Cooldowns

Cooldowns stop a command being spammed. There are two, and both can be set on the same command:

CooldownWhat it limits
GlobalHow often the command can run for the whole channel, regardless of who runs it.
Per userHow often a single viewer can run it. Others are unaffected.

By default mods and you bypass cooldowns entirely (you can turn that off in Bot settings). When someone hits a cooldown the bot either stays silent or posts a short "wait Ns" reply, your choice in Bot settings.

Aliases

Give a command extra trigger words that do the same thing. A !commands command with aliases cmds and help answers all three. Aliases share the command response, permission and cooldowns, and they cannot collide with another command trigger.

Public list visibility

Each command has a show in public list toggle. Public commands appear on your shareable command page at overlaything.com/c/yourname (built-in module commands from Queue, Quotes, Counters, Music and a live giveaway keyword show there too). Turn it off for internal or mod-only commands you would rather not advertise.

Unknown-command suggestions

Turn on suggestions in Bot settings and when a viewer mistypes (like !uptme) the bot can reply "Did you mean !uptime?". It is rate-limited per viewer so it never spams.

Previous Getting started Next Variables
Chatbot/Variables
Chatbot

Variables.

Variables are $( … ) tokens you drop into a command response. They fill in with live data when the command runs: the viewer name, your uptime, a random number, a quote, a counter value, and much more.

How variables work

Write a token anywhere in a command response and the bot replaces it before posting. They combine freely with your own text.

responseexample
Welcome $(user)! $(channel) has been live for $(uptime).

If a token has no value (or names something that does not exist) it simply renders as nothing, so a small typo never breaks the reply.

Tokens that target a user

A few tokens describe a person and accept an optional @mention. With no mention they describe the viewer who ran the command; with one, they describe that user. These are $(followage), $(watchtime) and $(accountage).

arg-or-selfexample
!followage          → your own follow age
!followage @cohh    → @cohh's follow age

Other arg-taking tokens read what the viewer typed: $(touser) is the first word after the command, $(query) is everything after it, and $(random 1-6) / $(pick a;b;c) take their own inline options.

Use $(querystring) inside URLs

When you put viewer input into an API URL, use $(querystring) (URL-encoded), never the raw $(query). The encoded form keeps spaces and symbols from breaking the link.

Full reference

Every available variable, grouped by what it relates to. Tokens shown as $(count.<name>) or $(api.<field>) take a name or field you supply.

User

$(user)

The viewer who ran the command.

Example
$(user)→ninja
$(user.id)

The viewer's numeric Twitch user ID.

Example
$(user.id)→44322889
$(chatter)

The viewer who ran the command. Alias of $(user).

Example
$(chatter)→ninja
$(chatter.id)

The running viewer's numeric Twitch ID. Alias of $(user.id).

Example
$(chatter.id)→44322889
$(user.followers)

The running viewer's own channel follower count.

Example
$(user.followers)→1,530
$(user.status)

Whether the running viewer's own channel is live (with game) or offline.

Example
$(user.status)→live playing Fortnite
$(user.title)

The running viewer's own channel stream title.

Example
$(user.title)→ranked grind to Champion
$(user.viewers)

The running viewer's own channel viewer count (0 if offline).

Example
$(user.viewers)→212
$(user.url)

A link to the running viewer's own channel page.

Example
$(user.url)→https://twitch.tv/ninja
$(user.tags)

The running viewer's own channel stream tags.

Example
$(user.tags)→English, FPS
$(user.game)

The category the running viewer's own channel last streamed.

Example
$(user.game)→Fortnite
$(touser)

The first word after the command (an @-mention), or the viewer if none was given.

Example
$(touser)→cohhcarnage
$(random.chatter)

A random active chatter in your channel right now.

Example
$(random.chatter)→pokimane
$(userlevel)

The calling viewer’s level (everyone, subscriber, vip, moderator, broadcaster).

Example
$(userlevel)→moderator
$(touser.id)

The numeric Twitch ID of the @-mentioned user (or the viewer).

Example
$(touser.id)→26610234
$(touser.followers)

The @-mentioned channel’s follower count.

Example
$(touser.followers)→1,850,000
$(touser.status)

Whether the @-mentioned channel is live (with game) or offline.

Example
$(touser.status)→live playing Path of Exile 2
$(touser.title)

The @-mentioned channel’s current stream title.

Example
$(touser.title)→Chill Tuesday | PoE2
$(touser.viewers)

The @-mentioned channel’s current viewer count (0 if offline).

Example
$(touser.viewers)→4,120
$(touser.url)

A link to the @-mentioned channel’s page.

Example
$(touser.url)→https://twitch.tv/cohhcarnage
$(touser.tags)

The @-mentioned channel’s stream tags.

Example
$(touser.tags)→English, RPG

Channel & Stream

$(channel)

Your channel / broadcaster display name.

Example
$(channel)→doxmia
$(streamer)

Your channel / broadcaster display name. Alias of $(channel).

Example
$(streamer)→doxmia
$(game)

The category / game you are currently streaming.

Example
$(game)→Just Chatting
$(title)

Your current stream title.

Example
$(title)→building the overlay platform
$(viewers)

Your current live viewer count.

Example
$(viewers)→342
$(uptime)

How long you have been live this stream.

Example
$(uptime)→2h 14m
$(followers)

Your channel’s total follower count.

Example
$(followers)→12,480
$(status)

Whether you’re live (with the game) or offline.

Example
$(status)→live playing Just Chatting
$(tags)

Your current stream tags, comma-separated.

Example
$(tags)→English, Software & Game Dev
$(channel.url)

A link to your channel page.

Example
$(channel.url)→https://twitch.tv/doxmia
$(channel.id)

Your channel’s numeric Twitch ID.

Example
$(channel.id)→99288217
$(livesince)

The date your current stream went live.

Example
$(livesince)→Jun 9, 2026
$(touser.game)

The category another user (an @-mention, or the viewer) last streamed. Great for shoutouts.

Example
$(touser.game)→Path of Exile 2
$(query)

Everything the viewer typed after the command.

Example
$(query)→best loadout?
$(querystring)

Everything typed after the command, URL-encoded (for use inside API URLs).

Example
$(querystring)→best%20loadout%3F
$(1)

A single word the viewer typed, by position. $(1) is the first word after the command, $(2) the second, and so on (no limit). Blank past the last word.

Example
$(1)→best

Date & Time

$(time)

The current local time in your configured timezone.

Example
$(time)→9:42 PM
$(date)

Today's date in your configured format and timezone.

Example
$(date)→Jun 9, 2026
$(random)

A random whole number. Defaults to 1-100, or pass your own range.

Example
$(random 1-6)→4
$(pick)

Randomly pick one of several options separated by semicolons.

Example
$(pick heads;tails)→tails

Loyalty

$(followage)

How long a user (an @-mention, or the viewer) has followed your channel.

Example
$(followage @cohhcarnage)→2 years, 3 months
$(watchtime)

Total tracked watch time for a user (an @-mention, or the viewer). Needs Loyalty enabled.

Example
$(watchtime @cohhcarnage)→38h 12m
$(accountage)

How long ago a user (an @-mention, or the viewer) created their Twitch account.

Example
$(accountage @cohhcarnage)→11 years
$(accountdate)

The date a user (an @-mention, or the viewer) created their Twitch account.

Example
$(accountdate)→Mar 14, 2015
$(subscribers)

Your channel’s total subscriber count. Aliases: $(subscriber), $(subcount).

Example
$(subscribers)→486
$(subscriber)

Alias of $(subscribers) | your channel’s total subscriber count.

Example
$(subscriber)→486
$(subcount)

Alias of $(subscribers) | your channel’s total subscriber count.

Example
$(subcount)→486

Quotes

$(quote)

A random saved quote (its text). Same pick as $(quote.text) in the same response.

Example
$(quote)→dont feed the trolls
$(quote.text)

The text of a random saved quote.

Example
$(quote.text)→dont feed the trolls
$(quote.author)

The author of the random quote.

Example
$(quote.author)→doxmia
$(quote.id)

The per-channel number of the random quote.

Example
$(quote.id)→42

Counters

$(count)

This command's lifetime run count (or, inside a counter's own response, that counter's value).

Example
$(count)→128
$(count.<name>)

The current value of a named counter.

Example
$(count.deaths)→7

Queue

$(queue.current)

The viewer currently up (now playing) in the queue.

Example
$(queue.current)→ninja
$(queue.next)

The next viewer waiting in the queue.

Example
$(queue.next)→shroud
$(queue.count)

How many viewers are waiting in the queue.

Example
$(queue.count)→5
$(queue.list)

Up to the next 5 waiting viewers, comma-separated.

Example
$(queue.list)→shroud, pokimane, tfue, myth, sykkuno
$(queue.position)

The calling viewer's position in the queue.

Example
$(queue.position)→3

Media Requests

$(media.current)

The now-playing song, with who requested it.

Example
$(media.current)→Darude - Sandstorm (requested by ninja)
$(media.current.title)

The title of the now-playing song.

Example
$(media.current.title)→Darude - Sandstorm
$(media.current.artist)

The channel / artist of the now-playing song.

Example
$(media.current.artist)→Darude
$(media.current.url)

A YouTube link to the now-playing song.

Example
$(media.current.url)→https://youtu.be/y6120QOlsfU
$(media.requester)

Who requested the now-playing song.

Example
$(media.requester)→ninja
$(media.next)

The title of the next song in the request queue.

Example
$(media.next)→Never Gonna Give You Up
$(media.queue)

Up to the next 5 requested song titles, comma-separated.

Example
$(media.queue)→Never Gonna Give You Up, Megalovania, Sandstorm
$(media.count)

How many songs are waiting in the request queue.

Example
$(media.count)→3

League of Legends

$(lol.rank)

A League player's ranked solo/duo tier, LP and win/loss. Needs the Riot integration enabled.

Example
$(lol.rank Faker#KR1 kr)→Challenger 1,487 LP (412W / 388L)
$(lol.recent)

A League player's last 5 ranked-solo results plus today's win/loss record.

Example
$(lol.recent Faker#KR1 kr)→WWLWW · today 3-1
$(lol.champs)

A League player's top 3 most-played ranked-solo champions with win rates.

Example
$(lol.champs Faker#KR1 kr)→Azir 62%, Ahri 58%, Orianna 55%

API & Advanced

$(api)

The raw response body of this command’s configured API call.

Example
$(api)→{"temp":21,"humidity":72}
$(api.<field>)

A single field pulled from this command’s JSON API response.

Example
$(api.main.temp)→21
$(url.commands)

A public link to your channel’s command list.

Example
$(url.commands)→https://overlaything.com/c/doxmia

Conditionals

$(if)

Show text only when a condition is true. Pair with $(endif).

Example
$(if subscribed)thanks for subbing!$(endif)→thanks for subbing!
$(else)

The text to show when the $(if) condition is false.

Example
$(if mod)hi boss$(else)hi$(endif)→hi boss
$(endif)

Closes an $(if) block.

Example
$(if vip)VIP$(endif)→VIP
$(subscribed)

True when the viewer is subscribed. Aliases: sub, subscriber.

Example
$(if subscribed)thanks for the support!$(endif)→thanks for the support!
$(founder)

True when the viewer is a founder (one of the channel’s earliest subscribers).

Example
$(if founder)OG sub!$(endif)→OG sub!
$(mod)

True when the viewer is a moderator (the broadcaster counts too). Alias: moderator.

Example
$(if mod)mod tools ready$(endif)→mod tools ready
$(vip)

True when the viewer has the VIP badge.

Example
$(if vip)VIP in the house$(endif)→VIP in the house
$(broadcaster)

True only when the channel owner runs the command. Alias: streamer.

Example
$(if broadcaster)hey boss$(endif)→hey boss
$(bits)

How many bits the viewer cheered in this message (0 if none).

Example
$(if bits >= 100)big cheer!$(endif)→big cheer!
$(is_cheer)

True when this message included a bit cheer.

Example
$(if is_cheer)thanks for the bits!$(endif)→thanks for the bits!
$(emote_count)

How many emotes the viewer used in this message.

Example
$(if emote_count >= 3)so many emotes$(endif)→so many emotes
$(first_time)

True when this is the viewer’s first-ever chat message in your channel.

Example
$(if first_time)welcome!$(endif)→welcome!
$(returning)

True when the viewer has chatted before (a returning chatter).

Example
$(if returning)welcome back!$(endif)→welcome back!
$(streams_seen)

How many of your streams this viewer has been seen in.

Example
$(if streams_seen >= 10)regular!$(endif)→regular!
$(hour)

The current hour (0–23) in your timezone.

Example
$(if hour >= 22)late-night crew$(endif)→late-night crew
$(day)

The current day name (e.g. monday) in your timezone.

Example
$(if day == "friday")happy Friday!$(endif)→happy Friday!
$(tier)

The viewer's sub tier as a number (0=not subbed, 1/2/3). Prime counts as 1.

Example
$(if tier >= 2)Tier 2+ perk unlocked$(endif)→Tier 2+ perk unlocked
$(follower)

True when the viewer follows your channel. Alias: following.

Example
$(if follower)thanks for following!$(endif)→thanks for following!
$(followage_days)

How many days the viewer has followed your channel.

Example
$(if followage_days >= 30)1+ month follower$(endif)→1+ month follower
$(followage_months)

How many months the viewer has followed your channel.

Example
$(if followage_months >= 12)1-year follower!$(endif)→1-year follower!
$(watchtime_minutes)

The viewer’s total watch time in minutes.

Example
$(if watchtime_minutes >= 60)1+ hour watched$(endif)→1+ hour watched
$(watchtime_hours)

The viewer’s total watch time in hours.

Example
$(if watchtime_hours >= 100)100-hour club!$(endif)→100-hour club!
$(live)

True when your channel is currently live. Alias: is_live.

Example
$(if live)we’re live!$(endif)→we’re live!
$(uptime_minutes)

How many minutes the current stream has been live.

Example
$(if uptime_minutes >= 120)2+ hours in$(endif)→2+ hours in
Module tokens need their module on

Tokens like $(quote), $(count.deaths), $(queue.next), $(media.current) and $(watchtime) only return a value when the matching module is enabled. The League tokens need the Riot integration turned on for the platform.

Previous Commands Next Conditionals
Chatbot/Conditionals
Chatbot

Conditionals.

Conditionals let one command react differently to different viewers and situations: greet a sub one way and everyone else another, hide mod tools from regular chat, or roll a chance-based reply, all in a single response.

The block form

Wrap part of a response in an $(if …) block. The bot evaluates the condition and posts only the branch that matches. An $(else) is optional, and every block ends with $(endif).

responseshape
$(if CONDITION)shown when true$(else)shown when false$(endif)

Blocks can nest, so an $(else) branch can hold another $(if …) for a chain of cases.

Writing the condition

A condition is a boolean expression. Combine smaller checks with and, or and not, and group with parentheses. Precedence runs not first, then and, then or, so subscribed and tier >= 2 or mod reads as "(subscribed and tier 2+) or mod". Use parentheses any time you want a different grouping.

conditiongrouping
subscribed and (tier >= 2 or mod)

Comparisons

Either side of a comparison can be a token like $(followers), a named operand like tier, a number, or a "quoted string". Text values must be quoted. Equality is == (a lone = is accepted as a friendly alias), inequality is !=, and the numeric comparisons are >, >=, < and <=. String comparisons are case-insensitive, so "Just Chatting" and "just chatting" match.

Truthiness: a bare operand with no comparison is true when it is a true flag, a non-zero number, or a non-empty string that is not 0 or false. Coercion: when both sides of a comparison look like numbers they compare as numbers, otherwise they compare as text, so $(count) > 100 works even though tokens arrive as strings.

What you can check

Conditions can read viewer status (subscribed, tier, mod, vip, follower, first_time), channel state (live, hour, uptime), and any $( … ) variable. The full list of named operands, with each one's type and meaning, appears in the Conditionals section of the variable reference.

Examples

Start simple. Compare a token to text (the = alias is shown here) to greet one specific viewer:

responsegreet by name
$(if $(user) = "ninja")the king has arrived 👑$(else)welcome $(user)!$(endif)

Check a viewer's tier exactly, with a nested fallback for any other sub:

responsetier 3
$(if tier == 3)Tier 3 legend, thank you!$(else)$(if subscribed)thanks for subbing!$(else)hi $(user)$(endif)$(endif)

Compare one token against another, here a shouted-out channel's follower count against your own:

responsetoken vs token
$(if $(touser.followers) > $(followers))$(touser) is bigger than us, go follow!$(else)show $(touser) some love$(endif)

Match the current category by name:

responsecategory
$(if $(game) == "Just Chatting")grab a seat and chat!$(endif)

Reward loyal subs, and nudge everyone else:

responseloyal sub
hi $(user), $(if subscribed)because you're a loyal sub you get priority!$(else)if you were subbed you'd have a much better chance!$(endif)

Unlock a perk for Tier 2 and above:

responsetiered perk
$(if tier >= 2)Tier 2+ perk unlocked for $(user)!$(endif)

Welcome a first-time chatter:

responsefirst timer
$(if first_time)Welcome to the stream, $(user)! 🎉$(else)wb $(user)$(endif)

Show a hint only your mods can see:

responsemod only
$(if mod)Mod tools: !timeout !clip !title$(endif)

Run a free, no-API jackpot that hits roughly ten percent of the time:

responsechance
$(if $(random 1-100) <= 10)💰 JACKPOT $(user)!$(else)no luck, try again$(endif)

Greet by time of day:

responsetime of day
$(if hour >= 18)Good evening$(else)Good day$(endif), $(user)!

Gate a reply on whether you are live:

responselive gated
$(if live)We're live for $(uptime)!$(else)Currently offline, see you next stream.$(endif)

Combine several checks in one condition:

responsecombined
$(if subscribed and tier >= 2 or mod)VIP lane$(else)standard queue$(endif)
The un-taken branch never runs

Only the matching branch is evaluated, so tokens in the other branch are never resolved. That makes it safe to put a costly $(api) call or a League $(lol.rank …) lookup inside a branch: it only fires when that branch is the one being posted.

Previous Variables Next Recipes
Chatbot/Recipes
Chatbot

Recipes.

Copy-ready command responses for the trickier variables: shoutouts, weather, dice, counters, League ranks and the built-in mod commands. Drop one into a command, tweak the wording, and go.

Shoutouts

A rich shoutout pulls everything about the last person mentioned. The viewer types the command followed by a name, and $(touser) resolves that channel along with its profile fields.

!soresponse
Go follow $(touser) at $(touser.url). Last seen playing $(touser.game) with $(touser.followers) followers!

A live-aware shoutout reads the target's stream state, so the wording changes depending on whether they are live right now.

!soresponse
$(touser) is currently $(touser.status). Check them out: $(touser.url)

Weather

Fully plug-and-play, no API key required. It uses wttr.in, a free weather service. Make a new command, turn on API call, and copy these exact settings in. A viewer types !weather London and gets a one-line forecast back.

!weatherGET · Text
API URL:        https://wttr.in/$(querystring)?format=3
Method:         GET
Response type:  Text
Response text:  $(api)

That returns the whole line ready-made, for example London: ⛅️ +12°C. Want to word it yourself? Switch the response type to JSON and read fields by path:

!weatherGET · JSON
API URL:        https://wttr.in/$(querystring)?format=j1
Response type:  JSON
Response text:  $(query): $(api.current_condition.0.weatherDesc.0.value), $(api.current_condition.0.temp_C)°C (feels $(api.current_condition.0.FeelsLikeC)°C)
Why $(querystring)

$(querystring) URL-encodes whatever the viewer typed so a city like "New York" is sent safely. Use $(query) (the raw text) only in the visible reply, never in the URL.

Random fun

A magic 8-ball picks one answer at random each time with $(pick a;b;c).

!8ballresponse
🎱 $(pick yes;no;maybe;ask again later)

A damage roll combines the runner, a target and a random number in one line.

!attackresponse
$(user) hits $(touser) for $(random 1-100) damage!

Counters

A death counter reads a named counter with $(count.<name>). Bump it elsewhere (a hotkey or a separate command) and this line always reflects the current total.

!deathsresponse
$(channel) has died $(count.deaths) times this stream.

League of Legends

Look up a fixed player's rank with the Riot integration. Pass a Riot ID and region, or swap in $(query) to let viewers ask about anyone.

!rankresponse
$(touser) is ranked $(lol.rank Faker#KR1 kr)

Channel status

A quick status line mixes your title and follower count into one reply.

!statusresponse
$(channel) is $(status), $(followers) followers.

Built-in mod commands

These are not responses you configure: !marker and !poll are built-in commands your mods type straight into chat. Drop a stream marker at the current moment with an optional label.

chatmod command
!marker clutch play

Or start a Twitch poll with a question, semicolon-separated choices, and a duration in seconds.

chatmod command
!poll "Next game?" Mario;Zelda;Metroid 120
Tokens render empty when unavailable

A token with no value renders as nothing, so a missing follower count or an off target never breaks the reply. Module and integration tokens need their module or integration switched on first.

Previous Conditionals Next API commands
Chatbot/API commands
Chatbot

API commands.

Power-user territory. Wire a command to an external API and pull a live value into the reply: a weather report, a count from your own service, a fact from a public endpoint. If you are not comfortable with APIs, you can safely skip this page.

Advanced feature

This page is for people comfortable calling web APIs. Everything else in the chatbot works without it. If a third party offers a simple URL that returns data, you can surface it in chat here.

The idea

An API command calls a URL when the command runs, then drops the result into the response with the $(api) token. Turn on API call on a command and fill in the request.

FieldWhat it is
API URLThe address to call. Can contain variables, e.g. $(querystring) for viewer input.
MethodGET (read, the usual choice), or POST / PUT when an API needs data sent to it.
Response typeJSON (pull a single field by path) or Text (use the whole body as-is).
Field pathFor JSON: a dotted path to the value you want, e.g. main.temp.
AuthenticationOptional. Bearer token, a custom header, or a query parameter.

Reading the response

How you read the result depends on the response type:

  • Text: $(api) is the whole response body, cleaned to a single line.
  • JSON with a field path: $(api) is the value at your configured path.
  • JSON, ad-hoc field: $(api.some.field) pulls any field by path, even array indexes like $(api.results.0.name).
A dotted path

A JSON path walks into the response object. If the API returns { "main": { "temp": 21 } }, the path main.temp gives 21. A missing path just renders empty.

Failures stay silent

If a call fails or returns something odd, $(api) renders empty rather than posting an error: a non-2xx status (404, 500, …), an unreachable host or timeout, unparseable JSON, or a missing field all yield nothing. Any HTML body is dropped (chat is plain text), and an over-long value is trimmed so it can't blow past Twitch's message limit. The rest of your reply still sends with the blank filled in.

Using viewer input safely

To let a viewer pass an argument into the URL, use $(querystring), which URL-encodes whatever they typed. Never use the raw $(query) in a URL: a space or symbol would break the request, and unescaped input is a risk.

Worked example: a weather command

A viewer types !weather London and gets the temperature back.

!weatherGET · JSON
API URL:      https://api.example.com/weather?q=$(querystring)
Response:     JSON
Field path:   current.temp_c
Response text: $(touser) it is $(api)°C right now

Worked example: a value from your own service

Suppose you run a small service that returns plain text, like a current giveaway count.

!playersGET · Text
API URL:      https://api.example.com/players/online
Response:     Text
Response text: Players online right now: $(api)

Authentication

When an API needs a key, choose a scheme and paste the secret. The secret is encrypted at rest and never shown back to you or posted in chat.

SchemeHow the secret is sent
BearerAs an Authorization: Bearer … header.
HeaderAs a custom request header whose name you set.
QueryAs a query parameter appended to the URL.
Safe by design

Responses are fetched server-side with protection against pointing a command at internal addresses, capped to a single clean line, and briefly cached so a command on a short cooldown does not hammer the third party. If a call fails, the token just renders empty rather than leaking an error into chat.

Previous Recipes Next Integrations
Chatbot/Integrations
Chatbot

Integrations.

Built-in connections to outside services that add ready-made variables. Today that is the Riot Games / League of Legends integration.

League of Legends (Riot Games)

When the Riot integration is enabled for the platform, three League tokens become available in your commands. They look up a player by Riot ID and region and post a live ranked summary.

TokenReturns
$(lol.rank Name#Tag REGION)Ranked solo/duo tier, LP, and win/loss record.
$(lol.recent Name#Tag REGION)Last 5 ranked-solo results plus today's win/loss.
$(lol.champs Name#Tag REGION)Top 3 most-played ranked-solo champions with win rates.

The arguments

Each token takes a Riot ID and a region. The Riot ID is the in-game name, a #, and the tag line. The region is the last word.

argumentsformat
Name#Tag REGION

Faker#KR1 kr
Doublelift#NA1 na

Supported regions include na, euw, eun, kr, jp, oc, br, la1, la2, tr and ru.

Examples

!rankcommand
Trigger:  !rank
Response: $(lol.rank Faker#KR1 kr)

In chat:  GOLD II (45 LP) - 30W/22L 57.7%
!recentcommand
Trigger:  !recent
Response: $(lol.recent Faker#KR1 kr)

In chat:  ✅ ✅ ❌ ✅ ❌ | Wins/Losses today: 2W/1L (66.7%)
Let viewers ask about anyone

Combine a token with $(query) so a viewer can pass the Riot ID: a !rank command with response $(lol.rank $(query)) answers !rank Faker#KR1 kr.

It just works when enabled

The League data uses a key that an OverlayThing operator configures once for everyone. You do not enter your own key. When the integration is on, the tokens work for your channel automatically. When it is off or not configured, the tokens render nothing rather than erroring.

Previous API commands Next Modules
Chatbot/Modules
Chatbot

Modules.

The bot is made of modules you switch on individually: timers, counters, quotes, chat alerts, welcome greetings, giveaways, a queue, song requests and loyalty. Plus ways to fire commands from a Stream Deck.

Timers

Post recurring messages on a schedule: rules, socials, a sponsor plug. Each timer posts after its interval (in minutes) once at least a minimum number of chat lines have passed since its last post, so it never talks to an empty room. Give a timer several messages and it rotates through them. Choose whether it runs only while you are live or always.

OptionWhat it does
IntervalMinutes between posts.
Minimum chat linesHow many messages must pass before it posts again.
WhenOnline only, or always.
MessagesOne or more lines it rotates through, each can use variables.

Counters

Track a number from chat: deaths, wins, anything. Each counter gets up to four trigger words for show, add, subtract and set, and you decide who can change it.

counterexample
Show:  !deaths        → "deaths is now 7"
Add:   !death         → bumps it up by one
Sub:   !undodeath     → backs it down
Set:   !setdeaths 0   → mods only

You can write a custom reply (with $(count) and $(count.name)), or use a different message per verb. The value is also readable from any command with $(count.deaths).

Quotes

A searchable quote book your chat builds with you. Recall a random quote, or a specific one by number.

CommandDoesWho
!quote [number]Show a random quote, or a specific one.Everyone
!addq <text>Add a new quote.Subscribers
!delq <number>Delete a quote.Mods
!editq <number> <text>Edit a quote.Mods

Pull a quote into any command with $(quote), or its parts with $(quote.text), $(quote.author) and $(quote.id).

Chat alerts

Post a chat message when someone follows, subs, resubs, gifts, cheers or raids, in step with your overlay alerts. Each event has its own message and an optional threshold (for example, only greet raids of 3+ viewers, or cheers over a bits amount).

chat alertcheer
Thanks for the {bits} bits, {name}! 🎉

Welcome

Greet people automatically. Three independent pieces:

GreetingFires for
First-time chatterSomeone chatting in your channel for the very first time.
Returning regularA familiar face coming back, after a quiet gap and once they reach a regular streak.
Raid shout-outAuto shout-out an incoming raider over a viewer threshold.

You set the message for each, and can tag the person by name. Returning-regular has a streak count (how many streams makes a "regular") and a re-greet gap (hours of quiet before you greet them again).

Giveaways

Run a giveaway and draw a winner from chat. Two modes:

ModeHow people enter
KeywordViewers type an entry phrase, e.g. !giveaway, during the giveaway.
Random (passive)No typing needed. The bot draws from active chatters in a recent window.

Set the prize, who can enter (everyone, followers, subscribers, VIPs and mods), and weighting (give subs more luck, or weight by watch time). Keyword giveaways can auto-draw after a number of minutes, or you draw manually. You can re-roll if the winner is absent, and a draw can fire a giveaway alert on your overlay. Exclude specific names from ever winning.

Queue

Let viewers line up to play with you. They !join, you pull people up with !next. Viewer commands (join, leave, check position, bump yourself down, list) and mod commands (next, clear, open, close) all have configurable trigger words.

OptionWhat it does
Open / closedThe queue only accepts entries while open.
Join roleWho may join (everyone up to subs/VIPs).
Max sizeCap the queue, or leave it unlimited.
Sub priorityPlace subscribers ahead in line.
Ask for a noteCollect a short note with each entry.
LeaderboardA public queue page with a play-count leaderboard.

Read queue state in commands with $(queue.current), $(queue.next), $(queue.count), $(queue.list) and $(queue.position).

Media requests (song requests)

Viewers request YouTube songs by name or link and the bot builds a play queue. Playback happens either in a dashboard tab or on a dedicated overlay you add to your stream, with a now-playing card.

CommandDoesWho (default)
!sr <song or link>Request a song.Per your request gate
!songShow what is playing.Everyone
!wrongsongRemove your last request.Everyone
!skipSkip to the next song.Mods
!stealSave the current song to your playlist.Mods
!volume <0-100>Set the music volume.Mods
!pausesongPause or resume.Mods
!sron / !sroffOpen or close requests.Mods

Set who can request (everyone up to subscribers), a max song length, how many requests one person can hold, duplicate blocking, and a fallback playlist that plays when no requests are queued. Read state with $(media.current), $(media.next), $(media.queue) and $(media.count).

Needs a YouTube key

Song requests use the YouTube Data API, so this module asks you to add a YouTube API key. It is encrypted at rest and only used to search and play.

Loyalty (watch time)

Track how long your viewers watch. The bot accrues watch time for people present in chat, which surfaces your most loyal regulars and powers the $(watchtime) token and the Welcome module's returning-regular greeting. You can choose to count only while you are live, and optionally only for people who actually chat (not silent lurkers).

Command API and Copy-URL (Stream Deck and hotkeys)

Most things the bot does can also be fired from outside chat, from a Stream Deck button, a hotkey tool, or any device that can open a URL. Across the chatbot dashboard you will find Copy URL menus that give you a private link which, when opened, runs that command or module action exactly as if it were typed in chat.

These links cover custom commands, counter verbs, queue and song-request actions, and giveaway start/draw/reroll/finish. They are authorized by your channel API token, so keep them private and reset the token if one ever leaks.

Deck-friendly

Put "add a death", "skip song", "draw the giveaway" or "open the queue" on physical buttons so you can run them mid-game without alt-tabbing.

Bot presence

You do not manage where the bot is. When you enable the chatbot it joins your chat; when you disable it, it leaves. Connection status (connected, offline, blocked) is shown on the Chatbot page and in Bot settings, where a Force reconnect button is available if you ever need it.

Previous Integrations Next Chat moderation
Chatbot/Chat moderation
Chatbot

Chat moderation.

When the bot is a moderator it can keep chat clean automatically: tunable spam filters, a banned-word list with per-word actions, and a searchable log of everything it did.

Separate from overlay moderation

This is live chat enforcement (deleting messages, timing people out). It is distinct from the overlay-side filtering that decides what reaches your chat box and text to speech, covered under Moderation.

Chat filters

Automatic spam protection you turn on filter by filter. Each filter has its own action and timeout, and exempts mods and you by default.

FilterCatches
CapsWalls of CAPITAL LETTERS.
SymbolsMessages stuffed with symbols.
LinksPosted URLs (with a whitelist for ones you allow).
EmotesEmote floods.
ParagraphsOverly long messages.
RepetitionRepeated characters or repeated messages.
ZalgoGlitchy combining-character text.
One-man spamOne person flooding the same thing.

Per filter you set the action (delete the message, time the user out, ban) and the timeout length, plus an optional chat warning with a {user} placeholder. A channel-wide silent mode suppresses those warnings while still enforcing.

Banned words

Keep a list of words and phrases the bot acts on in live chat, each with its own action (timeout or ban). This is separate from the overlay-display banned-word list, it is about enforcing in chat, not redacting on screen.

Test mode

Turn on mod test mode and a message from you or a mod that would be actioned is left alone, with the bot instead replying to name the rule that would have fired. It lets you tune filters and banned words live without timing anyone out.

Mod log

Every automated and manual moderation action is recorded in the Mod Log: what happened, to whom, why, and when. It is searchable and exportable, so you can review a timeout or settle a dispute after the fact.

Previous Modules Next Bot settings
Chatbot/Bot settings
Chatbot

Bot settings.

The channel-wide behavior of the bot: your prefix, how it replies, how cooldowns behave, and the timezone and date format it uses.

Prefix

The character before a command (!, &, ~ or -). Commands are stored prefix-free, so changing it applies everywhere at once. See Getting started.

Reply style

How the bot formats a reply to a command:

StyleLooks like
PlainA normal chat message.
MentionPrefixed with the viewer name, e.g. @you ….
ThreadPosted as a Twitch reply threaded under the viewer message.

Reply style only applies to replies triggered by a chat command. Event-driven posts (timers, chat alerts, raid shout-outs) always post plain.

Cooldown behavior

SettingWhat it does
On cooldownWhen a command is on cooldown, stay silent or post a short "wait Ns" reply.
Mods bypass cooldownLet mods and you skip cooldowns entirely. On by default.
Unknown commandIgnore an unmatched command, or suggest the closest one ("Did you mean …?").
Rate limitA safety cap on how many messages the bot sends per 30 seconds.

Timezone and date format

Set the timezone and date format the bot uses for the $(time) and $(date) variables, so a !time command shows your local time and dates read the way you expect.

Connection

Bot settings also shows connection health and a Force reconnect button. Use it if the bot ever looks stuck after you have confirmed it is enabled and a moderator.

Previous Chat moderation Next Remote Control
Remote Control/Remote Control
Remote Control

Remote Control.

Drive your local OBS Studio or Meld Studio straight from OverlayThing. Switch scenes, mute a mic, toggle a source, start a recording, all from a chat command, a dashboard button, or a hotkey link. You set everything up in the dashboard and never touch your streaming software again.

What it is

Remote Control connects your OverlayThing dashboard to the streaming software running on your machine. Once it is setup you (or your mod(s) of choice) can run actions like switch scene, mute, unmute audio, show or hide a source, and start or stop recording or streaming, without the streamer needing to do all the work.

You wire up those actions once in the dashboard, then fire each one three ways: a chat !command your community (or just your mods) can run, a button on the Remote Control page, or a hotkey URL you put on a Stream Deck or a keyboard macro. There is nothing to script and nothing to install beyond a single source in your streaming software.

How it runs

Remote Control uses a tiny browser source that sits in your scene and renders completely blank. It talks to your OBS or Meld over their local connection and relays your dashboard's instructions to them. You never see it on stream.

Get connected

Pick the software you stream with and follow the short setup:

  • Connect OBS Studio | add a dock or browser source, turn on the WebSocket, enter the port and password.
  • Connect Meld Studio | add the blank source to every scene, no password needed.

Once a provider is connected, head to Bindings & triggers to wire up actions, and read Security & access before you put a URL on a Stream Deck.

It looks after itself

Remote Control reconnects on its own if OBS or Meld restarts or your connection drops, and it updates itself in the background when we ship improvements. You do not need to refresh anything or re-add the source.

Previous Bot settings Next Connect OBS Studio
Remote Control/Connect OBS Studio
Remote Control

Connect OBS Studio.

Add the Remote Control URL as a dock or browser source, enable the OBS WebSocket, and enter the port and password in the dashboard. The status dot turns green when it connects.

Set it up

1

Add the Remote Control URL

On the Remote Control page, copy your OBS Remote Control URL. The recommended way to add it is as a Custom Browser Dock (in OBS: Docks, then Custom Browser Docks), which keeps it running independently of your scenes. If you prefer, you can add it as an ordinary browser source in a scene instead. Either works, and it renders completely blank.

2

Turn on the OBS WebSocket

In OBS, open Tools, then WebSocket Server Settings, enable the server, and note the port and password.

3

Enter the port and password in the dashboard

Back on the Remote Control page, type the same port and password into the OBS connection card and save. The status dot turns green once it connects.

Dock or source?

A Custom Browser Dock stays connected no matter which scene is live, so it is the simplest choice for OBS. A browser source works too, but only runs while a scene that contains it is active.

Next steps

Before you share or save anything, read Security & access | your OBS password and URL both deserve care. Then build Bindings & triggers to wire up actions.

Previous Remote Control Next Connect Meld Studio
Remote Control/Connect Meld Studio
Remote Control

Connect Meld Studio.

Add the blank Remote Control source to every Meld scene. There is no password to enter, it connects locally, and the status dot turns green when it does.

Set it up

1

Add the Remote Control source to every scene

Copy your Meld Remote Control URL and add it as a Web source in each of your scenes. It renders completely blank, so it never shows on stream. Meld needs the source present in every scene so the connection stays alive as you switch scenes.

2

No password needed

Meld connects locally without a password, so there is nothing else to enter. The status dot turns green once it connects.

Add it to every Meld scene

In Meld, the source only runs while a scene that contains it is active. Adding it to every scene keeps Remote Control connected no matter which scene you are on. It stays blank in all of them.

Meld actions are toggles

Meld's controls toggle, so mute, layer visibility, recording and streaming flip their current state. The dashboard board reflects Meld's live state, so the buttons stay in sync with what Meld is actually doing.

Next steps

Next, read Security & access before putting your URL anywhere, then build Bindings & triggers.

Previous Connect OBS Studio Next Bindings & triggers
Remote Control/Bindings & triggers
Remote Control

Bindings & triggers.

A binding is one or more actions plus the trigger that fires them. Build them on the Remote Control page and run them from chat, a dashboard button, or a hotkey URL.

Actions

An action is a single thing to do in OBS or Meld: switch a scene, show or hide a source, mute or unmute an input, set a volume or gain, start or stop recording or streaming, and more. Source and layer pickers are scoped to the scene you choose, so you only see what lives in that scene.

Triggers

Every binding fires from one of three triggers:

  1. A !command in chat, with a who can use it picker so you choose exactly which roles (Broadcaster, Moderator, VIPs, Subs, or Everyone) are allowed to run it, plus an optional cooldown so it cannot be spammed. You can always run your own commands.
  2. A dashboard button on the Remote Control page that you press yourself.
  3. A hotkey URL you can copy onto a Stream Deck button or a keyboard macro to fire the binding without opening anything.

Several actions at once

A binding can run several actions in a row, for example mute your mic and hide a source and then switch to your "Be right back" scene. A binding can include at most one scene switch, and the scene switch always runs last, so the rest of your changes are in place before the new scene comes up.

Build a "BRB" in seconds

Make a binding that mutes your mic, hides your camera, and switches to your break scene, then give it a !brb command limited to your mods and a Stream Deck button. One press and you are off.

A fun sub-only perk

Turn a source into a reward. Make a binding that shows a fun source or layer | a confetti burst, an emote rain, an air-horn clip that plays once and clears itself | then give it a !hype command limited to Subs with a short cooldown so it cannot be spammed. Now your subs can set off a little moment on stream as a perk, and the cooldown keeps it special, all without you lifting a finger.

Commands you create register in your bot command list as read-only, managed by Remote Control, so they can never clash with your other commands.

Previous Connect Meld Studio Next Security & access
Remote Control/Security & access
Remote Control

Security & access.

The Remote Control URL is a key to your streaming software, and your OBS password passes through our server to reach it. Here is what that means and how to stay safe.

Two things to keep safe

Keep your Remote Control URL private

The Remote Control URL grants control of your streaming software. Treat it like a key. Never show it on stream and never share it. If it ever leaks, open the connection card and reset it, which issues a fresh URL and stops the old one from working. Re-add the new URL to your dock or source.

Your OBS password passes through our server

To relay your commands, your OBS WebSocket password is sent to OverlayThing. It is only ever used to control the OBS running on your own machine, and nothing else. Meld needs no password at all. If that is a concern for you, the rest of the feature works the same way.

Who can do what

Dashboard buttons and hotkey URLs are yours to press. Chat commands run only for the roles you allow in each binding's who can use it picker, so you can hand !brb to your mods without opening anything else up. See Bindings & triggers for the per-command roles.

Previous Bindings & triggers Next Widgets overview
Widgets/Widgets overview
Widgets

Widgets overview.

Widgets are the building blocks of an overlay. Some fire on an event and leave (alerts), some stay on screen and update themselves (goals, timers, chat, labels), and some are just decoration (text, images, video). You can also build your own.

Adding a widget

In the editor, open the widget picker and choose what to add. It drops onto the canvas ready to style. Alerts are unique per overlay, so each overlay has at most one Subscriber alert, one Cheer alert, and so on. If you click an alert type you already have, the editor jumps you to it.

The catalog

WidgetWhat it is
AlertsFire on subs, follows, cheers, raids, redemptions, shoutouts, tips and merch sales.
GoalsA progress bar toward a target: followers, subs, bits, tips, raids or redemptions.
Countdown and subathonA countdown to a time or duration, or a subathon clock that grows with events.
Chat boxYour live Twitch chat on screen, fully styled.
Data labelsLive text readouts like latest follower or subs this session.
CounterShows a chatbot counter (deaths, wins) live on the overlay.
Text, image and videoStatic decoration and backgrounds.
Custom widgetsYour own HTML, CSS and JavaScript, or something the AI builder made.
Not sure where to start?

Add an alert and a goal, style them to your channel colors, and you already have a solid overlay. Use AI Magic Builder when you want something custom without writing code.

Previous Security & access Next Alerts
Widgets/Alerts
Widgets

Alerts.

The moment something happens, an alert fires on screen with motion, sound and your styling. They are the heart of an overlay, and each event type gets its own design.

Event types

Each alert is bound to one event. Style and time them independently.

AlertFires whenSome tokens
SubscriberSomeone subscribes, resubscribes, gifts, or subs with Prime.{name} {tier} {months}
FollowerA new follow lands.{name}
CheerSomeone cheers bits.{name} {bits} {message}
RaidA channel raids you.{name} {viewers}
Channel PointsA viewer redeems a reward.{name} {reward_title}
ShoutoutYou shout out another channel.{name} {viewers}
TipA donation hits your tip page.{name} {amount} {message}
MerchA Fourthwall order is placed.{product} {total} {item_count}
Giveaway WinnerThe chatbot draws a giveaway winner.{winner_name} {prize_name}

The full list of tokens for each alert is in the token reference.

Designing an alert

Open the alert designer from any alert widget. An alert is made of blocks you arrange and style: text, an image, a video, and a sound. On top of the blocks you control:

  • Background: none, a solid color, a gradient, or an image.
  • Entry and exit animation, their durations, and how long the alert holds.
  • Per-block animation: give the text its own entrance, add a continuous pulse, and so on.
  • Message templates that mix your words with tokens.
  • Text to speech, covered in Text to speech.
message templatetip
{name} tipped {amount}: "{message}"

Starter templates

Every alert type ships with a Standard template so it looks good before you touch a thing, plus a Blank option if you would rather build from scratch. Picking a template resets the alert to that starting point.

One event, many looks

A 5-gift sub should not look like a single Tier 1. Set up variations so bigger events trigger a bigger, louder version of the alert.

Test as you design

Use the test button in the designer to fire a sample event that matches what you are styling, so you can see the real animation and hear the sound.

Previous Widgets overview Next Variations
Widgets/Variations
Widgets

Variations.

One event, different reactions. Variations let a single alert play a bigger version for a Tier 3 sub, a special look for a 1,000-bit cheer, or a unique design when someone buys a specific piece of merch.

How it works

An alert has a base design and any number of variations. Each variation has criteria that decide when it can fire, plus the changes it makes on top of the base (different colors, text, sound, animation, even different blocks).

When an event arrives, OverlayThing looks at every variation whose criteria match. The most specific match wins. If two are equally specific, a weighted chance picks between them. If nothing matches, the base design plays.

Criteria

Each variation has one or more criteria, combined with match all (every criterion must be true) or match any (at least one). A criterion is a field, an operator, and a value.

OperatorMeans
at least / at mostNumeric thresholds, like bits at least 1,000.
is / is notExact match, like tier is 3.
greater than / less thanStrict numeric comparison.
matchesA text pattern, like a username or message.
is one ofMatches any value in a list, like sub type is one of resub or gifted.
includes any / all / noneFor lists such as merch collections or products in an order.

What you can match on

AlertFields you can match
SubscriberSub type (new, resub, gifted, prime), tier, months, gift count, whether it is gifted or anonymous.
CheerBits amount, whether it is anonymous, whether it has a message.
TipAmount and currency.
RaidViewer count.
Channel PointsWhich reward, the point cost, the message.
MerchOrder total, item count, collections and products in the order.

Examples

  • Tier 3 subs get a gold version with a different sound.
  • Cheers of 1,000 bits or more roll out a bigger animation.
  • A merch order that includes anything from your "Limited" collection plays a special alert.
Goals and timers too

Persistent widgets can use variations as well, including thresholds on progress, so a goal bar can change look once it passes 50%.

Previous Alerts Next Text to speech
Widgets/Text to speech
Widgets

Text to speech.

Have alerts read messages aloud: a tip note, a resub message, a redemption. Text to speech turns those into spoken audio that plays through your overlay.

Turning it on

Text to speech is configured per alert in the designer. Pick a voice, set the volume, and choose how it behaves alongside any sound or video in the alert:

Media modeBehavior
Just playSpeech and the alert sound or video play at the same time.
DuckThe alert sound or video drops to a lower volume while the voice is talking, then comes back.
QueueThe alert sound or video plays first, then the voice.

You can also set a short delay before the voice starts, and override the voice or speed on an individual text block.

Voices

Available voices come from the speech provider configured for the platform (for example ElevenLabs or Amazon Polly). You choose from the voice list in the designer.

Pronunciation

Voices sometimes mangle names, in-jokes or game terms. In Settings, under Pronunciation overrides, add a word and how it should sound, and speech will use your version everywhere it reads that word.

WordPronounce as
Bobbahb
Cwiczeniavee-cheh-nya
xQcex cue see

Quotas

Each account has a monthly character allowance for speech. Generated audio is cached, so re-firing the same message does not spend your allowance twice.

Mix the volume on your stream

Speech plays through the overlay browser source, the same as alert sounds. Keep that source in your streaming software audio mixer so you can balance it against your game and mic.

Previous Variations Next Goals
Widgets/Goals
Widgets

Goals.

A progress bar with a target. It fills itself as events come in, and you can celebrate the moment it hits the goal.

Goal types

Pick what the goal tracks:

  • Followers, Subscribers, Bits, Tips, Raids, or Channel Point redemptions.

Set it up

Choose the metric, a target, and a period that decides what counts: this stream, today, this week, this month, all time, or a custom date range. For subscriber goals you can also choose whether gifted subs count once per recipient or once per gift event.

Style it

The bar is fully stylable: solid, gradient or striped fill, rounded or pill or square ends, optional segments, and a label you write yourself using tokens like {current}, {target}, {progress_pct} and {remaining_to_target}.

Subathon-friendly

Pair a tip or sub goal with a subathon timer so your community can see both the money raised and the time on the clock.

Previous Text to speech Next Countdown & subathon
Widgets/Countdown & subathon
Widgets

Countdown & subathon.

Two timer widgets. A countdown runs down to a time or for a set duration. A subathon clock starts with time on it and grows as your community subscribes, cheers, tips and raids.

Countdown

Set it to count down a fixed duration (good for "back in 10 minutes") or to a target time (good for a scheduled start). Choose what happens when it reaches zero: hide, show zeroes, or show a message like "We are live!".

Subathon

A subathon timer starts at a value you set and adds time for events. You decide the rate for each:

EventAdds
SubscriptionSeconds per Tier 1, Tier 2, Tier 3, Prime, and gifted sub.
CheerSeconds per 100 bits.
TipSeconds per dollar tipped.
RaidSeconds per raid viewer.

Add caps so a single event or the whole clock cannot run away, pause it when you go offline, and optionally let mods pause it with a chat command.

Formatting

Both timers support several display formats (hours:minutes:seconds, minutes:seconds, and longer day-based formats) and tokens like {remaining} and {elapsed} so you can write your own layout.

Previous Goals Next Chat box
Widgets/Chat box
Widgets

Chat box.

Put your Twitch chat on stream, great for handheld, IRL or face-cam layouts where viewers cannot see the chat panel. Fully styled to match the rest of your overlay.

What it shows

Live messages with usernames in their Twitch colors, badges, and emotes. New messages animate in, and you can fade old ones out after a set time so the box stays clean.

Filtering

  • Moderation: apply your channel's moderation so blocked messages never appear.
  • Hide bots: exclude known bot accounts (common ones are excluded by default, and you can edit the list).
  • Include the broadcaster: choose whether your own messages show.

Styling

Control the maximum number of messages, the direction they stack, animation in and out, row spacing and background, badge visibility and size, username color (their chat color, a custom color, or random), font, and emote size. Emotes can come from Twitch as well as FFZ, BTTV and 7TV.

Readability on busy backgrounds

Add a subtle panel or backdrop behind the chat box so messages stay legible over fast-moving gameplay.

Previous Countdown & subathon Next Data labels
Widgets/Data labels
Widgets

Data labels.

Small live readouts that keep your channel numbers on screen: latest follower, latest sub, subs this session, followers this week. They update themselves, so you never touch them mid-stream.

How a label works

A data label is a piece of text bound to a data source, plus a template you write with tokens. Set the wording to whatever you like, "Last sub: {latest_sub_name}" or just "{latest_follower}", and the token fills in live.

What you can show

GroupExamples
Latest eventsLatest follower, latest subscriber and tier, latest tipper and amount, latest cheer, latest redemption.
This sessionFollowers this session, subs this session, and merch sales if Fourthwall is connected.
Recent windowsFollowers and subs over the last 7 or 30 days.

The full list is in the token reference. You can also make a label scroll, which is handy for a marquee of recent supporters.

Pulls from Stream Data

Labels read from the same numbers as your Stream Data page. Some all-time and top-supporter values are maintained there, so set or correct them on that page and your labels follow.

Previous Chat box Next Counter
Widgets/Counter
Widgets

Counter.

Put a live number on your overlay: deaths, wins, fails, anything you keep a running tally of. The counter widget shows the value of one of your chatbot counters and updates the instant the number changes.

How it works

A counter widget is tied to a single named counter from the chatbot Counters module. Pick which counter it tracks, and the widget shows that counter's current value. When the number changes (a mod runs !death, you press a Stream Deck button, or you edit it on the dashboard) the overlay updates straight away, with no refresh.

Counters live in the chatbot

The values themselves are owned by the chatbot. Create and manage your counters, and set who can change them, in the Counters module. This widget is just a way to show one of them on stream.

Set it up

Add the Counter widget from the widget picker, then choose the counter to track and the wording. The label uses a simple format with two tokens:

TokenShows
{name}The counter name, e.g. Deaths.
{value}The current count.
formatexample
Deaths: {value}
{name} - {value}
💀 {value}

Style it

Like any widget, you control the font, size, color, alignment and position on the canvas, so the counter fits the rest of your overlay.

Show it without the bot in chat

Even if you would rather not run public counter commands, you can still bump the number yourself: edit it on the Chatbot Counters page or put its Copy URL on a Stream Deck button.

Previous Data labels Next Text, image & video
Widgets/Text, image & video
Widgets

Text, image & video.

The plain building blocks. Use them for backgrounds, frames, logos, panels and labels that are not tied to an event.

Text

A text block you edit right on the canvas. Double-click to type, then style the font, size, color, alignment, shadow and outline. Text blocks can include tokens, so a plain-looking label can still show your latest follower.

Image

Drop in a logo, a frame, or a background. Choose how it fits its box (cover, contain or fill) and round the corners or fade it as needed.

Video

Use a looping video or animation as a backdrop or accent. Control how it fits, whether it loops, its volume, and a start delay or duration.

Layer order matters

Backgrounds belong at the bottom of the layers panel, with alerts and labels above them. Drag layers to reorder.

Previous Counter Next Your tip page
Monetize/Your tip page
Monetize

Your tip page.

A branded donation page viewers can reach from a single link in your panels or chat. Your banner, your colors, your PayPal, and every tip can fire an alert on your overlay.

Your link

Every account gets a tip page at a clean URL based on your Twitch name:

tip page url
https://tip.overlaything.com/ferret_king

What viewers see

  • Your banner, avatar and accent color up top.
  • Preset amounts plus a custom amount field.
  • A name and a message box, both of which can appear in your alert.
  • A Tip with PayPal button. Funds go to your PayPal account.
  • An optional leaderboard of your top tippers.

You can choose between a few page layouts and type styles in Tip settings.

Connect PayPal first

Tips cannot be collected until you add your PayPal email in Tip settings. Until then the page is not ready to take money.

Previous Text, image & video Next Tip settings
Monetize/Tip settings
Monetize

Tip settings.

Everything behind your tip page: the payment connection, your branding, the amounts, and how tips turn into on-stream alerts.

Payments

Add the PayPal email that should receive tips. Set your currency (USD, EUR, GBP, CAD, AUD or JPY), a minimum and optional maximum tip, a suggested amount, and how long a tip message can be.

Presets and branding

  • Preset amounts: up to five quick-pick buttons, for example 5, 10 and 25. You can feature one preset with a bit of motion and color to draw the eye.
  • Banner, avatar and accent color: make the page yours.
  • Layout and type style: pick the overall look.
  • Leaderboard: show or hide your top tippers.

Tip alerts

A confirmed tip fires your Tip alert on the overlay. Style that alert in the alert designer, and use variations if you want larger tips to look different or only show an alert above a certain amount.

Where tips are confirmed

PayPal notifies us when a payment clears, and only then is the tip marked confirmed and the alert fired. A viewer who starts but does not complete a payment will not trigger anything.

Previous Your tip page Next Merch with Fourthwall
Monetize/Merch with Fourthwall
Monetize

Merch with Fourthwall.

Connect your Fourthwall shop and merch sales fire alerts on stream, the same way subs and tips do. You can react differently to different products, collections or order sizes.

Connecting

Go to Settings, then Connections and connect Fourthwall. You authorize once, and we register to receive your orders and sync your collections and products so you can build alerts around them.

Merch alerts

Once connected, a Merch alert becomes available in the widget picker. When an order is placed, the alert fires with tokens you can drop into the design:

TokenShows
{product}The first item in the order.
{random_product}A random item from the order, fun for multi-item orders.
{product_list}Every item, comma separated.
{item_count}How many items.
{total_display}The order total with its currency symbol.
{first_product_image}The image of the first product.

Variations for merch

Merch works with variations too. Match on the order total, the number of items, or which collections and products are in the order, so a "Limited" drop or a big order gets its own celebration.

Privacy first

We only receive what an alert needs (products, totals, and an optional buyer name). Buyer email, address and payment details never reach the overlay.

Test it

You can fire a test merch alert and even simulate which collections an order belongs to, so you can confirm your variations behave before a real sale comes in.

Previous Tip settings Next AI Magic Builder
Build your own/AI Magic Builder
Build your own

AI Magic Builder.

Describe the widget you want in plain language and OverlayThing builds a styled, editable widget on your canvas. A fast way past a blank overlay, and a head start on custom code.

How it works

Open Magic Builder, type a prompt, and a new custom widget is generated, themed and editable. You get a preview before it lands on your canvas, and you can refine it in plain language ("make the font bigger", "use orange") without starting over.

promptexamples
› a cyberpunk follower goal with a neon progress bar
› a minimal latest-sub label for the top-left
› a raid alert that slides in from the right

Tips for good prompts

  • Name the kind of widget: goal, alert, label, counter.
  • Describe the vibe: cyberpunk, soft pastel, retro arcade.
  • Mention placement, colors and motion if you care about them.

It is a starting point

Generated widgets are normal custom widgets. The builder pulls out the obvious things to tweak (colors, fonts, sizes) as editable fields, and you can open the code at any time to take it further.

Reviewed before it lands

Generated code is checked against safety rules before you ever see it. If something looks risky you will get a warning, and clearly off-topic requests are politely declined.

Previous Merch with Fourthwall Next Custom widgets
Build your own/Custom widgets
Build your own

Custom widgets.

For when you want to break the mold. Write your own HTML, CSS and JavaScript, react to live events, and build something we would never ship. Sandboxed, with a real code editor.

The code editor

A custom widget has tabs for HTML, CSS, JS, Fields and a Console. Write your markup and styles, add behavior in JavaScript, and watch logs and errors live in the console while you work.

Fields

Define a fields schema and the editor builds an inspector form for it automatically, so you (or anyone using your widget) can change colors, text and numbers without editing code. Field values are available in your HTML and CSS as {{tokens}} and in your JavaScript through the event payload.

StreamElements compatible

If you are coming from StreamElements, you can paste an existing custom widget and it will largely work as-is. The event API and field system mirror theirs, with a few documented differences.

What you can rely on

  • animate.css is always available for entrance and exit animations.
  • jQuery is loaded automatically if your code uses it.
  • You can pull libraries and assets from common CDNs, and add your own to the allow-list per widget.
  • Persistent state survives reloads through a small per-widget storage API.
Sandboxed for a reason

Custom code runs in an isolated frame with no access to your account or tokens. It can react to events and draw to the overlay, nothing else. Heavy scripts can drop frames on stream, so test under load.

Ready for the API? See the Widget SDK.

Previous AI Magic Builder Next Widget SDK
Build your own/Widget SDK
Build your own

Widget SDK.

The API your custom widgets use to receive live events and persist state. It is intentionally compatible with StreamElements, so the global is available as both OL_API and SE_API.

Receiving events

Events are delivered as standard DOM events on window. The two you will use most are onWidgetLoad (fires once with your starting data) and onEventReceived (fires for every live event).

overlay.jsjs
window.addEventListener('onEventReceived', function (obj) {
  if (obj.detail.listener === 'cheer-latest') {
    var e = obj.detail.event;
    if (e.amount >= 1000) confettiBurst(e.name);
  }
});
Not an emitter

There is no OverlayThing.on(...) method. Subscribe with window.addEventListener and switch on obj.detail.listener.

Event listeners

listenerdetail.event payload
subscriber-latest{ name, amount, tier, message?, months?, gifted?, sender? }
cheer-latest{ name, amount, message? }
follower-latest{ name }
tip-latest{ name, amount, currency, message? }
raid-latest{ name, amount }
message{ data: { displayName, text, emotes, badges, ... } }
delete-message / delete-messages{ msgId } / { userId }
bot:counterA chatbot counter changed. Carries the counter and its new value.
event:testA sample event, shaped like the listener being tested.

The message, delete-message and delete-messages listeners carry live chat. The bot:counter listener fires whenever a chatbot counter changes, so a custom widget can react to a death count going up in real time.

onWidgetLoad

Fires once when your widget mounts. The detail carries your channel info, your field values, recent events, and a session-totals dictionary.

overlay.jsjs
window.addEventListener('onWidgetLoad', function (obj) {
  var d = obj.detail;
  var name = d.channel.username;
  var fields = d.fieldData;
  var recent = d.recents;        // last events, oldest first
  var totals = d.session.data;   // session / week / month counts
});

The OL_API object

MethodWhat it does
store.get(key) / store.set(key, value)Persist small values per widget, across reloads.
counters.get(name) / counters.set(name, n) / counters.add(name, n)Read or change a persisted counter. Values survive reloads and OBS source resets.
sanitize({ message })Run text through your channel moderation.
cheerFilter(text)Strip cheermote tokens out of a message.
getOverlayStatus()Find out if you are in the editor and whether audio is muted.
setField(key, value)Editor only. Update one of your widget fields from code.
alertEnded() / resumeQueue()Tell the alert queue your alert has finished so the next one can play.
Built for StreamElements parity

The global is exposed as both OL_API and SE_API, so a pasted StreamElements widget runs unmodified. Counters persist (they are backed by the same per-widget storage as store), live chat arrives on the message and delete-message listeners, and the chatbot pushes counter changes through bot:counter. A few SE-only methods exist purely as no-op stubs for compatibility. The full reference lives in the in-app docs for custom widgets.

Previous Custom widgets Next Dashboard
Your data/Dashboard
Your data

Dashboard.

Your home base. The numbers that matter at a glance, a chart to spot trends, and a live feed of everything happening on your channel.

The stat cards

Across the top: followers, subscribers, tips, raids, bits and channel-point redemptions, each compared against the previous period. Use the period selector to switch between day, week, month and all time.

Chart and activity

The chart breaks any of those metrics down over time, with best day, average and total. Below it, the activity feed is a searchable, filterable log of every event: subs, follows, tips, raids, cheers, redemptions and merch. Gifted subs are grouped into a single tidy row.

Quick controls

  • Active overlays: which of your overlays have been live on your stream recently.
  • Connections: at-a-glance status for Twitch, PayPal, Fourthwall and StreamElements.

Controlling alerts live

The Alert controls card lets you steer alerts mid-stream without leaving your game:

  • Pause / resume: hold all alerts (they queue up and play once you resume), handy during an intense moment or a break.
  • Mute text to speech: silence TTS while still showing alerts on screen.
  • Skip: drop the alert currently playing and move to the next one.

Each of these also has a Stream Deck URL you can copy onto a button, so a single press pauses, mutes or skips without alt-tabbing.

Your API token

Those Stream Deck URLs are authorized by your channel API token, the same token that powers the chat log API. You can copy it from the Alert controls card, and reset it if it ever leaks.

Resetting affects everything that uses it

Because one token powers both your Stream Deck URLs and the chat-log API, resetting it stops the old ones working immediately. Re-copy the new URLs afterward.

Previous Widget SDK Next Stream data
Your data/Stream data
Your data

Stream data.

The numbers behind your overlay. Labels, goals and leaderboards all read from here, so this is the source of truth for what is on screen, and the place to fix anything that looks off.

The tabs

TabWhat it holds
LatestThe most recent of each event type, with editable fields that power your label tokens.
RecentA read-only history of the last events per type.
GoalsRunning totals, plus the target and current value for each goal widget.
AggregatesTotals for the session, week, month or all time.
LeaderboardsTop tippers, cheerers, sub gifters and raiders by window.
SettingsHow periods are counted and your session grace period.

Fixing the numbers

Real events occasionally need a human touch: a tip came in off-platform, or a label shows the wrong name. On the Latest tab you can edit those values directly, and every widget that reads them updates to match. Session aggregates (like top tipper this stream) can be corrected too.

Sessions and periods

A stream session starts when you go live and ends when you go offline. In Settings you can set a grace period (how long a brief disconnect still counts as the same session) and choose whether week and month mean rolling windows (last 7 or 30 days) or calendar periods.

One source, everywhere

Because every widget reads from Stream Data, fixing a number here fixes it across your overlay, labels and leaderboards at once.

Previous Dashboard Next Chat log
Your data/Chat log
Your data

Chat log.

A searchable archive of your chat, events and moderation actions. Look up what a viewer said, find that clip-worthy moment, or review a timeout after the fact.

Beta feature

The chat log is currently a beta feature. If you do not see it, it may not be enabled for your account yet.

Searching

Search by user, by message text, or by date, and filter the feed by type:

  • Chat: regular messages.
  • Commands: messages that start with an exclamation mark.
  • Events: subs, cheers, raids, follows, redemptions and tips.
  • Moderation: timeouts, bans, warnings and clears.

Results render with emotes, badges and the context of each event, and clearly mark anything that was deleted or blocked.

Access and exclusions

Reading the chat log over the API uses your channel API token, the same one that authorizes the Stream Deck alert controls. You can reset it at any time (which also rotates those control URLs), and you can keep a list of bot accounts to exclude so automated chatter does not clutter your history.

Previous Stream data Next Moderation
Your data/Moderation
Your data

Moderation.

Every chat message, tip note and alert message runs through a moderation pipeline before it reaches your overlay or gets read aloud. You add your own banned words and decide where moderation applies; OverlayThing handles the heavier filtering automatically.

What happens to a message

When text comes in, it is checked layer by layer and ends in one of three outcomes:

OutcomeWhat it means
AllowedNothing matched. The message shows and is read aloud normally.
RedactedSpecific words were replaced (with [redacted] on your overlay, or *** on the tip page). The rest of the message still shows.
BlockedThe whole message is hidden. Viewers see nothing, and it is never read aloud.

What you control

Banned words

In Settings, under Moderation, keep your own list of banned words and phrases (type them comma or line separated). Matching is case-insensitive, and your words are redacted rather than blocking the whole message. They apply across your chat box, alert text, text to speech, and tip page messages. Banned words imported from StreamElements land in this same list.

Chat box filtering

Your chat box widget has its own switches: turn moderation on or off for that widget, include or hide your own messages, and exclude bot accounts. These are per widget, so two chat boxes can behave differently.

What runs automatically

On top of your banned words, OverlayThing applies platform-wide protection you do not have to configure:

  • A global blocklist of known-bad content.
  • Link filtering, so raw URLs do not get read aloud or splashed on screen.
  • Spam guards for things like all-caps walls and emoji floods.
  • AI moderation that catches hateful, harassing or explicit content even when no specific word is on a list.

You cannot tune these yourself, but you always see when they fire.

Reviewing what was caught

Moderated events are not silent. On your dashboard activity feed, anything redacted or blocked carries a badge you can expand to see what triggered it, the original text, and exactly what your viewers saw. Your chat log also keeps a moderation record you can search.

Get pinged in Discord

In Settings, under Moderation, add a Discord webhook and OverlayThing will post there whenever something is caught, with the original message, the cleaned version, and the reason. Handy for catching what slipped past on a busy stream.

For custom widgets

If you build a custom widget that shows viewer text, run it through the same pipeline with the SDK sanitize call before displaying it, so your custom code respects the same rules as everything else.

What you see vs what viewers see

You always see the original text in your own tools so you know what happened. Viewers only ever get the cleaned or blocked result.

Previous Chat log Next Settings & connections
Account/Settings & connections
Account

Settings & connections.

Your account, your connected services, and the controls that protect your access.

Account

Your profile comes from Twitch: your name, avatar and email sync automatically. You can set your time zone here, which keeps your stats lined up with your own day.

Connections

ServiceWhat it is for
TwitchYour sign-in and the source of every alert. Re-authorize here if scopes ever need refreshing.
PayPalThe account that receives tips. Set it up in Tip settings.
FourthwallConnect your shop so merch sales fire alerts.
StreamElementsUsed when importing your existing setup.

Notifications

Choose what you want to hear about by email (tips received, overlay or connection problems, a weekly digest, product updates), and optionally point a Discord webhook at your notifications or moderation events.

Security and data

  • Active sessions: see where you are signed in and sign out other devices.
  • Export your data: download everything in one click. See Export your data.
  • Delete your account: a confirmation starts a grace period during which you can still change your mind before anything is permanently removed.
Previous Moderation Next Export your data
Account/Export your data
Account

Export your data.

Your data is yours. From Settings, under Data and privacy, you can take it with you in a click, from a quick JSON snapshot to a complete ZIP with every asset.

Three ways to take it

OptionFormatBest for
Download my dataZIPA complete, verifiable copy including your media files.
Export everythingJSONA quick, readable snapshot to inspect or script against.
Encrypted full archiveEncrypted ZIPA secure off-site backup you keep under your own passphrase.

Download my data

The full takeout. One click builds a single ZIP containing your channel, every overlay with its widgets and variations, your tip settings, the last 90 days of events, and every asset binary (your uploaded images, video and sound). Use this when you want a complete, verifiable copy of everything we hold for your channel.

Export everything (JSON)

A lighter, one-click option. It bundles your overlays, alerts, labels, session data and tip records into a single JSON file, with no asset binaries (grab those with Download my data). It downloads named like this:

download
overlaything-export-yourname-2026-06-05.json

Because it is plain JSON, you can open it in any text editor or process it with your own scripts.

Encrypted full archive

For a backup you control end to end. Set a passphrase and choose what to include (configs, plus optionally your assets, events and chat-log history). We build an encrypted bundle and email you a one-hour download link. You decrypt it locally with the age tool.

Keep your passphrase safe

The encrypted archive is decrypted locally with your passphrase. If you lose the passphrase, the archive cannot be recovered, by you or by us.

Secrets are never included

None of these exports contain passwords or connected-service credentials. Your Twitch tokens, PayPal details and similar are excluded or redacted.

Moving in, not out?

If you are coming from another platform, the StreamElements import brings your existing setup and history into OverlayThing.

Previous Settings & connections Next Import from StreamElements
Account/Import from StreamElements
Account

Import from StreamElements.

Already set up elsewhere? Bring your overlays, alert settings, goals and history across so you are not starting from scratch.

Classic overlays only

The import reads your classic StreamElements overlays. The newer "Elements" overlay system from StreamElements is a separate product on a separate API, and we do not import it. If your setup was built in the Elements editor, it will not come across.

What comes over

From StreamElementsBecomes
Classic overlaysEditable overlays, with built-in widgets mapped to ours and custom widgets brought across as custom code.
Alert settingsPer-event styling, sounds and thresholds.
GoalsNative goal widgets with your targets.
Tip and donation historyRecords in your Stream Data and leaderboards.
Tip page settingsYour presets, currency and banned words.
Uploaded assetsRe-hosted and re-linked inside your overlays.

What does not come over

The import is about your overlays and your history. Whole StreamElements products that have no OverlayThing counterpart are not touched and are not imported:

  • "Elements", StreamElements' newer overlay system that replaced classic overlays. We import classic overlays; anything built in the Elements editor lives on a separate StreamElements API and is not picked up.
  • Your StreamElements chat bot, commands and timers.
  • Your loyalty points and store.
  • Merch and sponsorship deals.
  • Giveaways and contests.

Those keep running in StreamElements exactly as they did.

Running an import

1

Connect StreamElements

Paste your StreamElements token so we can read your existing setup. We show you what we found before anything is imported.

2

Choose what to bring

Pick which overlays and which data to import, and make a few choices up front (keeping original overlay sizes, how to handle alert boxes, and what to do with disabled events).

3

Review and run

Resolve any asset name clashes or font swaps, then start the import. It runs in the background and shows progress as it goes.

4

Check the result

Open each imported overlay and confirm the mapping. If anything is off, you can roll the whole import back and try different choices.

Custom code does not always convert cleanly

Bespoke StreamElements widgets come across as custom widgets, but the most advanced ones (those that relied on StreamElements-only features) may need a little rework in the custom code editor.

Tips are normalized to USD

Imported donation history is stored in USD. Your going-forward tip currency is set in Tip settings.

A best effort, not a one-to-one guarantee

The import reads StreamElements through their public data format. If that format changes or stops being available, the import can break until we update it, and we will do our best to keep up. Even working perfectly, an exact one-to-one copy is not something we can promise: the two overlay systems are built on fundamentally different foundations, so some things are recreated as the closest OverlayThing equivalent rather than reproduced identically.

Previous Export your data Next Label tokens
Reference/Label tokens
Reference

Label tokens.

Tokens are {placeholders} you drop into alert text, label templates and goal labels. They fill in with live values when the widget renders. This is the full set, grouped by where you use them.

Subscriber alert

TokenValue
{name}The subscriber.
{tier}Tier 1, 2, 3 or Prime.
{months}Months in this sub.
{cumulative_months}Total months subscribed.
{streak_months}Current consecutive months.
{gift_count}Number of gifts in a gift batch.
{sender}The gifter, on gifted subs.
{message}The resub message.

Cheer, tip, raid, follow

TokenValue
{name}The viewer (cheerer, tipper, raider or follower).
{bits}Bits cheered.
{amount}Tip amount, or raid viewer count, depending on the alert.
{currency}Tip currency.
{viewers}Raid viewer count.
{message}Cheer or tip message.

Channel points & shoutout

TokenValue
{name}The redeemer, or the channel you shouted out.
{reward_title}The reward redeemed.
{reward_cost}The point cost.
{user_input}The message attached to a redemption.

Merch alert

TokenValue
{product}First item in the order.
{random_product}A random item from the order.
{product_list}All items, comma separated.
{item_count}Number of items.
{total_display}Order total with currency symbol.
{first_product_image}Image of the first product.
{matched_category}The collection the order matched.

Goals

TokenValue
{current}Current progress.
{target}The goal target.
{progress_pct}Progress as a percentage.
{remaining_to_target}How much is left.
{metric_label}The metric name.
{period_label}The period, like This stream.

Countdown & subathon

TokenValue
{remaining}Time left, formatted.
{elapsed}Time elapsed, formatted.
{added_total}Total time added from events (subathon).
{last_event_user}Who last added time (subathon).

Data labels

TokenValue
{latest_follower}Most recent follower.
{latest_sub_name}Most recent subscriber.
{latest_tipper}Most recent tipper.
{latest_cheer_name}Most recent cheerer.
{session_followers}Followers this session.
{session_subs}Subs this session.
{7d_followers}Followers in the last 7 days.
{30d_subs}Subs in the last 30 days.
Unknown tokens

If you type a token that does not exist, it renders as empty rather than breaking the widget, so a small typo will not take your overlay down.

Previous Import from StreamElements Next Keyboard shortcuts
Reference/Keyboard shortcuts
Reference

Keyboard shortcuts.

The editor is built for the keyboard. These are the ones worth learning.

Editing

Undo⌘+Z
Redo⌘+⇧+Z
Delete selectedDel
Deselect / exit text editEsc

Layout

Group selected⌘+G
Ungroup⌘+⇧+G
Nudge 1px↑↓←→
Nudge 10px⇧+↑↓←→

These docs

Search the docs⌘+K
On Windows

Use Ctrl wherever these show the Command key.

Previous Label tokens Next Troubleshooting
Reference/Troubleshooting
Reference

Troubleshooting.

Quick fixes for the things that trip people up most.

My overlay is blank on stream

  • Check the URL in your browser source matches your current overlay URL. If you regenerated it, re-paste the new one.
  • Set the source size to your overlay resolution and make sure it is not sized to zero.
  • Refresh the browser source cache in your streaming software.

Alerts are not firing

  • Use Test Alert. If the test shows but real events do not, re-authorize Twitch from Settings, then Connections.
  • Check that a variation is not filtering the event out, and that the alert is on the overlay you are actually using.
  • For tips, confirm PayPal is connected and the tip clears any minimum you set.
  • For merch, confirm Fourthwall is connected.

No alert sound

  • Add the overlay browser source to your streaming software audio mixer. It may be muted by default.
  • Check the alert sound is on and its volume is up in the designer, and the same for text to speech.

Edits are not showing on stream

  • Give it a second. Edits autosave and push to connected sources on their own.
  • If a source has shut down when not visible on, switch scenes back to it to reload.
  • As a last resort, refresh the browser source cache in your streaming software.
Still stuck?

Reach out from the help option in the toolkit and we will take a look.

Previous Keyboard shortcuts
On this page
ESC
Get started
Overlays
Chatbot
Remote Control
Widgets
Monetize
Build your own
Your data
Account
Reference
↑↓ navigate ⏎ open esc close