Error 401 incorrect user authorization on Modify Channel Information

I am trying to make a simple script in python to change stream title of my channel.
I registered my application and generated client ID and secret.
I am using OAuth client credentials flow to generate bearer token and it works.
Then im getting the broadcaster_id by using Get Users method.
I am then trying to use Modify Channel Information to change the title which results in error.

I’ll post the code and the script output in the next post.

That Endpoint requires a scoped token, thus an App Access Token from the Client Credentials Flow is insufficient.

You need to use one of the other two Flows to tie the Token to the correct user.

import requests
from urllib.parse import urlencode

client_id = '***'
client_secret = '***'

# auth
data = {
	'client_id': client_id,
	'client_secret': client_secret,
	'grant_type': 'client_credentials',
	'scope': 'channel:manage:broadcast'
}

response = requests.post('https://id.twitch.tv/oauth2/token', data=data).json()

print(response)

token = response['access_token']
headers = {
	'Client-Id': client_id,
	'Authorization': 'Bearer ' + token,
}

# get broadcaster id
data = {
	'login': ['Flexlolo']
}

url = 'https://api.twitch.tv/helix/users?' + urlencode(data, doseq=True)
response = requests.get(url, headers=headers).json()

print(response)

broadcaster_id = response['data'][0]


# change title
data = {
	'broadcaster_id': broadcaster_id,
	'title': 'NEW TITLE STRING'
}

url = 'https://api.twitch.tv/helix/channels?' + urlencode(data, doseq=True)
response = requests.patch(url, headers=headers).json()

print(response)

and the output looks like this:

{'access_token': '***', 'expires_in': 4712212, 'scope': ['channel:manage:broadcast'], 'token_type': 'bearer'}
{'data': [{'id': '89346924', 'login': 'flexlolo', 'display_name': 'Flexlolo', 'type': '', 'broadcaster_type': '', 'description': '', 'profile_image_url': 'https://static-cdn.jtvnw.net/jtv_user_pictures/77a99df0-48fc-4764-8d0b-29f6da6df736-profile_image-300x300.png', 'offline_image_url': '', 'view_count': 4972, 'created_at': '2015-04-24T07:05:45.847672Z'}]}
{'error': 'Unauthorized', 'status': 401, 'message': 'incorrect user authorization'}

Just now I tried to use OAuth authorization code flow.
I formatted the url with all needed parameters and redirect_uri=‘http://localhost’.
I opened the url in browser and authorized my app. After that I was redirected to localhost with authorization code in the url.
I used that code to form a new request in python to generate access token according to the api reference and it successfully generated it.
I then tried to just use that newly created token in my code that I posted before to make the last request and it gave me the same error.

Modified code

import requests
from urllib.parse import urlencode

client_id = '***'
client_secret = '***'

data = {
	'client_id': client_id,
	'redirect_uri': 'http://localhost',
	'response_type': 'code',
	'scope': 'channel:manage:broadcast'
}

url = 'https://id.twitch.tv/oauth2/authorize?' + urlencode(data, doseq=True)
print('Authorization URL:')
print(url)

code = input('ENTER CODE: ')
assert len(code) == 30

# auth
data = {
	'client_id': client_id,
	'client_secret': client_secret,
	'code': code,
	'grant_type': 'authorization_code',
	'redirect_uri': 'http://localhost'
}

response = requests.post('https://id.twitch.tv/oauth2/token', data=data).json()
print(response)

token = response['access_token']

headers = {
	'Client-Id': client_id,
	'Authorization': 'Bearer ' + token,
}

# get broadcaster id
data = {
	'login': ['Flexlolo']
}

url = 'https://api.twitch.tv/helix/users?' + urlencode(data, doseq=True)
response = requests.get(url, headers=headers).json()

print(response)

broadcaster_id = response['data'][0]


# change title
data = {
	'broadcaster_id': broadcaster_id,
	'title': 'NEW TITLE STRING'
}

url = 'https://api.twitch.tv/helix/channels?' + urlencode(data, doseq=True)
response = requests.patch(url, headers=headers).json()

print(response)

output of the script

Authorization URL:
https://id.twitch.tv/oauth2/authorize?client_id=***&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=channel%3Amanage%3Abroadcast
ENTER CODE: ***
{'access_token': '***', 'expires_in': 15181, 'refresh_token': '***', 'scope': ['channel:manage:broadcast'], 'token_type': 'bearer'}
{'data': [{'id': '89346924', 'login': 'flexlolo', 'display_name': 'Flexlolo', 'type': '', 'broadcaster_type': '', 'description': '', 'profile_image_url': 'https://static-cdn.jtvnw.net/jtv_user_pictures/77a99df0-48fc-4764-8d0b-29f6da6df736-profile_image-300x300.png', 'offline_image_url': '', 'view_count': 4972, 'created_at': '2015-04-24T07:05:45.847672Z'}]}
{'error': 'Unauthorized', 'status': 401, 'message': 'incorrect user authorization'}

This should be
boradcaster_id = response['data'][0]['id']
Currently, you are passing the entire object as the id, and the token obviously does not match that, so it errors out.

I fixed the code as you suggested and it worked.
Is there a way to automate this authorization procedure so I dont have to manually generate and enter new code every time I launch the script? I know I can renew the acces_token every ~4 hours, but I am not planning on running the script all day.
I’m also thinking about temporarily hosting my own page at localhost just to automate recieving the code after redirect to it. Any suggestions?

That is exactly the way to do it.

Additionally, you can save the refresh token, which does not expire (at least not for the foreseeable future.)
Just refresh at startup.

1 Like

Thank you for your help, problem solved.