[Solved] Keep getting a 403 when editing channel info

For some reason when I started using the v3 API I was able to edit my channel info but now it just throws a 403 error, is there any way to fix this because the error isn’t documented.

To be more specific this is the error received:

Array
(
    [error] => Forbidden
    [status] => 403
    [message] => The current authorization is not valid for this context
)

Error 403: You don’t have permission to complete the operation or access the resource.

1. Invalid Access Token

The access tokens may be invalidated, if your application requests another token, your application is suspended, or the user de-authorizes your application. (Ex. You request 2 consecutive chat_login tokens, the first will be invalidated.)

You can check if a token is invalid by making a request to Twitch’s API Endpoint, GET / - Get top level links object and authorization status, with the token you’re testing in a header.

GET /

Basic information about the API and authentication status. If you are authenticated, the response includes the status of your token and links to other related resources.

Example Request

curl -H 'Accept: application/vnd.twitchtv.v3+json' -H 'Authorization: OAuth <access_token>' \
-X GET https://api.twitch.tv/kraken

Example Response

{
  "token": {
    "authorization": {
      "scopes": ["user_read", "channel_read", "channel_commercial", "user_read"],
      "created_at": "2015-11-12T06:39:44Z",
      "updated_at": "2015-11-12T07:21:20Z"
    },
    "user_name": "test",
    "valid": true
  },
  "_links": {
    "channel": "https://api.twitch.tv/kraken/channel",
    "users": "https://api.twitch.tv/kraken/users/test",
    "user": "https://api.twitch.tv/kraken/user",
    "channels": "https://api.twitch.tv/kraken/channels/test",
    "chat": "https://api.twitch.tv/kraken/chat/test",
    "streams": "https://api.twitch.tv/kraken/streams",
    "ingests":"https://api.twitch.tv/kraken/ingests",
    "teams": "https://api.twitch.tv/kraken/teams",
    "search": "https://api.twitch.tv/kraken/search"
  }
}

2. Authentication Scope requirements.

You request access to this information using the channel_editor scope parameter, which your app must include in its authentication request.

#3. Update channel’s status or game.

Authenticated, required scope: channel_editor

Parameters

status | optional | string | Channel’s title.
game | optional | string | Game category to be classified as.
delay | optional | string | Channel delay in seconds. Requires the channel owner’s OAuth token.

Form-encoded or JSON parameters specifying the properties to change. These should be under a channel object:

{
  "channel": {
    "status": "twitch n chill?",
    "game": "CS:GO",
    "delay": 60
    }
}

Example Request

curl -H 'Accept: application/vnd.twitchtv.v3+json' -H 'Authorization: OAuth <access_token>' \
-d "channel[status]=twitch+n+chill?&channel[game]=CS:GO&channel[delay]=60" \
-X PUT https://api.twitch.tv/kraken/channels/test

Example Response

{
  "mature": false,
  "status": "twitch n chill?",
  "broadcaster_language": "en",
  "display_name": "test",
  "game": "CS:GO",
  "delay": 60,
  "language": "en",
  "_id": 12345,
  "name": "test",
  "created_at": "2007-05-22T10:39:54Z",
  "updated_at": "2015-02-12T04:15:49Z",
  "logo": "",
  "banner": "",
  "video_banner": "",
  "background": null,
  "profile_banner": "",
  "profile_banner_background_color": "null",
  "partner": true,
  "url": "http://www.twitch.tv/test",
  "views": 10000000,
  "followers": 10000000,
  "_links": {
    "self": "https://api.twitch.tv/kraken/channels/test",
    "follows": "https://api.twitch.tv/kraken/channels/test/follows",
    "commercial": "https://api.twitch.tv/kraken/channels/test/commercial",
    "stream_key": "https://api.twitch.tv/kraken/channels/test/stream_key",
    "chat": "https://api.twitch.tv/kraken/chat/test",
    "features": "https://api.twitch.tv/kraken/channels/test/features",
    "subscriptions": "https://api.twitch.tv/kraken/channels/test/subscriptions",
    "editors": "https://api.twitch.tv/kraken/channels/test/editors",
    "teams": "https://api.twitch.tv/kraken/channels/test/teams",
    "videos": "https://api.twitch.tv/kraken/channels/test/videos"
  }
}
1 Like

I’ve already done everything that’s been listed in your post. The user can’t even send a request to the server unless their token is valid. Also, channel_editor is the requested scope. As I said in the OP, it worked before but doesn’t now for some reason.

can you please provide a snippet of the code you are using and the parameters you are passing to the PUT /channels/{channel}/ endpoint? I will test to see if the bug can be reproduced.

1 Like

It’s not actually functional, I just took the bare-minimum from the class I wrote for it.

<?php
define("CHANNEL_NAME", "se7ensinslivestream");
define("OAUTH_TOKEN", "removed");

$response = set_channel_info($channel_status, $channel_game);

public function set_channel_info($status = null, $game = null, $delay = 0)
{
	$params = array("channel" => array());
	if(!is_null($status))
	{
		$params["channel"]["status"] = $status;
	}
	if(!is_null($game))
	{
		$params["channel"]["game"] = $game;
	}
	if(is_int($delay) && $delay > 0)
	{
		$params["channel"]["delay"] = $delay;
	}
	return twitch_api_request("channels/" . CHANNEL_NAME, $params, "PUT");
}

