StreamElements API

StreamElements socket.io

onEventReceived examples

StreamElements socket.io

StreamElements socket.io URL is https://realtime.streamelements.com and you can authenticate to it using JWT, oAuth2 and overlay token. It uses "websocket" transport.

It seems it is possible to connect directly using Websockets (not socket.io) to wss://realtime.streamelements.com, but this document will only relate to socket.io version (although it would apply to both).


Official StreamElements socket.io documentation is on Streamelements Developer Portal

There is also a new Websockets implementation called Astro (wss://astro.streamelements.com), which will not be covered here, but you can find more information at https://docs.streamelements.com/websockets.


How to connect:

It seems StreamElements still uses an old version of Socket.io, version 2. I was able to connect to the server using a recent client version, like 4.5.4, though. However, if you are having issues to connect to it, try to use an older client version to check if it works.

You need to use a socket.io library to connect to StreamElements socket. It is originally a JavaScript library, but you can find other client implementations at Socket.io website

HTML

        <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
      
JavaScript

        // This snippet is only an example to connect to the StreamElements socket.
        // For more information on how to read events, check the next section

        const url = "https://realtime.streamelements.com";
        const options = { transports: ["websocket"]};
        const token = ""; // Your JWT, overlay token (aka apikey) or oAuth2 token
        const method = ""; // "jwt", "apikey" or "oauth2", based on the token above
        const socket = io(url, options); // The connection is started here

        // Connect and authenticate
        socket.on("connect", onConnect);
        socket.on("authenticated", onAuthenticated);
        socket.on("disconnect", onDisconnect);
        socket.on("unauthorized", console.error);

        function onConnect() {
          console.log("Connected to StreamElements socket.");
          // After connected, authenticate:
          socket.emit("authenticate", { method: method, token: token });
        }

        function onAuthenticated(data) {
          const { channelId, clientId, message, project } = data; // available variables for data
          console.log(`Successfully authenticated to channel ${channelId} with id ${clientId}`);
          console.log(message);
        }

        function onDisconnect(data) {
          // The client will try to reconnect automatically if the reasons are different from 
          // "io server disconnect" and "io client disconnect" (manual disconnections)
          // In case you want to connect even when there is a manual disconnection, use:
          // if (reason === "io server disconnect" || reason === "io client disconnect") {
          //  socket.connect();
          // }
          console.log(`Disconnected from StreamElements. Reason: ${data}`);        
        }
      

Events

Every time a new event occurs, the socket will emit an event message (except for a chat message). Some events are listed below:

Reference

        "event"                       // normal events like follower, subscribers, channel points. Alerts in general
        "event:test"                  // Whtn the button to next alert is clicked. Also test events you can emit
        "event:update"                // Same as "event", but updates data
        "event:skip"                  // When alert is skipped
        "session:reset"               // When session data is reset
        "overlay:mute"                // When overlays are muted or unmuted
        "overlay:refresh"             // When overlays are refreshed
        "overlay:update"              // When an overlay is updated
        "overlay:action"              // When the "Reload overlays" is clicked on Activity feed
        "overlay:togglequeue"         // When overlays are paused or resumed
        "kvstore:update"              // When a kvstore data is updated (like overlay paused)
        "session:update"              // When an session update occurs (new bits, new follower, tips, etc)
        "bot:counter"                 // When a counter is updated
        "giveaway:state"              // When a giveaway is created or closed
        "contest:state"               // When a contest is created or closed
        "contest:winner"              // When a contest winner is picked
        "songrequest::mediashare"     // Information on media share
        "songrequest:play"            // When song request starts playing
        "songrequest:pause"           // When song request is paused
        "songrequest:song:next"       // When next song is chosen to be played
        "songrequest:song:previous"   // When previous song is chosen to be played
        "songrequest:queue:remove"    // When song is removed from queue (or declined from pending requests)
        "songrequest:queue:add"       // When song is added to the queue (or approved from pending requests)
        "songrequest:history:add"     // When song is added to the history
        "songrequest:volume"          // When volume is set for song
        "songrequest:settings:update" // When song request settings is changed
      

Receiving events

In order to receive events, add a socket.on function with the event name you want to receive:

If you want, you can add all events from the box above, each one in its own code block.

Javascript

        socket.on("event", (data) => {
          console.log("event received:", data);
          // Your logic here
        });

        socket.on("event:test", (data) => {
          console.log("event:test received:", data);
          // Your logic here
        })

        socket.on("overlay:action", (data) => {
          console.log("overlay:action received:", data);
          // Your logic here
        })
    

Or, you can use "socket.onAny()" function to listen to any events:

Javascript

        socket.onAny((eventName, ...args) => {
          console.log("New event:", eventName);
          console.log("Data:", args[0]);
          // Your logic here
        });
    

Rooms

Some rooms are available to subscribe on StreamElements socket. Here are the ones I could find (ACCOUNT_ID is your actual StreamElements account id):

Reference

        "songrequest::ACCOUNT_ID"
        "contests::ACCOUNT_ID"
        "giveaways::ACCOUNT_ID"
        "store::ACCOUNT_ID"
        "obs::ACCOUNT_ID"
        "kvstore::ACCOUNT_ID"
        "plarium::ACCOUNT_ID"
        "appsflyer::ACCOUNT_ID"
        "partner-integrations::ACCOUNT_ID"
        "audience-queue::ACCOUNT_ID"
    

Before you ask, I also don't know what for "plarium" and "appsflyer" are used. Plarium is the company who owns the game “Raid - Shadow Legends” (a very known StreamElements sponsorship) and AppsFlyer is a company that does analytics and campaigns management. "partner-integrations" is probably the room for sponsorships, but I could not test it.

As for "obs", well... I believe it has something to do with OBS. I couldn't test it, so I'm not sure. Please let me know if you know more about it.

Subscribe to a room

In order to join a room, emit a “subscribe” event with the room name. In JavaScript, you also need a third parameter, the callback. So, it should look like below:

JavaScript

        const id = "5a2ed5cc9a474a2c2bc4f0aa"; // your account id
        socket.emit("subscribe" , {"room": `giveaways::${id}`} , (error, data) => console.log(error, data));
      

Or you can subscribe to multiple rooms at the same time:

JavaScript

        const id = "5a2ed5cc9a474a2c2bc4f0aa"; // your account id
        const rooms = [ "songrequest", "contests", "giveaways", "kvstore", "store", 
                        "obs", "audience-queue", "partner-integrations", "plarium", "appsflyer" ];

        rooms.forEach( (room) => {
          socket.emit("subscribe" , {"room": `${room}::${id}`} , (error, data) => {
            if(error){
              console.error(`Error subscribing to ${room}::${id}:\n ${error.message}`);
              return;
            }
            console.log(data);
          });
        });
      

Other info

There are way more data that needs to be documented, but I don't remember what else to add here. In the meantime, take some time to admire the randomly generated image below: