New Shoutouts API and EventSub subscription types are now in open beta

Update (2023-02-09): The API endpoint and EventSub subscription types have been promoted from open beta to generally available.

Last year, Twitch launched shoutouts, a new feature for streamers and their moderators to support other streamers by sharing their follow button in chat with the /shoutout command. Streamers who receive shoutouts see a notification their activity feed with the number of viewers they were shouted out to. We immediately received UserVoice suggestions for both an API endpoint to create shoutouts and EventSub subscription types to track when shoutouts happen.

Today weā€™re excited to launch the open beta Twitch API endpoints and EventSub subscription types for this new feature!

New Twitch API Endpoint

New EventSub Subscription Types

New Scopes

  • moderator:read:shoutouts - Read a broadcasterā€™s shoutouts.
  • moderator:manage:shoutouts - Manage a broadcasterā€™s shoutouts.

How do I get started?

The new endpoints and subscriptions types are publicly available in an open beta. Visit the documentation links above to start implementing shoutout functionality today. Once all UserVoice feedback is considered during the open beta, this functionality will become ā€œgenerally available,ā€ meaning no further updates or changes can be expected unless formally announced here on the forums.

If you have any questions or want to share how youā€™ll use these endpoints, please feel free to comment below.

3 Likes

Appreciate the moderator scopes on this :+1:

Edit: .receive is correctly moderator scoped, but .create should not be. Example use case is: third-party chat applications like chatterino/chatty that would like normal users to be able to see outbound shoutouts. Now uservoiced @ Shoutout Create EventSub Subscription should not require moderator auth ā€“ Twitch UserVoice

3 Likes

The docs for ā€˜channel.shoutout.createā€™ and ā€˜channel.shoutout.receiveā€™ EventSub subscriptions note ā€˜broadcaster_user_idā€™ as optional and ā€˜moderator_user_idā€™ as required in the ā€˜conditionā€™, yet not setting the ā€˜broadcaster_user_idā€™ when trying to subscribe throws a validation error:

data {
  error: 'Bad Request',
  status: 400,
  message: "unknown validation error: Key: 'SubscriptionCondition.broadcaster_user_id' Error:Field validation for 'broadcaster_user_id' failed on the 'required' tag"
}
config {
  transitional: {
    silentJSONParsing: true,
    forcedJSONParsing: true,
    clarifyTimeoutError: false
  },
  adapter: [ 'xhr', 'http' ],
  transformRequest: [ [Function: transformRequest] ],
  transformResponse: [ [Function: transformResponse] ],
  timeout: 0,
  xsrfCookieName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
  maxContentLength: -1,
  maxBodyLength: -1,
  env: {
    FormData: [Function: FormData] {
      LINE_BREAK: '\r\n',
      DEFAULT_CONTENT_TYPE: 'application/octet-stream'
    },
    Blob: null
  },
  validateStatus: [Function: validateStatus],
  headers: AxiosHeaders {
    Accept: 'application/json, text/plain, */*',
    'Content-Type': 'application/json',
    Authorization: '<redacted>',
    'Client-Id': '<redacted>',
    'User-Agent': 'axios/1.2.2',
    'Content-Length': '175',
    'Accept-Encoding': 'gzip, compress, deflate, br'
  },
  method: 'post',
  url: 'https://api.twitch.tv/helix/eventsub/subscriptions',
  data: '{"type":"channel.shoutout.create","version":"beta","condition":{"moderator_user_id":"<redacted>"},"transport":{"method":"websocket","session_id":"<redacted>"}}'
}

The same happens if only providing the ā€˜broadcaster_user_idā€™.
It only works when providing both at the moment.

Filed on github: Shoutout Create/Recieve - broadcaster_user_id not actually optional? Ā· Issue #710 Ā· twitchdev/issues Ā· GitHub

Edit: oh I suspect itā€™s a documentation bug but weā€™ll need the powers that be to intervene

1 Like

Documentation bug! Both fields are required

Thanks for the quick feedback on this! We have updated the documentation today to reflect that broadcaster_user_id is required.

Regarding the EventSub events, I find it strange that:

  • channel.shoutout.create has to_broadcaster_user_id but, unlike other from/to events, there is no from_broadcaster_user_id (instead it is just named broadcaster_user_id)

  • channel.shoutout.receive has from_broadcaster_user_id, but unlike other from/to events, there is no to_broadcaster_user_id (instead it is just named broadcaster_user_id)

Essentially, this naming seems inconsistent with other eventsub subscription typesā€¦ does this distinction exist because the condition object only has broadcaster_user_id (without an explicit from/to prefix)?

Would it not be better to follow the example of channel.raid where there is only one subscription type & you either specify from_broadcaster_user_id or to_broadcaster_user_id?

Edit: the activity feed mess may be related to this distinction but I donā€™t understand why you need to tie yourself to that system if you have all the .create events

Iā€™ve been trying to implement this today as part of an existing script we have for on-stream alerts and discovered shout outs canā€™t be processed (400 - bad response) when the streamer is not currently streaming and I am completely baffled as to why that is.

The vast majority of shout outs we do are when streamers stop by in their offline time, so this end point canā€™t be used to do itā€™s job. If someone has just raided then by the very nature of raiding, theyā€™re no longer streaming, so again, it canā€™t be used in that context either, so really what is the point? I guess Iā€™m going to have to go back to trying to figure out how to write my own chatbot app from scratch in order to work around this incredibly stupid and frustrating ā€˜featureā€™.

The streamer youā€™re getting the error for is the channel from where youā€™re sending the shoutout from.
So for example if I want to shoutout BarryCarlyon, I have to be live and have more than 1 viewer.

You should check the body of the repsonse itā€™ll describe the error.

As @Dkamps18 noted:

  • The Target Channel: online status doesnā€™t matter.
  • The Source Channel: has to be online.

So if you want to Shoutout somechannel then you need to be live, the state of somechannel is irrelevant.

See also the Help guide - Twitch Help Portal

1 Like

Ok, Iā€™m a dumb**s - thank you for pointing out my mistake! I retract my entire complaint! Iā€™m honestly very grateful, if also slightly embarrassed! Although I will say Iā€™m not the only person I know who mis-read it as such!

Hello, i have 401 error with this code , i donā€™t understand.

  axios.post(
    `https://api.twitch.tv/helix/chat/shoutouts?from_broadcaster_id=${from_broadcaster_id}&to_broadcaster_id=${to_broadcaster_id}&moderator_id=${moderator_id}`,
    {
      headers: {
        Authorization: "Bearer " + process.env.TWITCH_OAUTH_TOKEN,
        "Client-ID": process.env.TWITCH_CLIENT_ID,
        "Content-Type": "application/json",
      },
    }
  );

what is ā€œmoderator_idā€ ? i use tmi.js , how can i get ā€œmoderator_idā€ ? (i can use twitch api request)

As stated in the Send a Shoutout docs, the moderator_id is

The ID of the broadcaster or a user that is one of the broadcasterā€™s moderators. This ID must match the user ID in the access token.

So you need to make sure that the Moderator ID matches that of the User Token youā€™re using to make the request. If the token is the from the broadcaster, then the broadcaster id and moderator id would be the same. You can get the moderators id the same way you get any other users id, although Iā€™d recommend the Validate Tokens endpoint as that would ensure youā€™re using the correct token, as the id in the token has to match the one in your request.

Also, Iā€™d recommend logging the body of the response you get, as it will more clearly explain what the issue is other than just 401.