EventSub Hype Train Begin Subscription

I’ve been trying to use the EventSub section of the API and I seem to be having an issue with getting a subscription to the channel.hype_train.begin subscription-type. My code works for channel.subscribe, channel.follow, channel.cheer, channel.raid and channel.channel_points_custom_reward_redemption.add but for some reason I get {error: “Forbidden”, status: 403, message: “subscription missing proper authorization”} returned when I try to create a subscription for Hype Train Begin.

According to the documentation in EventSub “You must include an app access token in all API requests.” My understanding is that this should use OAuth client credentials flow which I do in the first part of my code below. I get the token back without any issue but when I use that token in the subscription call, I get the error for this specific request while the others go through without any issue.

I am using Javascript to initiate the request and PHP to handle the callback for the server-side of things, although this error happens before it ever makes it to the callback url so the Javascript is the only relevant part of the code. I’m sure I’m being dumb and just overlooking something but I just can’t seem to figure out why the other EventSub requests work fine but this specific one doesn’t. Any help would be much appreciated.

Here is the relevant part of the Javascript code-

//Get Token
function authenticate(action, type) {

const eventscopes = 'channel:read:subscriptions channel:read:hype_train';
const token_url = 'https://id.twitch.tv/oauth2/token?client_id='+ clientid +'&client_secret='+ secret +'&grant_type=client_credentials&scope='+ eventscopes;

fetch(token_url, {
	method: 'POST'
})
.then(response => response.json())
.then(data => {
	const access_token = data.access_token;
	
	switch(action) {
		case 'subscribe':
		console.log(data);
		subscribe(access_token, type);
		break;
		case 'view':
		view(access_token);
		break;
		case 'remove_all':
		remove_all(access_token);
	}
	
});

}

//Subscribe to EventSub
function subscribe(token, type) {

if(type == 'channel.raid') {
	condition = {"to_broadcaster_user_id" : roomid};
} else {
	condition = {"broadcaster_user_id" : roomid};
}

const url = 'https://api.twitch.tv/helix/eventsub/subscriptions';

const headers = {
	'Client-ID' : clientid,
	'Authorization' : 'Bearer ' + token,
	'Content-Type' : 'application/json'
}

const body = JSON.stringify({
	"type": type,
	"version": "1",
	condition,
	"transport": {
		"method": "webhook",
		"callback": callbackurl,
		"secret": requestsecret
	}
});

console.log(headers);
console.log(body);

fetch(url, {
	method: 'POST',
	body: body,
	headers: headers
})
.then(response => response.json())
.then(data => console.log(data));

}

The 403 error indicates you don’t have permission to subscribe to that topic.

While creating an EventSub subscription requires an App Access Token, you still need a user to go through the Implicit, or Auth Code, flow to grant your app the permission, which in this case is channel:read:hype_train

Once a user has gone through your OAuth process and granted your app that permission, you can then use your App token to subscribe to the topic.

Requesting scopes when creating an App token does nothing, as app tokens aren’t associated with a user so at no point does a user agree to let you access whatever those scopes are asking for.

Ok I think I understand. Thank you for your help!

You were right (of course you knew that)! It turns out my other requests worked because I already had the implicit authorization from my previous coding using PubSub. I never set up Hype Train in that code which is why that one was the only one giving me the 403 error. I added the channel:read:hype_train scope to that part of it (I seem to have misunderstood where I was supposed to define my scopes as well) and now the subscription works perfectly. Thank you again for your help!