function twitch_api_request($command = null, $params = null, $method = "GET", $add_oauth = true, $is_json = true)
{
	$ch = curl_init();
	if(is_null($command))
	{
		curl_setopt($ch, CURLOPT_URL, API_URL);
	}
	else
	{
		curl_setopt($ch, CURLOPT_URL, API_URL . $command);
	}
	switch($method)
	{
		case "POST":
			curl_setopt($ch, CURLOPT_POST, true); break;
		case "PUT":
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); break;
		case "DELETE":
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); break;
		default:
			break;
	}
	$headers = array("Accept: application/vnd.twitchtv.v" . API_VERSION . "+json");
	if($add_oauth)
	{
		$headers[] = "Authorization: OAuth " . OAUTH_TOKEN;
	}
	if(!is_null($params))
	{
		if($is_json)
		{
			$params = json_encode($params);
			$headers[] = "Content-Type: application/json";
		}
		curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
	}
	curl_setopt_array($ch, array(
		CURLOPT_HTTPHEADER => $headers,
		CURLOPT_RETURNTRANSFER => true
	));
	$response = json_decode(curl_exec($ch), true);

	curl_close($ch);

	return $response;
}
?>

I made some minor changes to your code… and this worked fine for me.

<?php

define("CHANNEL_NAME", "{YOUR_CHANNEL_NAME}");
define("OAUTH_TOKEN", "{YOUR_OAUTH_TOKEN}");
define("API_URL", "https://api.twitch.tv/kraken/");
define("API_VERSION", "3");

function set_channel_info($status = null, $game = null, $delay = 0)
{
    $params = array("channel" => array());
    if (!is_null($status)) {
        $params["channel"]["status"] = $status;
    }
    if (!is_null($game)) {
        $params["channel"]["game"] = $game;
    }
    if (is_int($delay) && $delay > 0) {
        $params["channel"]["delay"] = $delay;
    }
    return twitch_api_request("channels/" . CHANNEL_NAME, $params, "PUT");
}

function twitch_api_request($command = null, $params = null, $method = "GET", $add_oauth = true, $is_json = true)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_VERBOSE, true); // if TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // don't check certificate
    if (is_null($command)) {
        curl_setopt($ch, CURLOPT_URL, API_URL);
    } else {
        curl_setopt($ch, CURLOPT_URL, API_URL . $command);
    }
    switch ($method) {
        case "POST":
            curl_setopt($ch, CURLOPT_POST, true);
            break;
        case "PUT":
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
            break;
        case "DELETE":
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
            break;
        default:
            break;
    }
    $headers = array("Accept: application/vnd.twitchtv.v" . API_VERSION . "+json");
    if ($add_oauth) {
        $headers[] = "Authorization: OAuth " . OAUTH_TOKEN;
    }
    if (!is_null($params)) {
        if ($is_json) {
            $params = json_encode($params);
            $headers[] = "Content-Type: application/json";
        }
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    }
    curl_setopt_array($ch, array(
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_RETURNTRANSFER => true
    ));
    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);

    return $response;
}

$response = set_channel_info("twitch n chill?", "Twitch API");
var_dump($response);
1 Like

Strange, still doesn’t work for me, I’m getting the same error.

Have you tried to re-authenticating your test account?

go to https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URL&scope=channel_editor

It should redirect you to your website example.com/callback#access_token=j2k3b42b34jhb3h4bj234bhj234&scope=channel_editor

set your YOUR_OAUTH_TOKEN to match the access token, in this case j2k3b42b34jhb3h4bj234bhj234

and try it.

1 Like

Yes I’ve tried, it still doesn’t work.

Also, I’m using response_type=code and not token, I’m not using the JS API.

If you are going to use the code response_type=code, on your server, you have make the following request to obtain an access token:

POST https://api.twitch.tv/kraken/oauth2/token

`POST Body (URL-encoded)

client_id=[your client ID]
       &client_secret=[your client secret]
       &grant_type=authorization_code
       &redirect_uri=[your registered redirect URI]
       &code=[code received from redirect URI]
       &state=[your provided unique token]

The server will respond with a JSON-encoded access token:

  {
         "access_token": "[user access token]",
         "scope":[array of requested scopes]
 }

Then use that access_token that was returned.

or

you can use response_type=token and the access_token will be returned as part of the redirect_url.

  • Make sure you are using the access_token as the OAUTH_TOKEN and not the code.
1 Like

I’ve already covered that and it’s correct, I can check my token and everything and it’s valid plus the scope is set to channel_editor. That also returns a refresh_token.

I believe the error may have been caused by something else in your code. As for the API, everything seams to be functioning properly on my end. If you would like some help debugging your code you can message me (click on my name, then message.) or link me to your GitHub. I’d be happy to help.

by the way… are you authenticated as se7ensinslivestream, because if the channel broadcaster is not a partnered channel and they have your account set as Editor, you wont be able to make changes to the channel status/game/ect.

1 Like

I’d love to have someone else look over it. For some reason I can’t find the message page?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.