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).
window.addEventListener('onEventReceived', function (obj) {
if (obj.detail.listener === 'cheer-latest') {
var e = obj.detail.event;
if (e.amount >= 1000) confettiBurst(e.name);
}
});There is no OverlayThing.on(...) method. Subscribe with window.addEventListener and switch on obj.detail.listener.
Event listeners
| listener | detail.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:counter | A chatbot counter changed. Carries the counter and its new value. |
| event:test | A 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.
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
| Method | What 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. |
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.