In the beginning App Access Tokens could just load public data, that didn’t need any oAuth scopes, from Twitch API. And so any given developers project had to maintain a user access token(s) for users of their application.
Then extensions were introduced, bundled in Extensions are Subscriber support, allowing extensions and their EBS to read a given viewers subscription status to a channel, outside of the Extension JS Helper function to check the status in client side code. That then leaves how does an Extension EBS (aka Backend Service) perform the same call (since you should never trust the client) to perform the same check.
And so Extension generated App Access Tokens, could call Get Broadcaster Subscriptions. The first endpoint that is scoped that an app access token could load on behalf of a user.
Since then various aspects of Twitch Developer Tools have come and gone, we lost WebSub, and we lost PubSub, and we lost both (over time) in favour of EventSub. There is a bunch of other stuff that happened but the important part here is that with the loss of PubSub, Eventsub achieved “featured parity” with PubSub and a number of other things introduced Chat over Eventsub.
EventSub
An Extensions ability to grant the ability for an app access token to call subscriber information is baked into the “install an extension” work flow.
But EventSub introduced the dual (or even triple) legged auth approach.
First a user will need to perform a user oAuth loop, either Implicit, Authorization Code, or DCF (Device Code Flow). This then creates a link between the user and the ClientID along with the scopes requested.
Combine that with the recently added Get Authorization By User endpoint to check what scopes your ClientID has to a given user, you can check permissions before trying to create EventSub Subscriptions for Webhooks or Conduits.
So for eventsub the pattern is:
- Check the conditions and scopes needed for the EventSub Type/Topic
- For the user’s in the condition get that user to user authenticate with the needed scopes
- Generate an active app access token (if you don’t have one already)
- Create the Subscription
As an aside you can use “user.authorization.grant” to easily monitor for new user authentications and create subscriptions as a follow up, if say your user token gen is air gapped from your Eventsub handler. This is a pattern I use on the IGDB Extension to monitor for authentications and create subscriptions to stream.online/offline and channel.update (which yes are public topics but become cost 0 _if_ the user is authenticate to the Client ID, and I use the user.authorization.revoke to unsubscribe since I only want to keep cost 0 subscriptions), becuase the IGDB Extension config page launches an implicit flow since I don’t need the user token ever I just need to auth so creating one with a refresh token is overkill, but I digress….
So that briefly is how EventSub dual legged auth operates.
Chat Over EventSub
Then along came Chat over Eventsub and a bunch of separate topics essentially providing IRC chat as a already JSON-ifed consumable feed.
This also came with Conduits and the ability for chat bots to scale to as many channels as needed, because the broadcaster auth’s the chatbot to be present on their channel. It is similar to how adding Discord Bot to a Discord Server works from a broadcaster point of view.
But chat over eventsub specified two user ID’s in the condition. (which yes can be the same ID but we’ll skip that for simplicity).
So first a developer would
- Create a Client ID (generally owned by their own Twitch profile but the other of a Client ID is irrelevant, it’s always whom auths to the client that is important)
- Create a Twitch account with the username of the bot they want to use
- User Authenticate the bot to the Client ID with the relevant scopes
- Then authentication any number of broadcasters to the Client ID
- Now you can rejoin all channels with one API request (update shard), great for restarts or outages, as restart the websocket, call update shard, and then the bot is back in all rooms, no more slow roll rejoins or rate limit joins/etc.
So that is briefly the triple legged auth of chat over eventsub.
So What about App Access Tokens on the API?
Send Chat Message was introduced at the same time as chat over eventsub and is the first “proper” endpoint that worked with App Access Tokens following prior auth from the user(s) involved, (the broadcaster_id and sender_id)
This meant that for “general” operations a chat bot still needed to load and maintain either the broadcasters user token for Start Commercial for example, or the bots own token for Banning a User from chat.
So a bot would be juggling and maintaining up to three tokens,
- A broadcasters token for broadcaster based operations
- A bot token for doing moderation actions (for example), or sending chat
- An app access token for subscription management (or sending chat)
But, now, as of yesterday! For the most part that is no more!
Well Spill the Beans then!
TWENTY ONE API endpoints now support this pattern of using an App Access Token after performing prior user(s) authentication(s). Look for the Beta tag under the Authorization section of each endpoint.
Here is the list:
- Start Commercial
- Get Ad Schedule
- Snooze Next Ad
- Get Chatters
- Update Chat Settings
- Send a Shoutout*
- Check AutoMod Status
- Manage Held AutoMod Messages
- Get AutoMod Settings
- Update AutoMod Settings
- Get Banned Users
- Ban User*
- UnBan User*
- Get Blocked Terms
- Add Blocked Term
- Remove Blocked Term
- Delete Chat Messages
- Get Moderated Channels
- Update Shield Mode Status
- Get Shield Mode Status
- Warn Chat User
Anything marked in bold with a * has additional scope requirements compared to the user token version, please check the docs, but I suspect your bot will likely already have obtained the scopes.
So now a chat bot broadly doesn’t need to maintain or even keep on file a user access token for itself or the broadcaster, as most general operations a bot is gonna do will work using the App Access Token. This also comes with the bonus that a user access code flow token is only good for 4 hours but an app access token is good for much longer. (Remember to utilise the Validate Token Endpoint to check time remaining on a token)
I’ll note that “Get Clips Download” supports this pattern, but that API was introduced with the pattern.
But a Sadness
However, the obvious missing endpoint that doesn’t support this pattern is Send Chat Announcement which I hope is supported soon, I think that’s the only one I need to token juggle for at the moment.
Summary
Thats it! Go forth an App Access Token! And hopefully more of the API will support this pattern over time!
If you need further help please join as over on the Twitch Dev Discord or Support Forums!






